ScummVM API documentation
adpcm_intern.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
30#ifndef AUDIO_ADPCM_INTERN_H
31#define AUDIO_ADPCM_INTERN_H
32
33#include "audio/audiostream.h"
34#include "common/endian.h"
35#include "common/ptr.h"
36#include "common/array.h"
37#include "common/stream.h"
38#include "common/textconsole.h"
39
40namespace Audio {
41
43protected:
45 int32 _startpos;
46 const int32 _endpos;
47 const int _channels;
48 const uint32 _blockAlign;
49 uint32 _blockPos[2];
50 const int _rate;
51
52 struct ADPCMStatus {
53 // OKI/IMA
54 struct {
55 int32 last;
56 int32 stepIndex;
57 int16 sample[2];
58 } ima_ch[2];
59 } _status;
60
61 virtual void reset();
62
63public:
64 ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign);
65
66 bool endOfData() const override { return (_stream->eos() || _stream->pos() >= _endpos); }
67 bool isStereo() const override { return _channels == 2; }
68 int getRate() const override { return _rate; }
69
70 bool rewind() override;
71 bool seek(const Timestamp &where) override { return false; }
72 Timestamp getLength() const override { return Timestamp(); }
73
81 static const int16 _stepAdjustTable[16];
82};
83
85public:
86 Oki_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
87 : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { _decodedSampleCount = 0; }
88
89 bool endOfData() const override { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
90
91 int readBuffer(int16 *buffer, const int numSamples) override;
92
93protected:
94 int16 decodeOKI(byte);
95
96private:
97 uint8 _decodedSampleCount;
98 int16 _decodedSamples[2];
99};
100
102public:
103 XA_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
104 : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { _decodedSampleCount = 0; }
105
106 bool endOfData() const override { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
107
108 int readBuffer(int16 *buffer, const int numSamples) override;
109
110protected:
111 void decodeXA(const byte *src);
112
113private:
114 uint8 _decodedSampleCount;
115 uint8 _decodedSampleIndex;
116 int16 _decodedSamples[28 * 2 * 4];
117};
118
120protected:
121 int16 decodeIMA(byte code, int channel = 0, int shift = 3); // Default to using the left channel/using one channel
122
123public:
124 Ima_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
125 : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {}
126
130 static const int16 _imaTable[89];
131};
132
134public:
135 DVI_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
136 : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { _decodedSampleCount = 0; }
137
138 bool endOfData() const override { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
139
140 int readBuffer(int16 *buffer, const int numSamples) override;
141
142private:
143 uint8 _decodedSampleCount;
144 int16 _decodedSamples[2];
145};
146
148protected:
149 // Apple QuickTime IMA ADPCM
150 int32 _streamPos[2];
151 int16 _buffer[2][2];
152 uint8 _chunkPos[2];
153
154 void reset() override {
155 Ima_ADPCMStream::reset();
156 _chunkPos[0] = 0;
157 _chunkPos[1] = 0;
158 _streamPos[0] = 0;
159 _streamPos[1] = _blockAlign;
160 }
161
162public:
163 Apple_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
164 : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
165 _chunkPos[0] = 0;
166 _chunkPos[1] = 0;
167 _streamPos[0] = 0;
168 _streamPos[1] = _blockAlign;
169 }
170
171 int readBuffer(int16 *buffer, const int numSamples) override;
172};
173
175public:
176 MSIma_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
177 : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
178
179 if (blockAlign == 0)
180 error("MSIma_ADPCMStream(): blockAlign isn't specified");
181
182 if (blockAlign % (_channels * 4))
183 error("MSIma_ADPCMStream(): invalid blockAlign");
184
185 _samplesLeft[0] = 0;
186 _samplesLeft[1] = 0;
187 }
188
189 int readBuffer(int16 *buffer, const int numSamples) override;
190
191 void reset() override {
192 Ima_ADPCMStream::reset();
193 _samplesLeft[0] = 0;
194 _samplesLeft[1] = 0;
195 }
196
197private:
198 int16 _buffer[2][8];
199 int _samplesLeft[2];
200};
201
203protected:
205 byte predictor;
206 int16 delta;
207 int16 coeff1;
208 int16 coeff2;
209 int16 sample1;
210 int16 sample2;
211 };
212
213 struct {
214 // MS ADPCM
215 ADPCMChannelStatus ch[2];
216 } _status;
217
218 void reset() override {
219 ADPCMStream::reset();
220 memset(&_status, 0, sizeof(_status));
221 }
222
223public:
224 MS_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
225 : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
226 if (blockAlign == 0)
227 error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM");
228 memset(&_status, 0, sizeof(_status));
229 _decodedSampleCount = 0;
230 _decodedSampleIndex = 0;
231 }
232
233 bool endOfData() const override { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
234
235 int readBuffer(int16 *buffer, const int numSamples) override;
236
237protected:
238 int16 decodeMS(ADPCMChannelStatus *c, byte);
239
240private:
241 uint8 _decodedSampleCount;
242 uint8 _decodedSampleIndex;
243 int16 _decodedSamples[4];
244};
245
246// Duck DK3 IMA ADPCM Decoder
247// Based on FFmpeg's decoder and https://wiki.multimedia.cx/index.php?title=Duck_DK3_IMA_ADPCM
248
250public:
251 DK3_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
252 : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
253
254 // DK3 only works as a stereo stream
255 assert(channels == 2);
256 }
257
258 int readBuffer(int16 *buffer, const int numSamples) override;
259
260private:
261 byte _nibble, _lastByte;
262 bool _topNibble;
263};
264
266public:
267 FOURXM_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels)
268 : Ima_ADPCMStream(stream, disposeAfterUse, size, rate, channels, 0) {
269 decode();
270 }
271
272 int readBuffer(int16 *buffer, const int numSamples) override;
273 bool endOfData() const override {
274 return !_planes.empty() && _samplePos >= _planes[0].size();
275 }
276
277 void reset() override {
278 Ima_ADPCMStream::reset();
279 _samplePos = 0;
280 _planes.clear();
281 }
282
283private:
284 void decode();
285
286 uint _samplePos = 0;
288};
289
290} // End of namespace Audio
291
292#endif
Definition: adpcm_intern.h:42
static const int16 _stepAdjustTable[16]
Definition: adpcm_intern.h:81
Timestamp getLength() const override
Definition: adpcm_intern.h:72
bool seek(const Timestamp &where) override
Definition: adpcm_intern.h:71
int getRate() const override
Definition: adpcm_intern.h:68
bool rewind() override
bool endOfData() const override
Definition: adpcm_intern.h:66
bool isStereo() const override
Definition: adpcm_intern.h:67
Definition: adpcm_intern.h:147
int readBuffer(int16 *buffer, const int numSamples) override
Definition: adpcm_intern.h:249
int readBuffer(int16 *buffer, const int numSamples) override
Definition: adpcm_intern.h:133
int readBuffer(int16 *buffer, const int numSamples) override
bool endOfData() const override
Definition: adpcm_intern.h:138
Definition: adpcm_intern.h:265
int readBuffer(int16 *buffer, const int numSamples) override
bool endOfData() const override
Definition: adpcm_intern.h:273
Definition: adpcm_intern.h:119
static const int16 _imaTable[89]
Definition: adpcm_intern.h:130
Definition: adpcm_intern.h:202
int readBuffer(int16 *buffer, const int numSamples) override
bool endOfData() const override
Definition: adpcm_intern.h:233
Definition: adpcm_intern.h:174
int readBuffer(int16 *buffer, const int numSamples) override
Definition: adpcm_intern.h:84
int readBuffer(int16 *buffer, const int numSamples) override
bool endOfData() const override
Definition: adpcm_intern.h:89
Definition: audiostream.h:212
Definition: timestamp.h:83
Definition: adpcm_intern.h:101
bool endOfData() const override
Definition: adpcm_intern.h:106
int readBuffer(int16 *buffer, const int numSamples) override
Definition: array.h:52
size_type size() const
Definition: array.h:316
void clear()
Definition: array.h:321
bool empty() const
Definition: array.h:352
virtual bool eos() const =0
Definition: stream.h:745
virtual int64 pos() const =0
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: system.h:39
Definition: adpcm_intern.h:52
Definition: adpcm_intern.h:204