1 /* ScummVM - Graphic Adventure Engine
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.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include "sound/shorten.h"
28 #ifdef SOUND_SHORTEN_H
30 // Based on etree's Shorten tool, version 3.6.1
31 // http://etree.org/shnutils/shorten/
33 // FIXME: This doesn't work yet correctly
35 #include "common/endian.h"
36 #include "common/util.h"
37 #include "common/stream.h"
39 #include "sound/audiostream.h"
40 #include "sound/mixer.h"
44 #define MASKTABSIZE 33
45 #define MAX_SUPPORTED_VERSION 3
46 #define DEFAULT_BLOCK_SIZE 256
49 kTypeAU1
= 0, // lossless ulaw
50 kTypeS8
= 1, // signed 8 bit
51 kTypeU8
= 2, // unsigned 8 bit
52 kTypeS16HL
= 3, // signed 16 bit shorts: high-low
53 kTypeU16HL
= 4, // unsigned 16 bit shorts: high-low
54 kTypeS16LH
= 5, // signed 16 bit shorts: low-high
55 kTypeU16LH
= 6, // unsigned 16 bit shorts: low-high
56 kTypeULaw
= 7, // lossy ulaw
57 kTypeAU2
= 8, // new ulaw with zero mapping
58 kTypeAU3
= 9, // lossless alaw
59 kTypeALaw
= 10, // lossy alaw
61 kTypeAIFF
= 12, // AIFF
63 kTypeGenericULaw
= 128,
64 kTypeGenericALaw
= 129
67 enum kShortenCommands
{
81 #define M_LN2 0.69314718055994530942
84 // ---------------------------------------------------------------------------
86 class ShortenGolombReader
{
88 ShortenGolombReader(Common::ReadStream
*stream
, int version
);
89 ~ShortenGolombReader() {}
90 uint32
getUint32(uint32 numBits
); // UINT_GET
91 int32
getURice(uint32 numBits
); // uvar_get
92 int32
getSRice(uint32 numBits
); // var_get
97 uint32 _masktab
[MASKTABSIZE
];
98 Common::ReadStream
*_stream
;
101 ShortenGolombReader::ShortenGolombReader(Common::ReadStream
*stream
, int version
) {
109 for (int i
= 1; i
< MASKTABSIZE
; i
++) {
116 int32
ShortenGolombReader::getURice(uint32 numBits
) {
120 _buf
= _stream
->readUint32BE();
124 for (result
= 0; !(_buf
& (1L << --_nbitget
)); result
++) {
126 _buf
= _stream
->readUint32BE();
131 while (numBits
!= 0) {
132 if (_nbitget
>= numBits
) {
133 result
= (result
<< numBits
) | ((_buf
>> (_nbitget
- numBits
)) & _masktab
[numBits
]);
137 result
= (result
<< _nbitget
) | (_buf
& _masktab
[_nbitget
]);
138 _buf
= _stream
->readUint32BE();
147 int32
ShortenGolombReader::getSRice(uint32 numBits
) {
148 uint32 uvar
= (uint32
) getURice(numBits
+ 1);
149 return (uvar
& 1) ? (int32
) ~(uvar
>> 1) : (int32
) (uvar
>> 1);
152 uint32
ShortenGolombReader::getUint32(uint32 numBits
) {
153 return (_version
== 0) ? (uint32
)getURice(numBits
) : (uint32
)getURice(getURice(2));
156 // ---------------------------------------------------------------------------
158 byte
*loadShortenFromStream(Common::ReadStream
&stream
, int &size
, int &rate
, byte
&flags
) {
159 int32
*buffer
[2], *offset
[2]; // up to 2 channels
160 byte
*unpackedBuffer
= 0;
161 byte
*pBuf
= unpackedBuffer
;
165 ShortenGolombReader
*gReader
;
166 uint32 i
, j
, version
, mean
, type
, channels
, blockSize
;
167 uint32 maxLPC
= 0, lpcqOffset
= 0;
168 int32 bitShift
= 0, wrap
= 0;
174 stream
.read(magic
, 4);
175 if (memcmp(magic
, "ajkg", 4) != 0) {
176 warning("loadShortenFromStream: No 'ajkg' header");
180 version
= stream
.readByte();
182 if (version
> MAX_SUPPORTED_VERSION
) {
183 warning("loadShortenFromStream: Can't decode version %d, maximum supported version is %d", version
, MAX_SUPPORTED_VERSION
);
187 mean
= (version
< 2) ? 0 : 4;
189 gReader
= new ShortenGolombReader(&stream
, version
);
192 type
= gReader
->getUint32(4);
198 flags
|= Audio::Mixer::FLAG_UNSIGNED
;
201 flags
|= Audio::Mixer::FLAG_LITTLE_ENDIAN
;
203 flags
|= Audio::Mixer::FLAG_16BITS
;
206 flags
|= Audio::Mixer::FLAG_LITTLE_ENDIAN
;
208 flags
|= Audio::Mixer::FLAG_16BITS
;
209 flags
|= Audio::Mixer::FLAG_UNSIGNED
;
212 // TODO: Perhaps implement this if we find WAV Shorten encoded files
213 warning("loadShortenFromStream: Type WAV is not supported");
217 // TODO: Perhaps implement this if we find AIFF Shorten encoded files
218 warning("loadShortenFromStream: Type AIFF is not supported");
227 case kTypeGenericULaw
:
228 case kTypeGenericALaw
:
230 warning("loadShortenFromStream: Type %d is not supported", type
);
236 channels
= gReader
->getUint32(0);
237 if (channels
!= 1 && channels
!= 2) {
238 warning("loadShortenFromStream: Only 1 or 2 channels are supported, stream contains %d channels", channels
);
245 blockSize
= gReader
->getUint32((int) (log((double) DEFAULT_BLOCK_SIZE
) / M_LN2
));
246 maxLPC
= gReader
->getUint32(2);
247 mean
= gReader
->getUint32(0);
248 uint32 skipBytes
= gReader
->getUint32(1);
252 unpackedBuffer
= (byte
*) realloc(unpackedBuffer
, size
);
253 pBuf
= unpackedBuffer
+ prevSize
;
254 for (i
= 0; i
< skipBytes
; i
++) {
255 *pBuf
++ = gReader
->getUint32(7) & 0xFF;
259 blockSize
= DEFAULT_BLOCK_SIZE
;
262 wrap
= MAX
<uint32
>(3, maxLPC
);
264 // Initialize buffers
265 for (i
= 0; i
< channels
; i
++) {
266 buffer
[i
] = (int32
*)malloc((blockSize
+ wrap
) * 4);
267 offset
[i
] = (int32
*)malloc((MAX
<uint32
>(1, mean
)) * 4);
268 memset(buffer
[i
], 0, (blockSize
+ wrap
) * 4);
269 memset(offset
[i
], 0, (MAX
<uint32
>(1, mean
)) * 4);
273 lpc
= (int32
*) malloc(maxLPC
* 4);
279 int32 offsetMean
= 0;
280 uint32 blocks
= MAX
<int>(1, mean
);
284 else if (type
== kTypeU16HL
|| type
== kTypeU16LH
)
287 for (uint32 channel
= 0; channel
< channels
; channel
++)
288 for (uint32 block
= 0; block
< blocks
; block
++)
289 offset
[channel
][block
] = offsetMean
;
292 uint32 curChannel
= 0, cmd
= 0;
294 // Parse Shorten commands
296 cmd
= gReader
->getURice(2);
309 int32 channelOffset
= 0, energy
= 0;
312 if (cmd
!= kCmdZero
) {
313 energy
= gReader
->getURice(3);
314 // hack for version 0
319 // Find mean offset (code duplicated below)
321 channelOffset
= offset
[curChannel
][0];
323 int32 sum
= (version
< 2) ? 0 : mean
/ 2;
324 for (i
= 0; i
< mean
; i
++)
325 sum
+= offset
[curChannel
][i
];
327 channelOffset
= sum
/ mean
;
329 if (version
>= 2 && bitShift
> 0)
330 channelOffset
= (channelOffset
>> (bitShift
- 1)) >> 1;
333 // FIXME: The original code in this bit tries to modify memory outside of the array (negative indices)
334 // in cases kCmdDiff1, kCmdDiff2 and kCmdDiff3
335 // I've removed those invalid writes, since they happen all the time (even when curChannel is 0)
338 for (i
= 0; i
< blockSize
; i
++)
339 buffer
[curChannel
][i
] = 0;
342 for (i
= 0; i
< blockSize
; i
++)
343 buffer
[curChannel
][i
] = gReader
->getSRice(energy
) + channelOffset
;
346 gReader
->getSRice(energy
); // i = 0 (to fix invalid table/memory access)
347 for (i
= 1; i
< blockSize
; i
++)
348 buffer
[curChannel
][i
] = gReader
->getSRice(energy
) + buffer
[curChannel
][i
- 1];
351 gReader
->getSRice(energy
); // i = 0 (to fix invalid table/memory access)
352 gReader
->getSRice(energy
); // i = 1 (to fix invalid table/memory access)
353 for (i
= 2; i
< blockSize
; i
++)
354 buffer
[curChannel
][i
] = gReader
->getSRice(energy
) + 2 * buffer
[curChannel
][i
- 1] - buffer
[curChannel
][i
- 2];
357 gReader
->getSRice(energy
); // i = 0 (to fix invalid table/memory access)
358 gReader
->getSRice(energy
); // i = 1 (to fix invalid table/memory access)
359 gReader
->getSRice(energy
); // i = 2 (to fix invalid table/memory access)
360 for (i
= 3; i
< blockSize
; i
++)
361 buffer
[curChannel
][i
] = gReader
->getSRice(energy
) + 3 * (buffer
[curChannel
][i
- 1] - buffer
[curChannel
][i
- 2]) + buffer
[curChannel
][i
- 3];
364 lpcNum
= gReader
->getURice(2);
366 // Safeguard: if maxLPC < lpcNum, realloc the lpc buffer
367 if (maxLPC
< lpcNum
) {
368 warning("Safeguard: maxLPC < lpcNum (should never happen)");
370 lpc
= (int32
*) realloc(lpc
, maxLPC
* 4);
373 for (i
= 0; i
< lpcNum
; i
++)
374 lpc
[i
] = gReader
->getSRice(5);
376 for (i
= 0; i
< lpcNum
; i
++)
377 buffer
[curChannel
][i
- lpcNum
] -= channelOffset
;
379 for (i
= 0; i
< blockSize
; i
++) {
380 int32 sum
= lpcqOffset
;
381 for (j
= 0; j
< lpcNum
; j
++) {
382 // FIXME: The original code did an invalid memory access here
383 // (if i and j are 0, the array index requested is -1)
384 // I've removed those invalid writes, since they happen all the time (even when curChannel is 0)
385 if (i
<= j
) // ignore invalid table/memory access
387 sum
+= lpc
[j
] * buffer
[curChannel
][i
- j
- 1];
389 buffer
[curChannel
][i
] = gReader
->getSRice(energy
) + (sum
>> 5);
392 if (channelOffset
> 0)
393 for (i
= 0; i
< blockSize
; i
++)
394 buffer
[curChannel
][i
] += channelOffset
;
399 // Store mean value, if appropriate (duplicated code from above)
401 int32 sum
= (version
< 2) ? 0 : blockSize
/ 2;
402 for (i
= 0; i
< blockSize
; i
++)
403 sum
+= buffer
[curChannel
][i
];
405 for (i
= 1; i
< mean
; i
++)
406 offset
[curChannel
][i
- 1] = offset
[curChannel
][i
];
408 offset
[curChannel
][mean
- 1] = sum
/ blockSize
;
410 if (version
>= 2 && bitShift
> 0)
411 offset
[curChannel
][mean
- 1] = offset
[curChannel
][mean
- 1] << bitShift
;
416 // FIXME: removed for now, as this corrupts the heap, because it
417 // accesses negative array indices
418 //for (int32 k = -wrap; k < 0; k++)
419 // buffer[curChannel][k] = buffer[curChannel][k + blockSize];
423 for (i
= 0; i
< blockSize
; i
++)
424 buffer
[curChannel
][i
] <<= bitShift
;
427 if (curChannel
== channels
- 1) {
428 int dataSize
= (flags
& Audio::Mixer::FLAG_16BITS
) ? 2 : 1;
429 int limit
= (flags
& Audio::Mixer::FLAG_16BITS
) ? 32767 : 127;
430 limit
= (flags
& Audio::Mixer::FLAG_UNSIGNED
) ? limit
* 2 + 1 : limit
;
433 size
+= (blockSize
* dataSize
);
434 unpackedBuffer
= (byte
*) realloc(unpackedBuffer
, size
);
435 pBuf
= unpackedBuffer
+ prevSize
;
437 if (flags
& Audio::Mixer::FLAG_16BITS
) {
438 for (i
= 0; i
< blockSize
; i
++) {
439 for (j
= 0; j
< channels
; j
++) {
440 int16 val
= (int16
)(MIN
<int32
>(buffer
[j
][i
], limit
) & 0xFFFF);
441 // values are written in LE
442 *pBuf
++ = (byte
) (val
& 0xFF);
443 *pBuf
++ = (byte
) ((val
>> 8) & 0xFF);
447 for (i
= 0; i
< blockSize
; i
++)
448 for (j
= 0; j
< channels
; j
++)
449 *pBuf
++ = (byte
)(MIN
<int32
>(buffer
[j
][i
], limit
) & 0xFF);
452 curChannel
= (curChannel
+ 1) % channels
;
457 blockSize
= gReader
->getUint32((uint32
)log((double) blockSize
/ M_LN2
));
460 bitShift
= gReader
->getURice(2);
465 uint32 vLen
= (uint32
)gReader
->getURice(5);
468 unpackedBuffer
= (byte
*) realloc(unpackedBuffer
, size
);
469 pBuf
= unpackedBuffer
+ prevSize
;
472 *pBuf
++ = (byte
)(gReader
->getURice(8) & 0xFF);
478 warning("loadShortenFromStream: Unknown command: %d", cmd
);
481 for (i
= 0; i
< channels
; i
++) {
490 free(unpackedBuffer
);
498 // Rate is always 44100Hz
502 for (i
= 0; i
< channels
; i
++) {
511 free(unpackedBuffer
);
514 return unpackedBuffer
;
517 AudioStream
*makeShortenStream(Common::SeekableReadStream
&stream
) {
520 data
= loadShortenFromStream(stream
, size
, rate
, flags
);
525 // Since we allocated our own buffer for the data, we must set the autofree flag.
526 flags
|= Audio::Mixer::FLAG_AUTOFREE
;
528 return makeLinearInputStream(data
, size
, rate
, flags
, 0, 0);
531 } // End of namespace Audio
533 #endif // defined(SOUND_SHORTEN_H)