blob: eff6587404dc258b3ec3ac639801b598e7e3fbe0 [file] [log] [blame]
Mike Melanson3ef8be22003-09-02 04:32:021/*
2 * Assorted DPCM codecs
Vittorio Giovara41ed7ab2016-04-27 17:45:233 * Copyright (c) 2003 The FFmpeg project
Mike Melanson3ef8be22003-09-02 04:32:024 *
Diego Biurrunb78e7192006-10-07 15:30:465 * This file is part of FFmpeg.
6 *
7 * FFmpeg 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 *
Diego Biurrunb78e7192006-10-07 15:30:4612 * FFmpeg 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
Diego Biurrunb78e7192006-10-07 15:30:4618 * License along with FFmpeg; 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
Mike Melanson3ef8be22003-09-02 04:32:0240#include "avcodec.h"
Justin Ruggles1de84012011-09-11 16:24:0341#include "bytestream.h"
Andreas Rheinhardta688f3c2022-03-16 17:18:2842#include "codec_internal.h"
Andreas Rheinhardt66b691f2022-08-24 19:28:1643#include "decode.h"
Ronald S. Bultje3a3f06b2012-03-19 02:33:0444#include "mathops.h"
Mike Melanson3ef8be22003-09-02 04:32:0245
46typedef struct DPCMContext {
Paul B Mahol29bdcf52017-06-02 10:43:0247 int16_t array[256];
Paul B Maholc5a545c2023-01-21 11:21:4448 int sample[2]; ///< previous sample (for SOL_DPCM and WADY_DPCM)
49 int scale; ///< scale for WADY_DPCM
Justin Ruggles0354fb72011-09-11 16:46:0650 const int8_t *sol_table; ///< delta table for SOL_DPCM
Mike Melanson3ef8be22003-09-02 04:32:0251} DPCMContext;
52
Paul B Maholc6bbdba2020-03-15 10:03:2753static const int32_t derf_steps[96] = {
54 0, 1, 2, 3, 4, 5, 6, 7,
55 8, 9, 10, 11, 12, 13, 14, 16,
56 17, 19, 21, 23, 25, 28, 31, 34,
57 37, 41, 45, 50, 55, 60, 66, 73,
58 80, 88, 97, 107, 118, 130, 143, 157,
59 173, 190, 209, 230, 253, 279, 307, 337,
60 371, 408, 449, 494, 544, 598, 658, 724,
61 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
62 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
63 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132,
64 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289,
65 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767,
66};
67
Justin Ruggles0354fb72011-09-11 16:46:0668static const int16_t interplay_delta_table[] = {
Mike Melanson3ef8be22003-09-02 04:32:0269 0, 1, 2, 3, 4, 5, 6, 7,
70 8, 9, 10, 11, 12, 13, 14, 15,
71 16, 17, 18, 19, 20, 21, 22, 23,
72 24, 25, 26, 27, 28, 29, 30, 31,
73 32, 33, 34, 35, 36, 37, 38, 39,
74 40, 41, 42, 43, 47, 51, 56, 61,
75 66, 72, 79, 86, 94, 102, 112, 122,
76 133, 145, 158, 173, 189, 206, 225, 245,
77 267, 292, 318, 348, 379, 414, 452, 493,
78 538, 587, 640, 699, 763, 832, 908, 991,
79 1081, 1180, 1288, 1405, 1534, 1673, 1826, 1993,
80 2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008,
81 4373, 4772, 5208, 5683, 6202, 6767, 7385, 8059,
82 8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206,
83 17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589,
84 -29973, -26728, -23186, -19322, -15105, -10503, -5481, -1,
85 1, 1, 5481, 10503, 15105, 19322, 23186, 26728,
86 29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
87 -17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597,
88 -8794, -8059, -7385, -6767, -6202, -5683, -5208, -4772,
89 -4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373,
90 -2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180,
91 -1081, -991, -908, -832, -763, -699, -640, -587,
92 -538, -493, -452, -414, -379, -348, -318, -292,
93 -267, -245, -225, -206, -189, -173, -158, -145,
94 -133, -122, -112, -102, -94, -86, -79, -72,
95 -66, -61, -56, -51, -47, -43, -42, -41,
96 -40, -39, -38, -37, -36, -35, -34, -33,
97 -32, -31, -30, -29, -28, -27, -26, -25,
98 -24, -23, -22, -21, -20, -19, -18, -17,
99 -16, -15, -14, -13, -12, -11, -10, -9,
100 -8, -7, -6, -5, -4, -3, -2, -1
101
102};
103
Justin Ruggles0354fb72011-09-11 16:46:06104static const int8_t sol_table_old[16] = {
Justin Ruggles4bad4642011-09-11 16:37:17105 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
106 -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0
107};
Mike Melansond08d7142004-09-28 03:09:49108
Justin Ruggles0354fb72011-09-11 16:46:06109static const int8_t sol_table_new[16] = {
Justin Ruggles4bad4642011-09-11 16:37:17110 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
111 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15
112};
Diego Biurrun115329f2005-12-17 18:14:38113
Justin Ruggles0354fb72011-09-11 16:46:06114static const int16_t sol_table_16[128] = {
Mike Melansond08d7142004-09-28 03:09:49115 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
116 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
117 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
118 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
119 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
120 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
121 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
122 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
123 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
124 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
125 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
126 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
127 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
128};
129
Paul B Maholc5a545c2023-01-21 11:21:44130static const int16_t wady_table[128] = {
131 0, 2, 4, 6, 8, 10, 12, 15,
132 18, 21, 24, 28, 32, 36, 40, 44,
133 49, 54, 59, 64, 70, 76, 82, 88,
134 95, 102, 109, 116, 124, 132, 140, 148,
135 160, 170, 180, 190, 200, 210, 220, 230,
136 240, 255, 270, 285, 300, 320, 340, 360,
137 380, 400, 425, 450, 475, 500, 525, 550,
138 580, 610, 650, 700, 750, 800, 900, 1000,
139 -0, -2, -4, -6, -8, -10, -12, -15,
140 -18, -21, -24, -28, -32, -36, -40, -44,
141 -49, -54, -59, -64, -70, -76, -82, -88,
142 -95, -102,-109,-116,-124,-132,-140,-148,
143 -160,-170,-180,-190,-200,-210,-220,-230,
144 -240,-255,-270,-285,-300,-320,-340,-360,
145 -380,-400,-425,-450,-475,-500,-525,-550,
146 -580,-610,-650,-700,-750,-800,-900,-1000,
147};
Mike Melansond08d7142004-09-28 03:09:49148
Zuxy Meng98a6fff2008-03-21 03:11:20149static av_cold int dpcm_decode_init(AVCodecContext *avctx)
Mike Melanson3ef8be22003-09-02 04:32:02150{
151 DPCMContext *s = avctx->priv_data;
152 int i;
Mike Melanson3ef8be22003-09-02 04:32:02153
Vittorio Giovarac5022f52017-03-29 16:21:29154 if (avctx->ch_layout.nb_channels < 1 || avctx->ch_layout.nb_channels > 2) {
Piotr Bandurski8d889202012-11-05 16:44:24155 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
Justin Ruggles8d77d122011-09-11 16:40:40156 return AVERROR(EINVAL);
157 }
Mike Melanson3ef8be22003-09-02 04:32:02158
Mike Melansond08d7142004-09-28 03:09:49159 s->sample[0] = s->sample[1] = 0;
Mike Melanson3ef8be22003-09-02 04:32:02160
Paul B Maholc5a545c2023-01-21 11:21:44161 switch (avctx->codec->id) {
Mike Melanson3ef8be22003-09-02 04:32:02162
Anton Khirnov36ef5362012-08-05 09:11:04163 case AV_CODEC_ID_ROQ_DPCM:
Mike Melanson3ef8be22003-09-02 04:32:02164 /* initialize square table */
165 for (i = 0; i < 128; i++) {
Justin Rugglesf47f7ef2011-09-11 16:41:48166 int16_t square = i * i;
Paul B Mahol29bdcf52017-06-02 10:43:02167 s->array[i ] = square;
168 s->array[i + 128] = -square;
Mike Melanson3ef8be22003-09-02 04:32:02169 }
170 break;
171
Anton Khirnov36ef5362012-08-05 09:11:04172 case AV_CODEC_ID_SOL_DPCM:
Mike Melansond08d7142004-09-28 03:09:49173 switch(avctx->codec_tag){
174 case 1:
Justin Ruggles4bad4642011-09-11 16:37:17175 s->sol_table = sol_table_old;
Mike Melansond08d7142004-09-28 03:09:49176 s->sample[0] = s->sample[1] = 0x80;
177 break;
178 case 2:
Justin Ruggles4bad4642011-09-11 16:37:17179 s->sol_table = sol_table_new;
Mike Melansond08d7142004-09-28 03:09:49180 s->sample[0] = s->sample[1] = 0x80;
181 break;
182 case 3:
Mike Melansond08d7142004-09-28 03:09:49183 break;
184 default:
185 av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
186 return -1;
187 }
188 break;
Diego Biurrun115329f2005-12-17 18:14:38189
Paul B Mahol035ae3c2015-10-24 18:41:32190 case AV_CODEC_ID_SDX2_DPCM:
191 for (i = -128; i < 128; i++) {
192 int16_t square = i * i * 2;
Paul B Mahol29bdcf52017-06-02 10:43:02193 s->array[i+128] = i < 0 ? -square: square;
194 }
195 break;
196
Paul B Mahol01343682023-01-24 15:14:25197 case AV_CODEC_ID_CBD2_DPCM:
198 for (i = -128; i < 128; i++) {
199 int16_t cube = (i * i * i) / 64;
200 s->array[i+128] = cube;
201 }
202 break;
203
Paul B Mahol29bdcf52017-06-02 10:43:02204 case AV_CODEC_ID_GREMLIN_DPCM: {
205 int delta = 0;
206 int code = 64;
207 int step = 45;
208
209 s->array[0] = 0;
210 for (i = 0; i < 127; i++) {
211 delta += (code >> 5);
212 code += step;
213 step += 2;
214
215 s->array[i*2 + 1] = delta;
216 s->array[i*2 + 2] = -delta;
217 }
218 s->array[255] = delta + (code >> 5);
Paul B Mahol035ae3c2015-10-24 18:41:32219 }
220 break;
221
Paul B Maholc5a545c2023-01-21 11:21:44222 case AV_CODEC_ID_WADY_DPCM:
223 s->scale = (avctx->extradata && avctx->extradata_size > 0) ? avctx->extradata[0] : 1;
224 break;
225
Mike Melanson3ef8be22003-09-02 04:32:02226 default:
227 break;
228 }
229
Anton Khirnov36ef5362012-08-05 09:11:04230 if (avctx->codec->id == AV_CODEC_ID_SOL_DPCM && avctx->codec_tag != 3)
Justin Ruggles04b24cf2011-09-11 16:04:46231 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
232 else
233 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
234
Mike Melanson3ef8be22003-09-02 04:32:02235 return 0;
236}
237
Justin Ruggles4bad4642011-09-11 16:37:17238
Andreas Rheinhardtce7dbd02022-03-30 19:33:24239static int dpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
Justin Ruggles0eea2122011-09-06 16:17:45240 int *got_frame_ptr, AVPacket *avpkt)
Mike Melanson3ef8be22003-09-02 04:32:02241{
Thilo Borgmann7a00bba2009-04-07 15:59:50242 int buf_size = avpkt->size;
Mike Melanson3ef8be22003-09-02 04:32:02243 DPCMContext *s = avctx->priv_data;
Justin Ruggles0eea2122011-09-06 16:17:45244 int out = 0, ret;
Mike Melanson3ef8be22003-09-02 04:32:02245 int predictor[2];
Justin Rugglesb09c7ee2011-09-11 15:13:04246 int ch = 0;
Vittorio Giovarac5022f52017-03-29 16:21:29247 int stereo = avctx->ch_layout.nb_channels - 1;
Ronald S. Bultje3a3f06b2012-03-19 02:33:04248 int16_t *output_samples, *samples_end;
249 GetByteContext gb;
Mike Melanson3ef8be22003-09-02 04:32:02250
Ronald S. Bultje3a3f06b2012-03-19 02:33:04251 if (stereo && (buf_size & 1))
Alex Conversece7aee92012-02-17 22:13:40252 buf_size--;
Ronald S. Bultje3a3f06b2012-03-19 02:33:04253 bytestream2_init(&gb, avpkt->data, buf_size);
Alex Conversece7aee92012-02-17 22:13:40254
Justin Ruggles76db17d2011-09-11 15:51:08255 /* calculate output size */
256 switch(avctx->codec->id) {
Anton Khirnov36ef5362012-08-05 09:11:04257 case AV_CODEC_ID_ROQ_DPCM:
Justin Ruggles76db17d2011-09-11 15:51:08258 out = buf_size - 8;
259 break;
Anton Khirnov36ef5362012-08-05 09:11:04260 case AV_CODEC_ID_INTERPLAY_DPCM:
Vittorio Giovarac5022f52017-03-29 16:21:29261 out = buf_size - 6 - avctx->ch_layout.nb_channels;
Justin Ruggles76db17d2011-09-11 15:51:08262 break;
Anton Khirnov36ef5362012-08-05 09:11:04263 case AV_CODEC_ID_XAN_DPCM:
Vittorio Giovarac5022f52017-03-29 16:21:29264 out = buf_size - 2 * avctx->ch_layout.nb_channels;
Justin Ruggles76db17d2011-09-11 15:51:08265 break;
Anton Khirnov36ef5362012-08-05 09:11:04266 case AV_CODEC_ID_SOL_DPCM:
Justin Ruggles76db17d2011-09-11 15:51:08267 if (avctx->codec_tag != 3)
268 out = buf_size * 2;
269 else
270 out = buf_size;
271 break;
Paul B Maholc5a545c2023-01-21 11:21:44272 case AV_CODEC_ID_WADY_DPCM:
Paul B Maholc6bbdba2020-03-15 10:03:27273 case AV_CODEC_ID_DERF_DPCM:
Paul B Mahol29bdcf52017-06-02 10:43:02274 case AV_CODEC_ID_GREMLIN_DPCM:
Paul B Mahol01343682023-01-24 15:14:25275 case AV_CODEC_ID_CBD2_DPCM:
Paul B Mahol035ae3c2015-10-24 18:41:32276 case AV_CODEC_ID_SDX2_DPCM:
277 out = buf_size;
278 break;
Justin Ruggles76db17d2011-09-11 15:51:08279 }
Justin Ruggles8dbc6d02011-11-02 20:49:38280 if (out <= 0) {
Justin Ruggles08bd22a2011-09-11 17:18:51281 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
282 return AVERROR(EINVAL);
283 }
Vittorio Giovarac5022f52017-03-29 16:21:29284 if (out % avctx->ch_layout.nb_channels) {
Michael Niedermayer92115bb2012-01-26 16:04:51285 av_log(avctx, AV_LOG_WARNING, "channels have differing number of samples\n");
286 }
Justin Ruggles0eea2122011-09-06 16:17:45287
288 /* get output buffer */
Vittorio Giovarac5022f52017-03-29 16:21:29289 frame->nb_samples = (out + avctx->ch_layout.nb_channels - 1) / avctx->ch_layout.nb_channels;
Clément Bœsch1ec94b02013-03-12 07:41:53290 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
Justin Ruggles0eea2122011-09-06 16:17:45291 return ret;
Justin Rugglesb8788672012-12-23 23:03:43292 output_samples = (int16_t *)frame->data[0];
Ronald S. Bultje3a3f06b2012-03-19 02:33:04293 samples_end = output_samples + out;
Kostya Shishkova2085a72007-09-22 09:21:43294
Mike Melanson3ef8be22003-09-02 04:32:02295 switch(avctx->codec->id) {
296
Anton Khirnov36ef5362012-08-05 09:11:04297 case AV_CODEC_ID_ROQ_DPCM:
Ronald S. Bultje3a3f06b2012-03-19 02:33:04298 bytestream2_skipu(&gb, 6);
Justin Ruggles1de84012011-09-11 16:24:03299
Justin Ruggles3db8db42011-09-11 15:19:00300 if (stereo) {
Ronald S. Bultje3a3f06b2012-03-19 02:33:04301 predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
302 predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
Justin Ruggles3db8db42011-09-11 15:19:00303 } else {
Ronald S. Bultje3a3f06b2012-03-19 02:33:04304 predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16);
Mike Melanson3ef8be22003-09-02 04:32:02305 }
Mike Melanson3ef8be22003-09-02 04:32:02306
307 /* decode the samples */
Ronald S. Bultje3a3f06b2012-03-19 02:33:04308 while (output_samples < samples_end) {
Paul B Mahol29bdcf52017-06-02 10:43:02309 predictor[ch] += s->array[bytestream2_get_byteu(&gb)];
Justin Ruggles4bad4642011-09-11 16:37:17310 predictor[ch] = av_clip_int16(predictor[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08311 *output_samples++ = predictor[ch];
Mike Melanson3ef8be22003-09-02 04:32:02312
313 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00314 ch ^= stereo;
Mike Melanson3ef8be22003-09-02 04:32:02315 }
316 break;
317
Anton Khirnov36ef5362012-08-05 09:11:04318 case AV_CODEC_ID_INTERPLAY_DPCM:
Ronald S. Bultje3a3f06b2012-03-19 02:33:04319 bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */
Justin Ruggles1de84012011-09-11 16:24:03320
Vittorio Giovarac5022f52017-03-29 16:21:29321 for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
Ronald S. Bultje3a3f06b2012-03-19 02:33:04322 predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
Justin Ruggles1de84012011-09-11 16:24:03323 *output_samples++ = predictor[ch];
Mike Melanson3ef8be22003-09-02 04:32:02324 }
325
Justin Ruggles1de84012011-09-11 16:24:03326 ch = 0;
Ronald S. Bultje3a3f06b2012-03-19 02:33:04327 while (output_samples < samples_end) {
328 predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)];
Justin Ruggles4bad4642011-09-11 16:37:17329 predictor[ch] = av_clip_int16(predictor[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08330 *output_samples++ = predictor[ch];
Mike Melanson3ef8be22003-09-02 04:32:02331
332 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00333 ch ^= stereo;
Mike Melanson3ef8be22003-09-02 04:32:02334 }
Mike Melanson3ef8be22003-09-02 04:32:02335 break;
Mike Melanson9937e682003-09-08 04:10:59336
Anton Khirnov36ef5362012-08-05 09:11:04337 case AV_CODEC_ID_XAN_DPCM:
Justin Rugglesfc6faee2011-09-11 16:13:13338 {
339 int shift[2] = { 4, 4 };
Mike Melanson9937e682003-09-08 04:10:59340
Vittorio Giovarac5022f52017-03-29 16:21:29341 for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++)
Ronald S. Bultje3a3f06b2012-03-19 02:33:04342 predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
Justin Ruggles1de84012011-09-11 16:24:03343
344 ch = 0;
Ronald S. Bultje3a3f06b2012-03-19 02:33:04345 while (output_samples < samples_end) {
346 int diff = bytestream2_get_byteu(&gb);
347 int n = diff & 3;
348
349 if (n == 3)
Justin Rugglesb09c7ee2011-09-11 15:13:04350 shift[ch]++;
Mike Melanson9937e682003-09-08 04:10:59351 else
Ronald S. Bultje3a3f06b2012-03-19 02:33:04352 shift[ch] -= (2 * n);
353 diff = sign_extend((diff &~ 3) << 8, 16);
354
Michael Niedermayer20ade592020-04-09 13:37:55355 /* saturate the shifter to 0..31 */
356 shift[ch] = av_clip_uintp2(shift[ch], 5);
Mike Melanson9937e682003-09-08 04:10:59357
Justin Rugglesb09c7ee2011-09-11 15:13:04358 diff >>= shift[ch];
359 predictor[ch] += diff;
Mike Melanson9937e682003-09-08 04:10:59360
Justin Rugglesb09c7ee2011-09-11 15:13:04361 predictor[ch] = av_clip_int16(predictor[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08362 *output_samples++ = predictor[ch];
Mike Melanson9937e682003-09-08 04:10:59363
364 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00365 ch ^= stereo;
Mike Melanson9937e682003-09-08 04:10:59366 }
367 break;
Justin Rugglesfc6faee2011-09-11 16:13:13368 }
Anton Khirnov36ef5362012-08-05 09:11:04369 case AV_CODEC_ID_SOL_DPCM:
Mike Melansond08d7142004-09-28 03:09:49370 if (avctx->codec_tag != 3) {
Justin Rugglesb8788672012-12-23 23:03:43371 uint8_t *output_samples_u8 = frame->data[0],
Ronald S. Bultje3a3f06b2012-03-19 02:33:04372 *samples_end_u8 = output_samples_u8 + out;
373 while (output_samples_u8 < samples_end_u8) {
374 int n = bytestream2_get_byteu(&gb);
Justin Ruggles04b24cf2011-09-11 16:04:46375
376 s->sample[0] += s->sol_table[n >> 4];
377 s->sample[0] = av_clip_uint8(s->sample[0]);
378 *output_samples_u8++ = s->sample[0];
379
380 s->sample[stereo] += s->sol_table[n & 0x0F];
381 s->sample[stereo] = av_clip_uint8(s->sample[stereo]);
382 *output_samples_u8++ = s->sample[stereo];
Mike Melansond08d7142004-09-28 03:09:49383 }
384 } else {
Ronald S. Bultje3a3f06b2012-03-19 02:33:04385 while (output_samples < samples_end) {
386 int n = bytestream2_get_byteu(&gb);
Justin Ruggles5a54d512011-09-11 16:43:03387 if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
388 else s->sample[ch] += sol_table_16[n & 0x7F];
Justin Rugglesb09c7ee2011-09-11 15:13:04389 s->sample[ch] = av_clip_int16(s->sample[ch]);
Justin Ruggles76db17d2011-09-11 15:51:08390 *output_samples++ = s->sample[ch];
Mike Melansond08d7142004-09-28 03:09:49391 /* toggle channel */
Justin Ruggles3db8db42011-09-11 15:19:00392 ch ^= stereo;
Mike Melansond08d7142004-09-28 03:09:49393 }
394 }
395 break;
Paul B Mahol035ae3c2015-10-24 18:41:32396
Paul B Mahol01343682023-01-24 15:14:25397 case AV_CODEC_ID_CBD2_DPCM:
Paul B Mahol035ae3c2015-10-24 18:41:32398 case AV_CODEC_ID_SDX2_DPCM:
399 while (output_samples < samples_end) {
400 int8_t n = bytestream2_get_byteu(&gb);
401
402 if (!(n & 1))
403 s->sample[ch] = 0;
Paul B Mahol29bdcf52017-06-02 10:43:02404 s->sample[ch] += s->array[n + 128];
Paul B Mahol035ae3c2015-10-24 18:41:32405 s->sample[ch] = av_clip_int16(s->sample[ch]);
406 *output_samples++ = s->sample[ch];
407 ch ^= stereo;
408 }
409 break;
Paul B Mahol29bdcf52017-06-02 10:43:02410
411 case AV_CODEC_ID_GREMLIN_DPCM: {
412 int idx = 0;
413
414 while (output_samples < samples_end) {
415 uint8_t n = bytestream2_get_byteu(&gb);
416
Michael Niedermayerb1aecad2020-01-22 22:11:47417 *output_samples++ = s->sample[idx] += (unsigned)s->array[n];
Paul B Mahol29bdcf52017-06-02 10:43:02418 idx ^= 1;
419 }
420 }
421 break;
Paul B Maholc6bbdba2020-03-15 10:03:27422
423 case AV_CODEC_ID_DERF_DPCM: {
424 int idx = 0;
425
426 while (output_samples < samples_end) {
427 uint8_t n = bytestream2_get_byteu(&gb);
428 int index = FFMIN(n & 0x7f, 95);
429
430 s->sample[idx] += (n & 0x80 ? -1: 1) * derf_steps[index];
431 s->sample[idx] = av_clip_int16(s->sample[idx]);
432 *output_samples++ = s->sample[idx];
433 idx ^= stereo;
434 }
435 }
436 break;
Paul B Maholc5a545c2023-01-21 11:21:44437
438 case AV_CODEC_ID_WADY_DPCM: {
439 int idx = 0;
440
441 while (output_samples < samples_end) {
442 const uint8_t n = bytestream2_get_byteu(&gb);
443
444 if (n & 0x80)
445 s->sample[idx] = sign_extend((n & 0x7f) << 9, 16);
446 else
Michael Niedermayer8f0e2002023-04-16 15:45:41447 s->sample[idx] += s->scale * (unsigned)wady_table[n & 0x7f];
Paul B Maholc5a545c2023-01-21 11:21:44448 *output_samples++ = av_clip_int16(s->sample[idx]);
449 idx ^= stereo;
450 }
451 }
452 break;
Mike Melanson3ef8be22003-09-02 04:32:02453 }
454
Justin Rugglesb8788672012-12-23 23:03:43455 *got_frame_ptr = 1;
Justin Ruggles0eea2122011-09-06 16:17:45456
Alex Conversece7aee92012-02-17 22:13:40457 return avpkt->size;
Mike Melanson3ef8be22003-09-02 04:32:02458}
459
Paul B Mahol3110e282023-01-21 13:07:48460static void dpcm_flush(AVCodecContext *avctx)
461{
462 DPCMContext *s = avctx->priv_data;
463
464 s->sample[0] = s->sample[1] = 0;
465}
466
Diego Biurrun86714882011-09-23 19:11:15467#define DPCM_DECODER(id_, name_, long_name_) \
Andreas Rheinhardt20f97272022-03-16 20:09:54468const FFCodec ff_ ## name_ ## _decoder = { \
469 .p.name = #name_, \
Andreas Rheinhardt48286d42022-08-29 11:38:02470 CODEC_LONG_NAME(long_name_), \
Andreas Rheinhardt20f97272022-03-16 20:09:54471 .p.type = AVMEDIA_TYPE_AUDIO, \
472 .p.id = id_, \
473 .p.capabilities = AV_CODEC_CAP_DR1, \
Diego Biurrun86714882011-09-23 19:11:15474 .priv_data_size = sizeof(DPCMContext), \
475 .init = dpcm_decode_init, \
Paul B Mahol3110e282023-01-21 13:07:48476 .flush = dpcm_flush, \
Andreas Rheinhardt4243da42022-03-30 21:28:24477 FF_CODEC_DECODE_CB(dpcm_decode_frame), \
Mans Rullgard98ec8282011-02-10 12:04:25478}
Mike Melanson3ef8be22003-09-02 04:32:02479
Paul B Mahol01343682023-01-24 15:14:25480DPCM_DECODER(AV_CODEC_ID_CBD2_DPCM, cbd2_dpcm, "DPCM Cuberoot-Delta-Exact");
Paul B Maholc6bbdba2020-03-15 10:03:27481DPCM_DECODER(AV_CODEC_ID_DERF_DPCM, derf_dpcm, "DPCM Xilam DERF");
Paul B Mahol29bdcf52017-06-02 10:43:02482DPCM_DECODER(AV_CODEC_ID_GREMLIN_DPCM, gremlin_dpcm, "DPCM Gremlin");
Anton Khirnov36ef5362012-08-05 09:11:04483DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
484DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
Paul B Mahol035ae3c2015-10-24 18:41:32485DPCM_DECODER(AV_CODEC_ID_SDX2_DPCM, sdx2_dpcm, "DPCM Squareroot-Delta-Exact");
Anton Khirnov36ef5362012-08-05 09:11:04486DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
487DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
Paul B Maholc5a545c2023-01-21 11:21:44488DPCM_DECODER(AV_CODEC_ID_WADY_DPCM, wady_dpcm, "DPCM Marble WADY");