From 15318cad33835e4e2dc620d033e43cd930676cdd Mon Sep 17 00:00:00 2001 From: kergoth Date: Fri, 25 Jan 2002 22:14:26 +0000 Subject: Initial revision --- (limited to 'core/multimedia/opieplayer/libflash/adpcm.cc') diff --git a/core/multimedia/opieplayer/libflash/adpcm.cc b/core/multimedia/opieplayer/libflash/adpcm.cc new file mode 100644 index 0000000..a4bc435 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/adpcm.cc @@ -0,0 +1,235 @@ + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +// This file has been rearranged from the code posted +// on news:forums.macromedia.com by Jonathan Gay. +// Courtesy of Macromedia + +// +// ADPCM tables +// + +static const int indexTable2[2] = { + -1, 2, +}; + +// Is this ok? +static const int indexTable3[4] = { + -1, -1, 2, 4, +}; + +static const int indexTable4[8] = { + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static const int indexTable5[16] = { + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, +}; + +static const int* indexTables[] = { + indexTable2, + indexTable3, + indexTable4, + indexTable5 +}; + +static const int stepsizeTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +long +Adpcm::GetBits(int n) +{ + if ( bitPos < n ) FillBuffer(); + + assert(bitPos >= n); + + long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n); + bitPos -= n; + + return v; +} + +long +Adpcm::GetSBits(int n) +{ + if ( bitPos < n ) FillBuffer(); + + assert(bitPos >= n); + + long v = ((long)bitBuf << (32-bitPos)) >> (32-n); + bitPos -= n; + + return v; +} + +// +// The Decompressor +// + +// Constructor +Adpcm::Adpcm(unsigned char *buffer, long isStereo) +{ + stereo = isStereo; + src = buffer; + + nBits = 0; // flag that it is not inited + nSamples = 0; + + bitPos = 0; + bitBuf = 0; +} + +void +Adpcm::FillBuffer() +{ + while ( bitPos <= 24 /*&& srcSize > 0*/ ) { + bitBuf = (bitBuf<<8) | *src++; + bitPos += 8; + } +} + +void +Adpcm::Decompress(short *dst, long n) +{ + if ( nBits == 0 ) { + // Get the compression header + nBits = (int)GetBits(2)+2; + } + + const int* indexTable = indexTables[nBits-2]; + int k0 = 1 << (nBits-2); + int signmask = 1 << (nBits-1); + + if ( !stereo ) { + // Optimize for mono + long vp = valpred[0]; // maybe these can get into registers... + int ind = index[0]; + long ns = nSamples; + + while ( n-- > 0 ) { + ns++; + + if ( (ns & 0xFFF) == 1 ) { + // Get a new block header + *dst++ = (short)(vp = GetSBits(16)); + + ind = (int)GetBits(6); // The first sample in a block does not have a delta + } else { + // Process a delta value + int delta = (int)GetBits(nBits); + + // Compute difference and new predicted value + // Computes 'vpdiff = (delta+0.5)*step/4' + int step = stepsizeTable[ind]; + long vpdiff = 0; + int k = k0; + + do { + if ( delta & k ) + vpdiff += step; + step >>= 1; + k >>= 1; + } while ( k ); + + vpdiff += step; // add 0.5 + + if ( delta & signmask ) // the sign bit + vp -= vpdiff; + else + vp += vpdiff; + + // Find new index value + ind += indexTable[delta&(~signmask)]; + + if ( ind < 0 ) + ind = 0; + else if ( ind > 88 ) + ind = 88; + + // clamp output value + if ( vp != (short)vp ) + vp = vp < 0 ? -32768 : 32767; + + /* Step 7 - Output value */ + *dst++ = (short)vp; + } + } + + valpred[0] = vp; + index[0] = ind; + nSamples = ns; + + } else { + int sn = stereo ? 2 : 1; + + // Stereo + while ( n-- > 0 ) { + + nSamples++; + + if ( (nSamples & 0xFFF) == 1 ) { + // Get a new block header + for ( int i = 0; i < sn; i++ ) { + + *dst++ = (short)(valpred[i] = GetSBits(16)); + + // The first sample in a block does not have a delta + index[i] = (int)GetBits(6); + } + } else { + // Process a delta value + for ( int i = 0; i < sn; i++ ) { + int delta = (int)GetBits(nBits); + + // Compute difference and new predicted value + // Computes 'vpdiff = (delta+0.5)*step/4' + + int step = stepsizeTable[index[i]]; + long vpdiff = 0; + int k = k0; + + do { + if ( delta & k ) vpdiff += step; + step >>= 1; + k >>= 1; + } while ( k ); + vpdiff += step; // add 0.5 + + + if ( delta & signmask ) // the sign bit + valpred[i] -= vpdiff; + else + valpred[i] += vpdiff; + + // Find new index value + index[i] += indexTable[delta&(~signmask)]; + + if ( index[i] < 0 ) + index[i] = 0; + else if ( index[i] > 88 ) + index[i] = 88; + + // clamp output value + if ( valpred[i] != (short)valpred[i] ) + valpred[i] = valpred[i] < 0 ? -32768 : 32767; + + /* Step 7 - Output value */ + *dst++ = (short)valpred[i]; + } + } + } + } +} -- cgit v0.9.0.2