VirtualBox

source: vbox/trunk/src/libs/ffmpeg-20060710/libavcodec/dpcm.c@ 9441

Last change on this file since 9441 was 5776, checked in by vboxsync, 17 years ago

ffmpeg: exported to OSE

File size: 11.3 KB
Line 
1/*
2 * Assorted DPCM codecs
3 * Copyright (c) 2003 The ffmpeg Project.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/**
21 * @file: dpcm.c
22 * Assorted DPCM (differential pulse code modulation) audio codecs
23 * by Mike Melanson ([email protected])
24 * Xan DPCM decoder by Mario Brito ([email protected])
25 * for more information on the specific data formats, visit:
26 * http://www.pcisys.net/~melanson/codecs/simpleaudio.html
27 * SOL DPCMs implemented by Konstantin Shishkov
28 *
29 * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files
30 * found in the Wing Commander IV computer game. These AVI files contain
31 * WAVEFORMAT headers which report the audio format as 0x01: raw PCM.
32 * Clearly incorrect. To detect Xan DPCM, you will probably have to
33 * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan'
34 * (Xan video) for its video codec. Alternately, such AVI files also contain
35 * the fourcc 'Axan' in the 'auds' chunk of the AVI header.
36 */
37
38#include "avcodec.h"
39
40typedef struct DPCMContext {
41 int channels;
42 short roq_square_array[256];
43 long sample[2];//for SOL_DPCM
44 const int *sol_table;//for SOL_DPCM
45} DPCMContext;
46
47#define SATURATE_S16(x) if (x < -32768) x = -32768; \
48 else if (x > 32767) x = 32767;
49#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
50
51static int interplay_delta_table[] = {
52 0, 1, 2, 3, 4, 5, 6, 7,
53 8, 9, 10, 11, 12, 13, 14, 15,
54 16, 17, 18, 19, 20, 21, 22, 23,
55 24, 25, 26, 27, 28, 29, 30, 31,
56 32, 33, 34, 35, 36, 37, 38, 39,
57 40, 41, 42, 43, 47, 51, 56, 61,
58 66, 72, 79, 86, 94, 102, 112, 122,
59 133, 145, 158, 173, 189, 206, 225, 245,
60 267, 292, 318, 348, 379, 414, 452, 493,
61 538, 587, 640, 699, 763, 832, 908, 991,
62 1081, 1180, 1288, 1405, 1534, 1673, 1826, 1993,
63 2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008,
64 4373, 4772, 5208, 5683, 6202, 6767, 7385, 8059,
65 8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206,
66 17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589,
67 -29973, -26728, -23186, -19322, -15105, -10503, -5481, -1,
68 1, 1, 5481, 10503, 15105, 19322, 23186, 26728,
69 29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
70 -17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597,
71 -8794, -8059, -7385, -6767, -6202, -5683, -5208, -4772,
72 -4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373,
73 -2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180,
74 -1081, -991, -908, -832, -763, -699, -640, -587,
75 -538, -493, -452, -414, -379, -348, -318, -292,
76 -267, -245, -225, -206, -189, -173, -158, -145,
77 -133, -122, -112, -102, -94, -86, -79, -72,
78 -66, -61, -56, -51, -47, -43, -42, -41,
79 -40, -39, -38, -37, -36, -35, -34, -33,
80 -32, -31, -30, -29, -28, -27, -26, -25,
81 -24, -23, -22, -21, -20, -19, -18, -17,
82 -16, -15, -14, -13, -12, -11, -10, -9,
83 -8, -7, -6, -5, -4, -3, -2, -1
84
85};
86
87static const int sol_table_old[16] =
88 { 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15,
89 -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0};
90
91static const int sol_table_new[16] =
92 { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
93 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15};
94
95static const int sol_table_16[128] = {
96 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
97 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
98 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
99 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
100 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
101 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
102 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
103 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
104 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
105 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
106 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
107 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
108 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
109};
110
111
112
113static int dpcm_decode_init(AVCodecContext *avctx)
114{
115 DPCMContext *s = avctx->priv_data;
116 int i;
117 short square;
118
119 s->channels = avctx->channels;
120 s->sample[0] = s->sample[1] = 0;
121
122 switch(avctx->codec->id) {
123
124 case CODEC_ID_ROQ_DPCM:
125 /* initialize square table */
126 for (i = 0; i < 128; i++) {
127 square = i * i;
128 s->roq_square_array[i] = square;
129 s->roq_square_array[i + 128] = -square;
130 }
131 break;
132
133
134 case CODEC_ID_SOL_DPCM:
135 switch(avctx->codec_tag){
136 case 1:
137 s->sol_table=sol_table_old;
138 s->sample[0] = s->sample[1] = 0x80;
139 break;
140 case 2:
141 s->sol_table=sol_table_new;
142 s->sample[0] = s->sample[1] = 0x80;
143 break;
144 case 3:
145 s->sol_table=sol_table_16;
146 break;
147 default:
148 av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
149 return -1;
150 }
151 break;
152
153 default:
154 break;
155 }
156
157 return 0;
158}
159
160static int dpcm_decode_frame(AVCodecContext *avctx,
161 void *data, int *data_size,
162 uint8_t *buf, int buf_size)
163{
164 DPCMContext *s = avctx->priv_data;
165 int in, out = 0;
166 int predictor[2];
167 int channel_number = 0;
168 short *output_samples = data;
169 int shift[2];
170 unsigned char byte;
171 short diff;
172
173 if (!buf_size)
174 return 0;
175
176 switch(avctx->codec->id) {
177
178 case CODEC_ID_ROQ_DPCM:
179 if (s->channels == 1)
180 predictor[0] = LE_16(&buf[6]);
181 else {
182 predictor[0] = buf[7] << 8;
183 predictor[1] = buf[6] << 8;
184 }
185 SE_16BIT(predictor[0]);
186 SE_16BIT(predictor[1]);
187
188 /* decode the samples */
189 for (in = 8, out = 0; in < buf_size; in++, out++) {
190 predictor[channel_number] += s->roq_square_array[buf[in]];
191 SATURATE_S16(predictor[channel_number]);
192 output_samples[out] = predictor[channel_number];
193
194 /* toggle channel */
195 channel_number ^= s->channels - 1;
196 }
197 break;
198
199 case CODEC_ID_INTERPLAY_DPCM:
200 in = 6; /* skip over the stream mask and stream length */
201 predictor[0] = LE_16(&buf[in]);
202 in += 2;
203 SE_16BIT(predictor[0])
204 output_samples[out++] = predictor[0];
205 if (s->channels == 2) {
206 predictor[1] = LE_16(&buf[in]);
207 in += 2;
208 SE_16BIT(predictor[1])
209 output_samples[out++] = predictor[1];
210 }
211
212 while (in < buf_size) {
213 predictor[channel_number] += interplay_delta_table[buf[in++]];
214 SATURATE_S16(predictor[channel_number]);
215 output_samples[out++] = predictor[channel_number];
216
217 /* toggle channel */
218 channel_number ^= s->channels - 1;
219 }
220
221 break;
222
223 case CODEC_ID_XAN_DPCM:
224 in = 0;
225 shift[0] = shift[1] = 4;
226 predictor[0] = LE_16(&buf[in]);
227 in += 2;
228 SE_16BIT(predictor[0]);
229 if (s->channels == 2) {
230 predictor[1] = LE_16(&buf[in]);
231 in += 2;
232 SE_16BIT(predictor[1]);
233 }
234
235 while (in < buf_size) {
236 byte = buf[in++];
237 diff = (byte & 0xFC) << 8;
238 if ((byte & 0x03) == 3)
239 shift[channel_number]++;
240 else
241 shift[channel_number] -= (2 * (byte & 3));
242 /* saturate the shifter to a lower limit of 0 */
243 if (shift[channel_number] < 0)
244 shift[channel_number] = 0;
245
246 diff >>= shift[channel_number];
247 predictor[channel_number] += diff;
248
249 SATURATE_S16(predictor[channel_number]);
250 output_samples[out++] = predictor[channel_number];
251
252 /* toggle channel */
253 channel_number ^= s->channels - 1;
254 }
255 break;
256 case CODEC_ID_SOL_DPCM:
257 in = 0;
258 if (avctx->codec_tag != 3) {
259 while (in < buf_size) {
260 int n1, n2;
261 n1 = (buf[in] >> 4) & 0xF;
262 n2 = buf[in++] & 0xF;
263 s->sample[0] += s->sol_table[n1];
264 if (s->sample[0] < 0) s->sample[0] = 0;
265 if (s->sample[0] > 255) s->sample[0] = 255;
266 output_samples[out++] = (s->sample[0] - 128) << 8;
267 s->sample[s->channels - 1] += s->sol_table[n2];
268 if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0;
269 if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255;
270 output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8;
271 }
272 } else {
273 while (in < buf_size) {
274 int n;
275 n = buf[in++];
276 if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F];
277 else s->sample[channel_number] += s->sol_table[n & 0x7F];
278 SATURATE_S16(s->sample[channel_number]);
279 output_samples[out++] = s->sample[channel_number];
280 /* toggle channel */
281 channel_number ^= s->channels - 1;
282 }
283 }
284 break;
285 }
286
287 *data_size = out * sizeof(short);
288 return buf_size;
289}
290
291AVCodec roq_dpcm_decoder = {
292 "roq_dpcm",
293 CODEC_TYPE_AUDIO,
294 CODEC_ID_ROQ_DPCM,
295 sizeof(DPCMContext),
296 dpcm_decode_init,
297 NULL,
298 NULL,
299 dpcm_decode_frame,
300};
301
302AVCodec interplay_dpcm_decoder = {
303 "interplay_dpcm",
304 CODEC_TYPE_AUDIO,
305 CODEC_ID_INTERPLAY_DPCM,
306 sizeof(DPCMContext),
307 dpcm_decode_init,
308 NULL,
309 NULL,
310 dpcm_decode_frame,
311};
312
313AVCodec xan_dpcm_decoder = {
314 "xan_dpcm",
315 CODEC_TYPE_AUDIO,
316 CODEC_ID_XAN_DPCM,
317 sizeof(DPCMContext),
318 dpcm_decode_init,
319 NULL,
320 NULL,
321 dpcm_decode_frame,
322};
323
324AVCodec sol_dpcm_decoder = {
325 "sol_dpcm",
326 CODEC_TYPE_AUDIO,
327 CODEC_ID_SOL_DPCM,
328 sizeof(DPCMContext),
329 dpcm_decode_init,
330 NULL,
331 NULL,
332 dpcm_decode_frame,
333};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette