annotate liba52/resample_altivec.c @ 25040:ea694492cb2e

Open device file only right before we need it, so we do not have to add close to all the abort code-paths
author reimar
date Sat, 17 Nov 2007 18:26:25 +0000
parents 9e6f7a23b4b1
children 6f0309e575e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11849
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
1 // this code is based on a52dec/libao/audio_out_oss.c
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
2 // AltiVec support Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org>
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
3
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
4 #ifndef SYS_DARWIN
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
5 #include <altivec.h>
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
6 #endif
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
7
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
8 const vector signed int magic = {0x43c00000,0x43c00000,0x43c00000,0x43c00000};
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
9
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
10 static inline vector signed short convert16_altivec(vector signed int v1, vector signed int v2)
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
11 {
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
12 register vector signed short result;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
13 v1 = vec_subs(v1, magic);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
14 v2 = vec_subs(v2, magic);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
15 result = vec_packs(v1, v2);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
16
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
17 return result;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
18 }
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
19
24996
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
20 static void unaligned_store(vector signed short value, int off, int16_t *dst)
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
21 {
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
22 register vector unsigned char align = vec_lvsr(0, dst),
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
23 mask = vec_lvsl(0, dst);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
24 register vector signed short t0,t1, edges;
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
25
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
26 t0 = vec_ld(0+off, dst);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
27 t1 = vec_ld(15+off, dst);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
28 edges = vec_perm(t1 ,t0, mask);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
29 t1 = vec_perm(value, edges, align);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
30 t0 = vec_perm(edges, value, align);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
31 vec_st(t1, 15+off, dst);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
32 vec_st(t0, 0+off, dst);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
33 }
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
34
11849
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
35 static int a52_resample_STEREO_to_2_altivec(float * _f, int16_t * s16){
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
36 #if 0
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
37 int i;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
38 int32_t * f = (int32_t *) _f;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
39 for (i = 0; i < 256; i++) {
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
40 s16[2*i] = convert (f[i]);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
41 s16[2*i+1] = convert (f[i+256]);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
42 }
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
43 return 2*256;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
44 #else
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
45 int i = 0;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
46 int32_t * f = (int32_t *) _f;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
47 register vector signed int f0, f4, f256, f260;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
48 register vector signed short reven, rodd, r0, r1;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
49
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
50 for (i = 0; i < 256; i+= 8) {
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
51 f0 = vec_ld(0, f);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
52 f4 = vec_ld(16, f);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
53
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
54 f256 = vec_ld(1024, f);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
55 f260 = vec_ld(1040, f);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
56
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
57 reven = convert16_altivec(f0, f4);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
58 rodd = convert16_altivec(f256, f260);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
59
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
60 r0 = vec_mergeh(reven, rodd);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
61 r1 = vec_mergel(reven, rodd);
24996
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
62 // FIXME can be merged to spare some I/O
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
63 unaligned_store(r0, 0, s16);
9e6f7a23b4b1 unaligned store, should fix bug #893
lu_zero
parents: 11849
diff changeset
64 unaligned_store(r1, 16, s16);
11849
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
65
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
66 f += 8;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
67 s16 += 16;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
68 }
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
69 return(2*256);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
70 #endif
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
71 }
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
72
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
73 static void* a52_resample_altivec(int flags, int ch){
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
74 fprintf(stderr, "Checking for AltiVec resampler : 0x%08x, %d\n", flags, ch);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
75
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
76 switch (flags) {
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
77 case A52_CHANNEL:
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
78 case A52_STEREO:
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
79 case A52_DOLBY:
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
80 if(ch==2) return a52_resample_STEREO_to_2_altivec;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
81 break;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
82
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
83 default:
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
84 fprintf(stderr, "Unsupported flags: 0x%08x (%d channels)\n", flags, ch);
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
85 break;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
86 }
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
87 return NULL;
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
88 }
459ba3f14302 Altivec optimized stereo resampler by Romain Dolbeau (made it working under Linux myself)
alex
parents:
diff changeset
89