Mercurial > mplayer.hg
comparison libfaad2/output.c @ 10725:e989150f8216
libfaad2 v2.0rc1 imported
author | arpi |
---|---|
date | Sat, 30 Aug 2003 22:30:28 +0000 |
parents | |
children | 3185f64f6350 |
comparison
equal
deleted
inserted
replaced
10724:adf5697b9d83 | 10725:e989150f8216 |
---|---|
1 /* | |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
3 ** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com | |
4 ** | |
5 ** This program is free software; you can redistribute it and/or modify | |
6 ** it under the terms of the GNU General Public License as published by | |
7 ** the Free Software Foundation; either version 2 of the License, or | |
8 ** (at your option) any later version. | |
9 ** | |
10 ** This program is distributed in the hope that it will be useful, | |
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 ** GNU General Public License for more details. | |
14 ** | |
15 ** You should have received a copy of the GNU General Public License | |
16 ** along with this program; if not, write to the Free Software | |
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 ** | |
19 ** Any non-GPL usage of this software or parts of this software is strictly | |
20 ** forbidden. | |
21 ** | |
22 ** Commercial non-GPL licensing of this software is possible. | |
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | |
24 ** | |
25 ** $Id$ | |
26 **/ | |
27 | |
28 #include "common.h" | |
29 #include "structs.h" | |
30 | |
31 #include "output.h" | |
32 #include "decoder.h" | |
33 | |
34 #ifndef FIXED_POINT | |
35 | |
36 #include "dither.h" | |
37 | |
38 | |
39 #define ftol(A,B) {tmp = *(int32_t*) & A - 0x4B7F8000; \ | |
40 B = (int16_t)((tmp==(int16_t)tmp) ? tmp : (tmp>>31)^0x7FFF);} | |
41 | |
42 #define ROUND(x) ((x >= 0) ? (int32_t)floor((x) + 0.5) : (int32_t)ceil((x) + 0.5)) | |
43 | |
44 #define ROUND32(x) ROUND(x) | |
45 | |
46 #define ROUND64(x) (doubletmp = (x) + Dither.Add + (int64_t)0x001FFFFD80000000L, *(int64_t*)(&doubletmp) - (int64_t)0x433FFFFD80000000L) | |
47 | |
48 #define FLOAT_SCALE (1.0f/(1<<15)) | |
49 | |
50 dither_t Dither; | |
51 double doubletmp; | |
52 | |
53 #define DM_MUL (1./(1.+sqrt(2.))) | |
54 | |
55 static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample, | |
56 uint8_t downMatrix, uint8_t *internal_channel) | |
57 { | |
58 if (downMatrix) | |
59 { | |
60 if (channel == 0) | |
61 { | |
62 return DM_MUL * (input[internal_channel[1]][sample] + | |
63 input[internal_channel[0]][sample]/sqrt(2.) + | |
64 input[internal_channel[3]][sample]/sqrt(2.)); | |
65 } else { | |
66 return DM_MUL * (input[internal_channel[2]][sample] + | |
67 input[internal_channel[0]][sample]/sqrt(2.) + | |
68 input[internal_channel[4]][sample]/sqrt(2.)); | |
69 } | |
70 } else { | |
71 return input[internal_channel[channel]][sample]; | |
72 } | |
73 } | |
74 | |
75 void* output_to_PCM(faacDecHandle hDecoder, | |
76 real_t **input, void *sample_buffer, uint8_t channels, | |
77 uint16_t frame_len, uint8_t format) | |
78 { | |
79 uint8_t ch; | |
80 uint16_t i, j = 0; | |
81 uint8_t internal_channel; | |
82 | |
83 int16_t *short_sample_buffer = (int16_t*)sample_buffer; | |
84 int32_t *int_sample_buffer = (int32_t*)sample_buffer; | |
85 float32_t *float_sample_buffer = (float32_t*)sample_buffer; | |
86 double *double_sample_buffer = (double*)sample_buffer; | |
87 | |
88 /* Copy output to a standard PCM buffer */ | |
89 for (ch = 0; ch < channels; ch++) | |
90 { | |
91 internal_channel = hDecoder->internal_channel[ch]; | |
92 | |
93 switch (format) | |
94 { | |
95 case FAAD_FMT_16BIT: | |
96 for(i = 0; i < frame_len; i++) | |
97 { | |
98 int32_t tmp; | |
99 real_t ftemp; | |
100 //real_t inp = input[internal_channel][i]; | |
101 real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); | |
102 | |
103 ftemp = inp + 0xff8000; | |
104 ftol(ftemp, short_sample_buffer[(i*channels)+ch]); | |
105 } | |
106 break; | |
107 case FAAD_FMT_16BIT_DITHER: | |
108 for(i = 0; i < frame_len; i++, j++) | |
109 { | |
110 real_t inp = input[internal_channel][i]; | |
111 double Sum = inp * 65535.f; | |
112 int64_t val; | |
113 if(j > 31) | |
114 j = 0; | |
115 val = dither_output(1, 0, j, Sum, ch) / 65536; | |
116 if (val > (1<<15)-1) | |
117 val = (1<<15)-1; | |
118 else if (val < -(1<<15)) | |
119 val = -(1<<15); | |
120 short_sample_buffer[(i*channels)+ch] = (int16_t)val; | |
121 } | |
122 break; | |
123 case FAAD_FMT_16BIT_L_SHAPE: | |
124 case FAAD_FMT_16BIT_M_SHAPE: | |
125 case FAAD_FMT_16BIT_H_SHAPE: | |
126 for(i = 0; i < frame_len; i++, j++) | |
127 { | |
128 real_t inp = input[internal_channel][i]; | |
129 double Sum = inp * 65535.f; | |
130 int64_t val; | |
131 if(j > 31) | |
132 j = 0; | |
133 val = dither_output(1, 1, j, Sum, ch) / 65536; | |
134 if (val > (1<<15)-1) | |
135 val = (1<<15)-1; | |
136 else if (val < -(1<<15)) | |
137 val = -(1<<15); | |
138 short_sample_buffer[(i*channels)+ch] = (int16_t)val; | |
139 } | |
140 break; | |
141 case FAAD_FMT_24BIT: | |
142 for(i = 0; i < frame_len; i++) | |
143 { | |
144 real_t inp = input[internal_channel][i]; | |
145 if (inp > (1<<15)-1) | |
146 inp = (1<<15)-1; | |
147 else if (inp < -(1<<15)) | |
148 inp = -(1<<15); | |
149 int_sample_buffer[(i*channels)+ch] = ROUND(inp*(1<<8)); | |
150 } | |
151 break; | |
152 case FAAD_FMT_32BIT: | |
153 for(i = 0; i < frame_len; i++) | |
154 { | |
155 real_t inp = input[internal_channel][i]; | |
156 if (inp > (1<<15)-1) | |
157 inp = (1<<15)-1; | |
158 else if (inp < -(1<<15)) | |
159 inp = -(1<<15); | |
160 int_sample_buffer[(i*channels)+ch] = ROUND32(inp*(1<<16)); | |
161 } | |
162 break; | |
163 case FAAD_FMT_FLOAT: | |
164 for(i = 0; i < frame_len; i++) | |
165 { | |
166 real_t inp = input[internal_channel][i]; | |
167 float_sample_buffer[(i*channels)+ch] = inp*FLOAT_SCALE; | |
168 } | |
169 break; | |
170 case FAAD_FMT_DOUBLE: | |
171 for(i = 0; i < frame_len; i++) | |
172 { | |
173 real_t inp = input[internal_channel][i]; | |
174 double_sample_buffer[(i*channels)+ch] = (double)inp*FLOAT_SCALE; | |
175 } | |
176 break; | |
177 } | |
178 } | |
179 | |
180 return sample_buffer; | |
181 } | |
182 | |
183 | |
184 /* Dither output */ | |
185 static int64_t dither_output(uint8_t dithering, uint8_t shapingtype, uint16_t i, double Sum, uint8_t k) | |
186 { | |
187 double Sum2; | |
188 int64_t val; | |
189 if(dithering) | |
190 { | |
191 if(!shapingtype) | |
192 { | |
193 double tmp = Random_Equi(Dither.Dither); | |
194 Sum2 = tmp - Dither.LastRandomNumber[k]; | |
195 Dither.LastRandomNumber[k] = tmp; | |
196 Sum2 = Sum += Sum2; | |
197 val = ROUND64(Sum2)&Dither.Mask; | |
198 } else { | |
199 Sum2 = Random_Triangular(Dither.Dither) - scalar16(Dither.DitherHistory[k], Dither.FilterCoeff + i); | |
200 Sum += Dither.DitherHistory[k][(-1-i)&15] = Sum2; | |
201 Sum2 = Sum + scalar16(Dither.ErrorHistory[k], Dither.FilterCoeff + i ); | |
202 val = ROUND64(Sum2)&Dither.Mask; | |
203 Dither.ErrorHistory[k][(-1-i)&15] = (float)(Sum - val); | |
204 } | |
205 return val; | |
206 } | |
207 else | |
208 return ROUND64 (Sum); | |
209 } | |
210 | |
211 #else | |
212 | |
213 void* output_to_PCM(faacDecHandle hDecoder, | |
214 real_t **input, void *sample_buffer, uint8_t channels, | |
215 uint16_t frame_len, uint8_t format) | |
216 { | |
217 uint8_t ch; | |
218 uint16_t i; | |
219 int16_t *short_sample_buffer = (int16_t*)sample_buffer; | |
220 | |
221 /* Copy output to a standard PCM buffer */ | |
222 for (ch = 0; ch < channels; ch++) | |
223 { | |
224 for(i = 0; i < frame_len; i++) | |
225 { | |
226 int32_t tmp = input[ch][i]; | |
227 tmp += (1 << (REAL_BITS-1)); | |
228 tmp >>= REAL_BITS; | |
229 if (tmp > 0x7fff) tmp = 0x7fff; | |
230 else if (tmp <= -32768) tmp = -32768; | |
231 short_sample_buffer[(i*channels)+ch] = (int16_t)tmp; | |
232 } | |
233 } | |
234 | |
235 return sample_buffer; | |
236 } | |
237 | |
238 #endif |