blob: d4cf806b82857410a47ca79d9348c8426a199774 [file] [log] [blame]
Mike Melanson3ef8be22003-09-02 04:32:021/*
2 * Assorted DPCM codecs
Diego Biurrun406792e2009-01-19 15:46:403 * Copyright (c) 2003 The ffmpeg Project
Mike Melanson3ef8be22003-09-02 04:32:024 *
Mans Rullgard2912e872011-03-18 17:35:105 * This file is part of Libav.
Diego Biurrunb78e7192006-10-07 15:30:466 *
Mans Rullgard2912e872011-03-18 17:35:107 * Libav is free software; you can redistribute it and/or
Mike Melanson3ef8be22003-09-02 04:32:028 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
Diego Biurrunb78e7192006-10-07 15:30:4610 * version 2.1 of the License, or (at your option) any later version.
Mike Melanson3ef8be22003-09-02 04:32:0211 *
Mans Rullgard2912e872011-03-18 17:35:1012 * Libav is distributed in the hope that it will be useful,
Mike Melanson3ef8be22003-09-02 04:32:0213 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
Mans Rullgard2912e872011-03-18 17:35:1018 * License along with Libav; if not, write to the Free Software
Diego Biurrun5509bff2006-01-12 22:43:2619 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Mike Melanson3ef8be22003-09-02 04:32:0220 */
21
22/**
Diego Biurrun33edd312010-07-02 10:59:3523 * @file
Mike Melanson3ef8be22003-09-02 04:32:0224 * Assorted DPCM (differential pulse code modulation) audio codecs
25 * by Mike Melanson ([email protected])
Mike Melanson9937e682003-09-08 04:10:5926 * Xan DPCM decoder by Mario Brito ([email protected])
Mike Melanson3ef8be22003-09-02 04:32:0227 * for more information on the specific data formats, visit:
28 * http://www.pcisys.net/~melanson/codecs/simpleaudio.html
Mike Melansond08d7142004-09-28 03:09:4929 * SOL DPCMs implemented by Konstantin Shishkov
Mike Melanson9937e682003-09-08 04:10:5930 *
31 * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files
32 * found in the Wing Commander IV computer game. These AVI files contain
33 * WAVEFORMAT headers which report the audio format as 0x01: raw PCM.
34 * Clearly incorrect. To detect Xan DPCM, you will probably have to
35 * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan'
36 * (Xan video) for its video codec. Alternately, such AVI files also contain
37 * the fourcc 'Axan' in the 'auds' chunk of the AVI header.
Mike Melanson3ef8be22003-09-02 04:32:0238 */
39
Diego Biurrun6a5d31a2009-01-11 22:19:4840#include "libavutil/intreadwrite.h"
Mike Melanson3ef8be22003-09-02 04:32:0241#include "avcodec.h"
Justin Ruggles1de84012011-09-11 16:24:0342#include "bytestream.h"
Mike Melanson3ef8be22003-09-02 04:32:0243
44typedef struct DPCMContext {
45 int channels;
Justin Rugglesf47f7ef2011-09-11 16:41:4846 int16_t roq_square_array[256];
Justin Ruggles04b24cf2011-09-11 16:04:4647 int sample[2]; ///< previous sample (for SOL_DPCM)
Justin Ruggles0354fb72011-09-11 16:46:0648 const int8_t *sol_table; ///< delta table for SOL_DPCM
Mike Melanson3ef8be22003-09-02 04:32:0249} DPCMContext;
50
Justin Ruggles0354fb72011-09-11 16:46:0651static const int16_t interplay_delta_table[] = {
Mike Melanson3ef8be22003-09-02 04:32:0252 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
Justin Ruggles0354fb72011-09-11 16:46:0687static const int8_t sol_table_old[16] = {
Justin Ruggles4bad4642011-09-11 16:37:1788 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
89 -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0
90};
Mike Melansond08d7142004-09-28 03:09:4991
Justin Ruggles0354fb72011-09-11 16:46:0692static const int8_t sol_table_new[16] = {
Justin Ruggles4bad4642011-09-11 16:37:1793 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
94 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15
95};
Diego Biurrun115329f2005-12-17 18:14:3896
Justin Ruggles0354fb72011-09-11 16:46:0697static const int16_t sol_table_16[128] = {
Mike Melansond08d7142004-09-28 03:09:4998 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
99 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
100 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
101 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
102 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
103 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
104 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
105 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
106 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
107 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
108 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
109 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
110 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
111};
112
113
Zuxy Meng98a6fff2008-03-21 03:11:20114static av_cold int dpcm_decode_init(AVCodecContext *avctx)
Mike Melanson3ef8be22003-09-02 04:32:02115{
116 DPCMContext *s = avctx->priv_data;
117 int i;
Mike Melanson3ef8be22003-09-02 04:32:02118
Justin Ruggles8d77d122011-09-11 16:40:40119 if (avctx->channels < 1 || avctx->channels > 2) {
120 av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");
121 return AVERROR(EINVAL);
122 }
123
Mike Melanson3ef8be22003-09-02 04:32:02124 s->channels = avctx->channels;
Mike Melansond08d7142004-09-28 03:09:49125 s->sample[0] = s->sample[1] = 0;
Mike Melanson3ef8be22003-09-02 04:32:02126
127 switch(avctx->codec->id) {
128
129 case CODEC_ID_ROQ_DPCM:
130 /* initialize square table */
131 for (i = 0; i < 128; i++) {
Justin Rugglesf47f7ef2011-09-11 16:41:48132 int16_t square = i * i;
Justin Ruggles4bad4642011-09-11 16:37:17133 s->roq_square_array[i ] = square;
Mike Melanson3ef8be22003-09-02 04:32:02134 s->roq_square_array[i + 128] = -square;
135 }
136 break;
137
Mike Melansond08d7142004-09-28 03:09:49138 case CODEC_ID_SOL_DPCM:
139 switch(avctx->codec_tag){
140 case 1:
Justin Ruggles4bad4642011-09-11 16:37:17141 s->sol_table = sol_table_old;
Mike Melansond08d7142004-09-28 03:09:49142 s->sample[0] = s->sample[1] = 0x80;
143 break;
144 case 2:
Justin Ruggles4bad4642011-09-11 16:37:17145 s->sol_table = sol_table_new;
Mike Melansond08d7142004-09-28 03:09:49146 s->sample[0] = s->sample[1] = 0x80;
147 break;
148 case 3:
Mike Melansond08d7142004-09-28 03:09:49149 break;
150 default:
151 av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
152 return -1;
153 }
154 break;
Diego Biurrun115329f2005-12-17 18:14:38155
Mike Melanson3ef8be22003-09-02 04:32:02156 default:
157 break;
158 }
159
Justin Ruggles04b24cf2011-09-11 16:04:46160 if (avctx->codec->id == CODEC_ID_SOL_DPCM && avctx->codec_tag != 3)
161 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
162 else
163 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
164
Mike Melanson3ef8be22003-09-02 04:32:02165 return 0;
166}
167
Justin Ruggles4bad4642011-09-11 16:37:17168
169static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
Thilo Borgmann7a00bba2009-04-07 15:59:50170 AVPacket *avpkt)
Mike Melanson3ef8be22003-09-02 04:32:02171{
Thilo Borgmann7a00bba2009-04-07 15:59:50172 const uint8_t *buf = avpkt->data;
173 int buf_size = avpkt->size;
Justin Ruggles1de84012011-09-11 16:24:03174 const uint8_t *buf_end = buf + buf_size;
Mike Melanson3ef8be22003-09-02 04:32:02175 DPCMContext *s = avctx->priv_data;
Justin Ruggles1de84012011-09-11 16:24:03176 int out = 0;
Mike Melanson3ef8be22003-09-02 04:32:02177 int predictor[2];
Justin Rugglesb09c7ee2011-09-11 15:13:04178 int ch = 0;
Justin Ruggles3db8db42011-09-11 15:19:00179 int stereo = s->channels - 1;
Justin Rugglesf47f7ef2011-09-11 16:41:48180 int16_t *output_samples = data;
Mike Melanson3ef8be22003-09-02 04:32:02181
Mike Melansonc89c1d22004-01-31 17:30:28182 if (!buf_size)
183 return 0;
184
Justin Ruggles76db17d2011-09-11 15:51:08185 /* calculate output size */
186 switch(avctx->codec->id) {
187 case CODEC_ID_ROQ_DPCM:
188 out = buf_size - 8;
189 break;
190 case CODEC_ID_INTERPLAY_DPCM:
191 out = buf_size - 6 - s->channels;
192 break;
193 case CODEC_ID_XAN_DPCM:
194 out = buf_size - 2 * s->channels;
195 break;
196 case CODEC_ID_SOL_DPCM:
197 if (avctx->codec_tag != 3)
198 out = buf_size * 2;
199 else
200 out = buf_size;
201 break;
202 }
203 out *= av_get_bytes_per_sample(avctx->sample_fmt);
204
205 if (*data_size < out) {
206 av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
207 return AVERROR(EINVAL);
208 }
Kostya Shishkova2085a72007-09-22 09:21:43209
Mike Melanson3ef8be22003-09-02 04:32:02210 switch(avctx->codec->id) {
211
212 case CODEC_ID_ROQ_DPCM:
Justin Ruggles1de84012011-09-11 16:24:03213 buf += 6;
214
Justin Ruggles3db8db42011-09-11 15:19:00215 if (stereo) {
Justin Ruggles1de84012011-09-11 16:24:03216 predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8);
217 predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8);
Justin Ruggles3db8db42011-09-11 15:19:00218 } else {
Justin Ruggles1de84012011-09-11 16:24:03219 predictor[0] = (int16_t)bytestream_get_le16(&buf);
Mike Melanson3ef8be22003-09-02 04:32:02220 }
Mike Melanson3ef8be22003-09-02 04:32:02221
222 /* decode the samples */
Justin Ruggles1de84012011-09-11 16:24:03223 while (buf < buf_end) {
224 predictor[ch] += s->roq_square_array[*buf++];
Justin Ruggles4bad4642011-09-11 16:37:17225 predictor[ch] = av_clip_int16(predictor[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08226 *output_samples++ = predictor[ch];
Mike Melanson3ef8be22003-09-02 04:32:02227
228 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00229 ch ^= stereo;
Mike Melanson3ef8be22003-09-02 04:32:02230 }
231 break;
232
233 case CODEC_ID_INTERPLAY_DPCM:
Justin Ruggles1de84012011-09-11 16:24:03234 buf += 6; /* skip over the stream mask and stream length */
235
236 for (ch = 0; ch < s->channels; ch++) {
237 predictor[ch] = (int16_t)bytestream_get_le16(&buf);
238 *output_samples++ = predictor[ch];
Mike Melanson3ef8be22003-09-02 04:32:02239 }
240
Justin Ruggles1de84012011-09-11 16:24:03241 ch = 0;
242 while (buf < buf_end) {
243 predictor[ch] += interplay_delta_table[*buf++];
Justin Ruggles4bad4642011-09-11 16:37:17244 predictor[ch] = av_clip_int16(predictor[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08245 *output_samples++ = predictor[ch];
Mike Melanson3ef8be22003-09-02 04:32:02246
247 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00248 ch ^= stereo;
Mike Melanson3ef8be22003-09-02 04:32:02249 }
Mike Melanson3ef8be22003-09-02 04:32:02250 break;
Mike Melanson9937e682003-09-08 04:10:59251
252 case CODEC_ID_XAN_DPCM:
Justin Rugglesfc6faee2011-09-11 16:13:13253 {
254 int shift[2] = { 4, 4 };
Mike Melanson9937e682003-09-08 04:10:59255
Justin Ruggles1de84012011-09-11 16:24:03256 for (ch = 0; ch < s->channels; ch++)
257 predictor[ch] = (int16_t)bytestream_get_le16(&buf);
258
259 ch = 0;
260 while (buf < buf_end) {
261 uint8_t n = *buf++;
Justin Rugglesfc6faee2011-09-11 16:13:13262 int16_t diff = (n & 0xFC) << 8;
Justin Ruggles989bb7b2011-09-11 16:08:38263 if ((n & 0x03) == 3)
Justin Rugglesb09c7ee2011-09-11 15:13:04264 shift[ch]++;
Mike Melanson9937e682003-09-08 04:10:59265 else
Justin Ruggles989bb7b2011-09-11 16:08:38266 shift[ch] -= (2 * (n & 3));
Mike Melanson9937e682003-09-08 04:10:59267 /* saturate the shifter to a lower limit of 0 */
Justin Rugglesb09c7ee2011-09-11 15:13:04268 if (shift[ch] < 0)
269 shift[ch] = 0;
Mike Melanson9937e682003-09-08 04:10:59270
Justin Rugglesb09c7ee2011-09-11 15:13:04271 diff >>= shift[ch];
272 predictor[ch] += diff;
Mike Melanson9937e682003-09-08 04:10:59273
Justin Rugglesb09c7ee2011-09-11 15:13:04274 predictor[ch] = av_clip_int16(predictor[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08275 *output_samples++ = predictor[ch];
Mike Melanson9937e682003-09-08 04:10:59276
277 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00278 ch ^= stereo;
Mike Melanson9937e682003-09-08 04:10:59279 }
280 break;
Justin Rugglesfc6faee2011-09-11 16:13:13281 }
Mike Melansond08d7142004-09-28 03:09:49282 case CODEC_ID_SOL_DPCM:
Mike Melansond08d7142004-09-28 03:09:49283 if (avctx->codec_tag != 3) {
Justin Ruggles04b24cf2011-09-11 16:04:46284 uint8_t *output_samples_u8 = data;
Justin Ruggles1de84012011-09-11 16:24:03285 while (buf < buf_end) {
286 uint8_t n = *buf++;
Justin Ruggles04b24cf2011-09-11 16:04:46287
288 s->sample[0] += s->sol_table[n >> 4];
289 s->sample[0] = av_clip_uint8(s->sample[0]);
290 *output_samples_u8++ = s->sample[0];
291
292 s->sample[stereo] += s->sol_table[n & 0x0F];
293 s->sample[stereo] = av_clip_uint8(s->sample[stereo]);
294 *output_samples_u8++ = s->sample[stereo];
Mike Melansond08d7142004-09-28 03:09:49295 }
296 } else {
Justin Ruggles1de84012011-09-11 16:24:03297 while (buf < buf_end) {
298 uint8_t n = *buf++;
Justin Ruggles5a54d512011-09-11 16:43:03299 if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
300 else s->sample[ch] += sol_table_16[n & 0x7F];
Justin Rugglesb09c7ee2011-09-11 15:13:04301 s->sample[ch] = av_clip_int16(s->sample[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08302 *output_samples++ = s->sample[ch];
Mike Melansond08d7142004-09-28 03:09:49303 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00304 ch ^= stereo;
Mike Melansond08d7142004-09-28 03:09:49305 }
306 }
307 break;
Mike Melanson3ef8be22003-09-02 04:32:02308 }
309
Justin Ruggles76db17d2011-09-11 15:51:08310 *data_size = out;
Mike Melanson3ef8be22003-09-02 04:32:02311 return buf_size;
312}
313
Diego Biurrun86714882011-09-23 19:11:15314#define DPCM_DECODER(id_, name_, long_name_) \
315AVCodec ff_ ## name_ ## _decoder = { \
316 .name = #name_, \
317 .type = AVMEDIA_TYPE_AUDIO, \
318 .id = id_, \
319 .priv_data_size = sizeof(DPCMContext), \
320 .init = dpcm_decode_init, \
321 .decode = dpcm_decode_frame, \
322 .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
Mans Rullgard44adbeb2011-02-10 12:04:25323}
Mike Melanson3ef8be22003-09-02 04:32:02324
Diego Biurrun12dd57f2009-03-02 06:01:32325DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
Justin Ruggles4bad4642011-09-11 16:37:17326DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
327DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
328DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");