4 * This file is responsible for decoding Microsoft ADPCM data.
5 * Details about the data format can be found here:
6 * http://www.pcisys.net/~melanson/codecs/
8 * Copyright (c) 2002 Mike Melanson
10 * This file is part of MPlayer.
12 * MPlayer is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * MPlayer is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <libavutil/common.h>
32 #include <libavutil/intreadwrite.h>
36 #include "ad_internal.h"
38 static const ad_info_t info
=
40 "MS ADPCM audio decoder",
49 static const int ms_adapt_table
[] =
51 230, 230, 230, 230, 307, 409, 512, 614,
52 768, 614, 512, 409, 307, 230, 230, 230
55 static const uint8_t ms_adapt_coeff1
[] =
57 64, 128, 0, 48, 60, 115, 98
60 static const int8_t ms_adapt_coeff2
[] =
62 0, -64, 0, 16, 0, -52, -58
65 #define MS_ADPCM_PREAMBLE_SIZE 6
67 #define LE_16(x) ((int16_t)AV_RL16(x))
69 // clamp a number between 0 and 88
70 #define CLAMP_0_TO_88(x) x = av_clip(x, 0, 88);
71 // clamp a number within a signed 16-bit range
72 #define CLAMP_S16(x) x = av_clip_int16(x);
73 // clamp a number above 16
74 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16;
75 // sign extend a 4-bit value
76 #define SE_4BIT(x) if (x & 0x8) x -= 0x10;
78 static int preinit(sh_audio_t
*sh_audio
)
80 sh_audio
->audio_out_minsize
= sh_audio
->wf
->nBlockAlign
* 4;
81 sh_audio
->ds
->ss_div
=
82 (sh_audio
->wf
->nBlockAlign
- MS_ADPCM_PREAMBLE_SIZE
) * 2;
83 sh_audio
->audio_in_minsize
=
84 sh_audio
->ds
->ss_mul
= sh_audio
->wf
->nBlockAlign
;
88 static int init(sh_audio_t
*sh_audio
)
90 sh_audio
->channels
=sh_audio
->wf
->nChannels
;
91 sh_audio
->samplerate
=sh_audio
->wf
->nSamplesPerSec
;
92 sh_audio
->i_bps
= sh_audio
->wf
->nBlockAlign
*
93 (sh_audio
->channels
*sh_audio
->samplerate
) / sh_audio
->ds
->ss_div
;
94 sh_audio
->samplesize
=2;
99 static void uninit(sh_audio_t
*sh_audio
)
103 static int control(sh_audio_t
*sh_audio
,int cmd
,void* arg
, ...)
105 if(cmd
==ADCTRL_SKIP_FRAME
){
106 demux_read_data(sh_audio
->ds
, sh_audio
->a_in_buffer
,sh_audio
->ds
->ss_mul
);
109 return CONTROL_UNKNOWN
;
112 static inline int check_coeff(uint8_t c
) {
114 mp_msg(MSGT_DECAUDIO
, MSGL_WARN
,
115 "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n",
122 static int ms_adpcm_decode_block(unsigned short *output
, unsigned char *input
,
123 int channels
, int block_size
)
125 int current_channel
= 0;
134 int upper_nibble
= 1;
136 int snibble
; // signed nibble
139 if (channels
!= 1) channels
= 2;
140 if (block_size
< 7 * channels
)
143 // fetch the header information, in stereo if both channels are present
144 coeff_idx
= check_coeff(input
[stream_ptr
]);
145 coeff1
[0] = ms_adapt_coeff1
[coeff_idx
];
146 coeff2
[0] = ms_adapt_coeff2
[coeff_idx
];
150 coeff_idx
= check_coeff(input
[stream_ptr
]);
151 coeff1
[1] = ms_adapt_coeff1
[coeff_idx
];
152 coeff2
[1] = ms_adapt_coeff2
[coeff_idx
];
156 idelta
[0] = LE_16(&input
[stream_ptr
]);
160 idelta
[1] = LE_16(&input
[stream_ptr
]);
164 sample1
[0] = LE_16(&input
[stream_ptr
]);
168 sample1
[1] = LE_16(&input
[stream_ptr
]);
172 sample2
[0] = LE_16(&input
[stream_ptr
]);
176 sample2
[1] = LE_16(&input
[stream_ptr
]);
182 output
[out_ptr
++] = sample2
[0];
183 output
[out_ptr
++] = sample1
[0];
185 output
[out_ptr
++] = sample2
[0];
186 output
[out_ptr
++] = sample2
[1];
187 output
[out_ptr
++] = sample1
[0];
188 output
[out_ptr
++] = sample1
[1];
191 while (stream_ptr
< block_size
)
193 // get the next nibble
195 nibble
= snibble
= input
[stream_ptr
] >> 4;
197 nibble
= snibble
= input
[stream_ptr
++] & 0x0F;
201 // should this really be a division and not a shift?
202 // coefficients were originally scaled by for, which might have
203 // been an optimization for 8-bit CPUs _if_ a shift is correct
205 ((sample1
[current_channel
] * coeff1
[current_channel
]) +
206 (sample2
[current_channel
] * coeff2
[current_channel
])) / 64) +
207 (snibble
* idelta
[current_channel
]);
208 CLAMP_S16(predictor
);
209 sample2
[current_channel
] = sample1
[current_channel
];
210 sample1
[current_channel
] = predictor
;
211 output
[out_ptr
++] = predictor
;
213 // compute the next adaptive scale factor (a.k.a. the variable idelta)
214 idelta
[current_channel
] =
215 (ms_adapt_table
[nibble
] * idelta
[current_channel
]) / 256;
216 CLAMP_ABOVE_16(idelta
[current_channel
]);
218 // toggle the channel
219 current_channel
^= channels
- 1;
222 return (block_size
- (MS_ADPCM_PREAMBLE_SIZE
* channels
)) * 2;
225 static int decode_audio(sh_audio_t
*sh_audio
,unsigned char *buf
,int minlen
,int maxlen
)
228 if (demux_read_data(sh_audio
->ds
, sh_audio
->a_in_buffer
,
229 sh_audio
->ds
->ss_mul
) !=
230 sh_audio
->ds
->ss_mul
)
233 res
= ms_adpcm_decode_block(
234 (unsigned short*)buf
, sh_audio
->a_in_buffer
,
235 sh_audio
->wf
->nChannels
, sh_audio
->wf
->nBlockAlign
);
236 return res
< 0 ? res
: 2 * res
;