summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2009-08-29 19:44:27 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2009-08-29 19:44:27 +0000
commitf4774bf5bf8fff2b45a6cee8e0b064b560b45809 (patch)
tree4733101102473cc94e08dc3cc4a4a34b988a9396
parenteb3cb724e8d4b60f20356944173e7cddddb51398 (diff)
downloadrockbox-f4774bf5bf8fff2b45a6cee8e0b064b560b45809.tar.gz
rockbox-f4774bf5bf8fff2b45a6cee8e0b064b560b45809.zip
Submit interim version of FS#10565. Performance optimization of atrac3 decoder for ARM. Introduce ASM routines for multiplications and two synthesis loops, refactured parts of synthesis and windowing. Speeds up decoding by a factor of 2.4 on PP502x.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22548 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libatrac/SOURCES3
-rw-r--r--apps/codecs/libatrac/atrac3.c136
-rwxr-xr-xapps/codecs/libatrac/atrac3_arm.S137
-rw-r--r--apps/codecs/libatrac/atrac3data_fixed.h121
-rw-r--r--apps/codecs/libatrac/fixp_math.h92
5 files changed, 343 insertions, 146 deletions
diff --git a/apps/codecs/libatrac/SOURCES b/apps/codecs/libatrac/SOURCES
index 972f9621fc..5a033c1732 100644
--- a/apps/codecs/libatrac/SOURCES
+++ b/apps/codecs/libatrac/SOURCES
@@ -1,2 +1,5 @@
1atrac3.c 1atrac3.c
2#if defined(CPU_ARM)
3atrac3_arm.S
4#endif
2../lib/ffmpeg_bitstream.c 5../lib/ffmpeg_bitstream.c
diff --git a/apps/codecs/libatrac/atrac3.c b/apps/codecs/libatrac/atrac3.c
index 47a63cae30..9ea2be8775 100644
--- a/apps/codecs/libatrac/atrac3.c
+++ b/apps/codecs/libatrac/atrac3.c
@@ -67,6 +67,101 @@ static inline int16_t av_clip_int16(int a)
67static int32_t qmf_window[48] IBSS_ATTR; 67static int32_t qmf_window[48] IBSS_ATTR;
68static VLC spectral_coeff_tab[7]; 68static VLC spectral_coeff_tab[7];
69static channel_unit channel_units[2]; 69static channel_unit channel_units[2];
70
71/**
72 * Matrixing within quadrature mirror synthesis filter.
73 *
74 * @param p3 output buffer
75 * @param inlo lower part of spectrum
76 * @param inhi higher part of spectrum
77 * @param nIn size of spectrum buffer
78 */
79
80#if defined(CPU_ARM)
81 extern void
82 atrac3_iqmf_matrixing(int32_t *p3,
83 int32_t *inlo,
84 int32_t *inhi,
85 unsigned int nIn);
86#else
87 static inline void
88 atrac3_iqmf_matrixing(int32_t *p3,
89 int32_t *inlo,
90 int32_t *inhi,
91 unsigned int nIn)
92 {
93 for(i=0; i<nIn; i+=2){
94 p3[2*i+0] = inlo[i ] + inhi[i ];
95 p3[2*i+1] = inlo[i ] - inhi[i ];
96 p3[2*i+2] = inlo[i+1] + inhi[i+1];
97 p3[2*i+3] = inlo[i+1] - inhi[i+1];
98 }
99 }
100#endif
101
102/**
103 * Matrixing within quadrature mirror synthesis filter.
104 *
105 * @param out output buffer
106 * @param in input buffer
107 * @param win windowing coefficients
108 * @param nIn size of spectrum buffer
109 */
110
111#if defined(CPU_ARM)
112 extern void
113 atrac3_iqmf_dewindowing(int32_t *out,
114 int32_t *in,
115 int32_t *win,
116 unsigned int nIn);
117#else
118 static inline void
119 atrac3_iqmf_dewindowing(int32_t *out,
120 int32_t *in,
121 int32_t *win,
122 unsigned int nIn)
123 {
124 int32_t i, j, s1, s2;
125
126 for (j = nIn; j != 0; j--) {
127 /* i=0 */
128 s1 = fixmul31(win[0], in[0]);
129 s2 = fixmul31(win[1], in[1]);
130
131 /* i=2..46 */
132 for (i = 2; i < 48; i += 2) {
133 s1 += fixmul31(win[i ], in[i ]);
134 s2 += fixmul31(win[i+1], in[i+1]);
135 }
136
137 out[0] = s2;
138 out[1] = s1;
139
140 in += 2;
141 out += 2;
142 }
143 }
144#endif
145
146/**
147 * IMDCT windowing.
148 *
149 * @param buffer sample buffer
150 * @param win window coefficients
151 */
152
153static inline void
154atrac3_imdct_windowing(int32_t *buffer,
155 const int32_t *win)
156{
157 int32_t i;
158 /* win[0..127] = win[511..384], win[128..383] = 1 */
159 for(i = 0; i<128; i++) {
160 buffer[ i] = fixmul31(win[i], buffer[ i]);
161 buffer[511-i] = fixmul31(win[i], buffer[511-i]);
162 }
163}
164
70/** 165/**
71 * Quadrature mirror synthesis filter. 166 * Quadrature mirror synthesis filter.
72 * 167 *
@@ -77,42 +172,19 @@ static channel_unit channel_units[2];
77 * @param delayBuf delayBuf buffer 172 * @param delayBuf delayBuf buffer
78 * @param temp temp buffer 173 * @param temp temp buffer
79 */ 174 */
175
80static void iqmf (int32_t *inlo, int32_t *inhi, unsigned int nIn, int32_t *pOut, int32_t *delayBuf, int32_t *temp) 176static void iqmf (int32_t *inlo, int32_t *inhi, unsigned int nIn, int32_t *pOut, int32_t *delayBuf, int32_t *temp)
81{ 177{
82 unsigned int i, j; 178 /* Restore the delay buffer */
83 int32_t *p1, *p3;
84
85 memcpy(temp, delayBuf, 46*sizeof(int32_t)); 179 memcpy(temp, delayBuf, 46*sizeof(int32_t));
86 180
87 p3 = temp + 46; 181 /* loop1: matrixing */
182 atrac3_iqmf_matrixing(temp + 46, inlo, inhi, nIn);
88 183
89 /* loop1 */ 184 /* loop2: dewindowing */
90 for(i=0; i<nIn; i+=2){ 185 atrac3_iqmf_dewindowing(pOut, temp, qmf_window, nIn);
91 p3[2*i+0] = inlo[i ] + inhi[i ];
92 p3[2*i+1] = inlo[i ] - inhi[i ];
93 p3[2*i+2] = inlo[i+1] + inhi[i+1];
94 p3[2*i+3] = inlo[i+1] - inhi[i+1];
95 }
96
97 /* loop2 */
98 p1 = temp;
99 for (j = nIn; j != 0; j--) {
100 int32_t s1 = 0;
101 int32_t s2 = 0;
102 186
103 for (i = 0; i < 48; i += 2) { 187 /* Save the delay buffer */
104 s1 += fixmul31(p1[i], qmf_window[i]);
105 s2 += fixmul31(p1[i+1], qmf_window[i+1]);
106 }
107
108 pOut[0] = s2;
109 pOut[1] = s1;
110
111 p1 += 2;
112 pOut += 2;
113 }
114
115 /* Update the delay buffer. */
116 memcpy(delayBuf, temp + (nIn << 1), 46*sizeof(int32_t)); 188 memcpy(delayBuf, temp + (nIn << 1), 46*sizeof(int32_t));
117} 189}
118 190
@@ -146,9 +218,7 @@ static void IMLT(int32_t *pInput, int32_t *pOutput, int odd_band)
146 mdct_backward(512, pInput, pOutput); 218 mdct_backward(512, pInput, pOutput);
147 219
148 /* Windowing. */ 220 /* Windowing. */
149 for(i = 0; i<512; i++) 221 atrac3_imdct_windowing(pOutput, window_lookup);
150 pOutput[i] = fixmul31(pOutput[i], window_lookup[i]);
151
152} 222}
153 223
154 224
diff --git a/apps/codecs/libatrac/atrac3_arm.S b/apps/codecs/libatrac/atrac3_arm.S
new file mode 100755
index 0000000000..be8b2a0e0e
--- /dev/null
+++ b/apps/codecs/libatrac/atrac3_arm.S
@@ -0,0 +1,137 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2009 by Andree Buschmann
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22 .section .text, "ax", %progbits
23
24/****************************************************************************
25 * void atrac3_iqmf_matrixing(int32_t *dest,
26 * int32_t *inlo,
27 * int32_t *inhi,
28 * unsigned int count);
29 *
30 * Matrixing step within iqmf of atrac3 synthesis. Reference implementation:
31 *
32 * for(i=0; i<counter; i+=2){
33 * dest[2*i+0] = inlo[i ] + inhi[i ];
34 * dest[2*i+1] = inlo[i ] - inhi[i ];
35 * dest[2*i+2] = inlo[i+1] + inhi[i+1];
36 * dest[2*i+3] = inlo[i+1] - inhi[i+1];
37 * }
38 * Note: r12 is a scratch register and can be used without restorage.
39 ****************************************************************************/
40 .align 2
41 .global atrac3_iqmf_matrixing
42 .type atrac3_iqmf_matrixing, %function
43
44atrac3_iqmf_matrixing:
45 /* r0 = dest */
46 /* r1 = inlo */
47 /* r2 = inhi */
48 /* r3 = counter */
49 stmfd sp!, {r4-r9, lr} /* save non-scratch registers */
50
51.iqmf_matrixing_loop:
52 ldmia r1!, { r4, r6, r8, r12} /* load inlo[0...3] */
53 ldmia r2!, { r5, r7, r9, lr } /* load inhi[0...3] */
54 add r4, r4, r5 /* r4 = inlo[0] + inhi[0] */
55 sub r5, r4, r5, asl #1 /* r5 = inlo[0] - inhi[0] */
56 add r6, r6, r7 /* r6 = inlo[1] + inhi[1] */
57 sub r7, r6, r7, asl #1 /* r7 = inlo[1] - inhi[1] */
58 add r8, r8, r9 /* r8 = inlo[2] + inhi[2] */
59 sub r9, r8, r9, asl #1 /* r9 = inlo[2] - inhi[2] */
60 add r12, r12, lr /* r12 = inlo[3] + inhi[3] */
61 sub lr , r12, lr, asl #1 /* lr = inlo[3] - inhi[3] */
62 stmia r0!, {r4-r9, r12, lr} /* store results to dest */
63 subs r3, r3, #4 /* counter -= 4 */
64 bgt .iqmf_matrixing_loop
65
66 ldmfd sp!, {r4-r9, pc} /* restore registers */
67
68.atrac3_iqmf_matrixing_end:
69 .size atrac3_iqmf_matrixing,.atrac3_iqmf_matrixing_end-atrac3_iqmf_matrixing
70
71
72/****************************************************************************
73 * atrac3_iqmf_dewindowing(int32_t *out,
74 * int32_t *in,
75 * int32_t *win,
76 * unsigned int nIn);
77 *
78 * Dewindowing step within iqmf of atrac3 synthesis. Reference implementation:
79 *
80 * for (j = nIn; j != 0; j--) {
81 * s1 = fixmul32(in[0], win[0]);
82 * s2 = fixmul32(in[1], win[1]);
83 * for (i = 2; i < 48; i += 2) {
84 * s1 += fixmul32(in[i ], win[i ]);
85 * s2 += fixmul32(in[i+1], win[i+1]);
86 * }
87 * out[0] = s2 << 1;
88 * out[1] = s1 << 1;
89 * in += 2;
90 * out += 2;
91 * }
92 * Note: r12 is a scratch register and can be used without restorage.
93 ****************************************************************************/
94 .align 2
95 .global atrac3_iqmf_dewindowing
96 .type atrac3_iqmf_dewindowing, %function
97
98atrac3_iqmf_dewindowing:
99 /* r0 = dest */
100 /* r1 = input samples */
101 /* r2 = window coefficients */
102 /* r3 = counter */
103 stmfd sp!, {r4-r10, lr} /* save non-scratch registers */
104
105.iqmf_dewindow_outer_loop: /* outer loop 0...counter-1 */
106
107 ldmia r2!, {r5, r6} /* load win[0..1] */
108 ldmia r1!, {r7, r8} /* load in[0..1] */
109 smull lr , r10, r5, r7 /* s1 = win[0] * in[0] */
110 smull r12, r9 , r6, r8 /* s2 = win[1] * in[1] */
111
112 mov r4, #46 /* r4 = 46 */
113.iqmf_dewindow_inner_loop: /* inner loop i=2...48 */
114 ldmia r2!, {r5, r6} /* load win[i...i+1] */
115 ldmia r1!, {r7, r8} /* load in[i...i+1] */
116 smlal lr , r10, r5, r7 /* s1 = win[i ] * in[i ] */
117 smlal r12, r9 , r6, r8 /* s2 = win[i+1] * in[i+1] */
118
119 subs r4, r4, #2 /* inner loop -= 2*/
120 bgt .iqmf_dewindow_inner_loop
121
122 mov lr , lr , lsr #31
123 orr r10, lr , r10, lsl #1 /* s1 = low>>31 || hi<<1 */
124 mov r12, r12, lsr #31
125 orr r9 , r12, r9 , lsl #1 /* s2 = low>>31 || hi<<1 */
126
127 stmia r0!, {r9, r10} /* store result out[0]=s2, out[1]=s1 */
128 sub r1, r1, #184 /* roll back 64 entries = 184 bytes */
129 sub r2, r2, #192 /* roll back 48 entries = 192 bytes = win[0] */
130
131 subs r3, r3, #1 /* outer loop -= 1 */
132 bgt .iqmf_dewindow_outer_loop
133
134 ldmfd sp!, {r4-r10, pc} /* restore registers */
135
136.atrac3_iqmf_dewindowing_end:
137 .size atrac3_iqmf_dewindowing,.atrac3_iqmf_dewindowing_end-atrac3_iqmf_dewindowing
diff --git a/apps/codecs/libatrac/atrac3data_fixed.h b/apps/codecs/libatrac/atrac3data_fixed.h
index 561c45a87d..f0924a5190 100644
--- a/apps/codecs/libatrac/atrac3data_fixed.h
+++ b/apps/codecs/libatrac/atrac3data_fixed.h
@@ -22,102 +22,39 @@ static const int32_t SFTable_fixed[64] ICONST_ATTR = {
22}; 22};
23 23
24/* transform data */ 24/* transform data */
25/* floating point values scaled by 2^31 */ 25/* floating point values scaled by 2^31 */
26static const int32_t qmf_48tap_half_fix[24] ICONST_ATTR = { 26static const int32_t qmf_48tap_half_fix[24] ICONST_ATTR = {
27 0xffff855e, 0xfffcfbca, 0xfffe28eb, 0x9de6b, 0x7f028, 0xffe40d08, 27 0xffff855e, 0xfffcfbca, 0xfffe28eb, 0x0009de6b, 0x0007f028, 0xffe40d08,
28 0xffeef140, 0x42a692, 0x19ab1f, 0xff75dec7, 0xffe738f5, 0x100e928, 28 0xffeef140, 0x0042a692, 0x0019ab1f, 0xff75dec7, 0xffe738f5, 0x0100e928,
29 0xfffdfedf, 0xfe478b84, 0x50b279, 0x2c83f88, 0xff005ad7, 0xfba2ee80, 29 0xfffdfedf, 0xfe478b84, 0x0050b279, 0x02c83f88, 0xff005ad7, 0xfba2ee80,
30 0x2685970, 0x6f42798, 0xfa6b6f10, 0xf3475f80, 0x10e7f7c0, 0x3b6c44c0 30 0x02685970, 0x06f42798, 0xfa6b6f10, 0xf3475f80, 0x10e7f7c0, 0x3b6c44c0
31}; 31};
32 32
33/* mdct window scaled by 2^31 */ 33/* mdct window scaled by 2^31 */
34static const int32_t window_lookup[512] ICONST_ATTR = { 34/* Remark: The preceding sign corrects the sign of the hexadecimal values */
35 0xffffb10c, 0xfffd394b, 0xfff8494f, 0xfff0e025, 0xffe6fc5f, 0xffda9c15, 35static const int32_t window_lookup[128] ICONST_ATTR = {
36 0xffcbbce6, 0xffba5bf4, 0xffa675e8, 0xff9006f0, 0xff770aba, 0xff5b7c7e, 36 -0xffffb10c, -0xfffd394b, -0xfff8494f, -0xfff0e025, -0xffe6fc5f, -0xffda9c15,
37 0xff3d56f2, 0xff1c9452, 0xfef92e59, 0xfed31e45, 0xfeaa5cd5, 0xfe7ee247, 37 -0xffcbbce6, -0xffba5bf4, -0xffa675e8, -0xff9006f0, -0xff770aba, -0xff5b7c7e,
38 0xfe50a657, 0xfe1fa041, 0xfdebc6c1, 0xfdb5100d, 0xfd7b71d5, 0xfd3ee149, 38 -0xff3d56f2, -0xff1c9452, -0xfef92e59, -0xfed31e45, -0xfeaa5cd5, -0xfe7ee247,
39 0xfcff5311, 0xfcbcbb49, 0xfc770d99, 0xfc2e3d15, 0xfbe23c39, 0xfb92fd29, 39 -0xfe50a657, -0xfe1fa041, -0xfdebc6c1, -0xfdb5100d, -0xfd7b71d5, -0xfd3ee149,
40 0xfb407141, 0xfaea8989, 0xfa913661, 0xfa3467b1, 0xf9d40cd9, 0xf9701499, 40 -0xfcff5311, -0xfcbcbb49, -0xfc770d99, -0xfc2e3d15, -0xfbe23c39, -0xfb92fd29,
41 0xf9086d41, 0xf89d04a9, 0xf82dc7f1, 0xf7baa3e1, 0xf74384b1, 0xf6c85611, 41 -0xfb407141, -0xfaea8989, -0xfa913661, -0xfa3467b1, -0xf9d40cd9, -0xf9701499,
42 0xf6490321, 0xf5c576b1, 0xf53d9b21, 0xf4b15a01, 0xf4209ce1, 0xf38b4c71, 42 -0xf9086d41, -0xf89d04a9, -0xf82dc7f1, -0xf7baa3e1, -0xf74384b1, -0xf6c85611,
43 0xf2f15171, 0xf2529411, 0xf1aefbf1, 0xf10670a1, 0xf058d941, 0xefa61cc1, 43 -0xf6490321, -0xf5c576b1, -0xf53d9b21, -0xf4b15a01, -0xf4209ce1, -0xf38b4c71,
44 0xeeee21c1, 0xee30cec1, 0xed6e0a41, 0xeca5ba61, 0xebd7c5c1, 0xeb041241, 44 -0xf2f15171, -0xf2529411, -0xf1aefbf1, -0xf10670a1, -0xf058d941, -0xefa61cc1,
45 0xea2a8601, 0xe94b0861, 0xe8657f61, 0xe779d241, 0xe687e861, 0xe58fa9e1, 45 -0xeeee21c1, -0xee30cec1, -0xed6e0a41, -0xeca5ba61, -0xebd7c5c1, -0xeb041241,
46 0xe490fec1, 0xe38bd101, 0xe28009c1, 0xe16d93e1, 0xe0545ba1, 0xdf344dc1, 46 -0xea2a8601, -0xe94b0861, -0xe8657f61, -0xe779d241, -0xe687e861, -0xe58fa9e1,
47 0xde0d5881, 0xdcdf6bc1, 0xdbaa7801, 0xda6e70c1, 0xd92b4ac1, 0xd7e0fc81, 47 -0xe490fec1, -0xe38bd101, -0xe28009c1, -0xe16d93e1, -0xe0545ba1, -0xdf344dc1,
48 0xd68f7ec1, 0xd536cd41, 0xd3d6e5c1, 0xd26fc901, 0xd10179c1, 0xcf8bff41, 48 -0xde0d5881, -0xdcdf6bc1, -0xdbaa7801, -0xda6e70c1, -0xd92b4ac1, -0xd7e0fc81,
49 0xce0f6301, 0xcc8bb241, 0xcb00fdc1, 0xc96f5b01, 0xc7d6e141, 0xc637af41, 49 -0xd68f7ec1, -0xd536cd41, -0xd3d6e5c1, -0xd26fc901, -0xd10179c1, -0xcf8bff41,
50 0xc491e4c1, 0xc2e5a801, 0xc1332401, 0xbf7a8701, 0xbdbc0681, 0xbbf7da01, 50 -0xce0f6301, -0xcc8bb241, -0xcb00fdc1, -0xc96f5b01, -0xc7d6e141, -0xc637af41,
51 0xba2e4181, 0xb85f7f81, 0xb68bde01, 0xb4b3a981, 0xb2d73781, 0xb0f6df01, 51 -0xc491e4c1, -0xc2e5a801, -0xc1332401, -0xbf7a8701, -0xbdbc0681, -0xbbf7da01,
52 0xaf12ff01, 0xad2bfa81, 0xab423981, 0xa9562981, 0xa7683c01, 0xa578e701, 52 -0xba2e4181, -0xb85f7f81, -0xb68bde01, -0xb4b3a981, -0xb2d73781, -0xb0f6df01,
53 0xa388a681, 0xa197f801, 0x9fa75e81, 0x9db75f01, 0x9bc88201, 0x99db5301, 53 -0xaf12ff01, -0xad2bfa81, -0xab423981, -0xa9562981, -0xa7683c01, -0xa578e701,
54 0x97f06001, 0x96083601, 0x94236601, 0x92427f81, 0x90661481, 0x8e8eb481, 54 -0xa388a681, -0xa197f801, -0x9fa75e81, -0x9db75f01, -0x9bc88201, -0x99db5301,
55 0x8cbced01, 0x8af14d81, 0x892c5f81, 0x876eab01, 0x85b8b681, 0x840b0301, 55 -0x97f06001, -0x96083601, -0x94236601, -0x92427f81, -0x90661481, -0x8e8eb481,
56 0x82660c01, 0x80ca4a01, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 56 -0x8cbced01, -0x8af14d81, -0x892c5f81, -0x876eab01, -0x85b8b681, -0x840b0301,
57 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 57 -0x82660c01, -0x80ca4a01,
58 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
59 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
60 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
61 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
62 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
63 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
64 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
65 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
66 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
67 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
68 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
69 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
70 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
71 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
72 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
73 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
74 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
75 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
76 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
77 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
78 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
79 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
80 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
81 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
82 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
83 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
84 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
85 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
86 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
87 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
88 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
89 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
90 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
91 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
92 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
93 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
94 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
95 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
96 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
97 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
98 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
99 0x80ca4a01, 0x82660c01, 0x840b0301, 0x85b8b681, 0x876eab01, 0x892c5f81,
100 0x8af14d81, 0x8cbced01, 0x8e8eb481, 0x90661481, 0x92427f81, 0x94236601,
101 0x96083601, 0x97f06001, 0x99db5301, 0x9bc88201, 0x9db75f01, 0x9fa75e81,
102 0xa197f801, 0xa388a681, 0xa578e701, 0xa7683c01, 0xa9562981, 0xab423981,
103 0xad2bfa81, 0xaf12ff01, 0xb0f6df01, 0xb2d73781, 0xb4b3a981, 0xb68bde01,
104 0xb85f7f81, 0xba2e4181, 0xbbf7da01, 0xbdbc0681, 0xbf7a8701, 0xc1332401,
105 0xc2e5a801, 0xc491e4c1, 0xc637af41, 0xc7d6e141, 0xc96f5b01, 0xcb00fdc1,
106 0xcc8bb241, 0xce0f6301, 0xcf8bff41, 0xd10179c1, 0xd26fc901, 0xd3d6e5c1,
107 0xd536cd41, 0xd68f7ec1, 0xd7e0fc81, 0xd92b4ac1, 0xda6e70c1, 0xdbaa7801,
108 0xdcdf6bc1, 0xde0d5881, 0xdf344dc1, 0xe0545ba1, 0xe16d93e1, 0xe28009c1,
109 0xe38bd101, 0xe490fec1, 0xe58fa9e1, 0xe687e861, 0xe779d241, 0xe8657f61,
110 0xe94b0861, 0xea2a8601, 0xeb041241, 0xebd7c5c1, 0xeca5ba61, 0xed6e0a41,
111 0xee30cec1, 0xeeee21c1, 0xefa61cc1, 0xf058d941, 0xf10670a1, 0xf1aefbf1,
112 0xf2529411, 0xf2f15171, 0xf38b4c71, 0xf4209ce1, 0xf4b15a01, 0xf53d9b21,
113 0xf5c576b1, 0xf6490321, 0xf6c85611, 0xf74384b1, 0xf7baa3e1, 0xf82dc7f1,
114 0xf89d04a9, 0xf9086d41, 0xf9701499, 0xf9d40cd9, 0xfa3467b1, 0xfa913661,
115 0xfaea8989, 0xfb407141, 0xfb92fd29, 0xfbe23c39, 0xfc2e3d15, 0xfc770d99,
116 0xfcbcbb49, 0xfcff5311, 0xfd3ee149, 0xfd7b71d5, 0xfdb5100d, 0xfdebc6c1,
117 0xfe1fa041, 0xfe50a657, 0xfe7ee247, 0xfeaa5cd5, 0xfed31e45, 0xfef92e59,
118 0xff1c9452, 0xff3d56f2, 0xff5b7c7e, 0xff770aba, 0xff9006f0, 0xffa675e8,
119 0xffba5bf4, 0xffcbbce6, 0xffda9c15, 0xffe6fc5f, 0xfff0e025, 0xfff8494f,
120 0xfffd394b, 0xffffb10c,
121}; 58};
122 59
123/* Gain tables scaled by 2^16 */ 60/* Gain tables scaled by 2^16 */
diff --git a/apps/codecs/libatrac/fixp_math.h b/apps/codecs/libatrac/fixp_math.h
index 8a734f6b68..88cb5e4b66 100644
--- a/apps/codecs/libatrac/fixp_math.h
+++ b/apps/codecs/libatrac/fixp_math.h
@@ -10,27 +10,77 @@
10 10
11/* Fixed point math routines for use in atrac3.c */ 11/* Fixed point math routines for use in atrac3.c */
12 12
13static inline int32_t fixmul16(int32_t x, int32_t y) 13#if defined(CPU_ARM)
14{ 14 #define fixmul16(X,Y) \
15 int64_t temp; 15 ({ \
16 temp = x; 16 int32_t low; \
17 temp *= y; 17 int32_t high; \
18 18 asm volatile ( /* calculates: result = (X*Y)>>16 */ \
19 temp >>= 16; 19 "smull %0,%1,%2,%3 \n\t" /* 64 = 32x32 multiply */ \
20 20 "mov %0, %0, lsr #16 \n\t" /* %0 = %0 >> 16 */ \
21 return (int32_t)temp; 21 "orr %0, %0, %1, lsl #16 \n\t"/* result = %0 OR (%1 << 16) */ \
22} 22 : "=&r"(low), "=&r" (high) \
23 23 : "r"(X),"r"(Y)); \
24static inline int32_t fixmul31(int32_t x, int32_t y) 24 low; \
25{ 25 })
26 int64_t temp; 26
27 temp = x; 27 #define fixmul31(X,Y) \
28 temp *= y; 28 ({ \
29 29 int32_t low; \
30 temp >>= 31; //16+31-16 = 31 bits 30 int32_t high; \
31 31 asm volatile ( /* calculates: result = (X*Y)>>31 */ \
32 return (int32_t)temp; 32 "smull %0,%1,%2,%3 \n\t" /* 64 = 32x32 multiply */ \
33} 33 "mov %0, %0, lsr #31 \n\t" /* %0 = %0 >> 31 */ \
34 "orr %0, %0, %1, lsl #1 \n\t" /* result = %0 OR (%1 << 1) */ \
35 : "=&r"(low), "=&r" (high) \
36 : "r"(X),"r"(Y)); \
37 low; \
38 })
39
40 #define fixmul32(X,Y) \
41 ({ \
42 int32_t low; \
43 int32_t high; \
44 asm volatile ( /* calculates: result = (X*Y)>>32 */ \
45 "smull %0,%1,%2,%3 \n\t" /* 64 = 32x32 multiply */ \
46 : "=&r"(low), "=&r" (high) \
47 : "r"(X),"r"(Y)); \
48 high; \
49 })
50#else
51 static inline int32_t fixmul16(int32_t x, int32_t y)
52 {
53 int64_t temp;
54 temp = x;
55 temp *= y;
56
57 temp >>= 16;
58
59 return (int32_t)temp;
60 }
61
62 static inline int32_t fixmul31(int32_t x, int32_t y)
63 {
64 int64_t temp;
65 temp = x;
66 temp *= y;
67
68 temp >>= 31; //16+31-16 = 31 bits
69
70 return (int32_t)temp;
71 }
72
73 static inline int32_t fixmul32(int32_t x, int32_t y)
74 {
75 int64_t temp;
76 temp = x;
77 temp *= y;
78
79 temp >>= 32; //16+31-16 = 31 bits
80
81 return (int32_t)temp;
82 }
83#endif
34 84
35static inline int32_t fixdiv16(int32_t x, int32_t y) 85static inline int32_t fixdiv16(int32_t x, int32_t y)
36{ 86{