Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

adpcm.cc

Go to the documentation of this file.
00001 
00002 #include "swf.h"
00003 
00004 #ifdef RCSID
00005 static char *rcsid = "$Id: adpcm.cc,v 1.1.1.1 2002/01/25 22:14:58 kergoth Exp $";
00006 #endif
00007 
00008 // This file has been rearranged from the code posted
00009 // on news:forums.macromedia.com by Jonathan Gay.
00010 // Courtesy of Macromedia
00011 
00012 //
00013 // ADPCM tables
00014 //
00015 
00016 static const int indexTable2[2] = {
00017     -1, 2,
00018 };
00019 
00020 // Is this ok?
00021 static const int indexTable3[4] = {
00022     -1, -1, 2, 4,
00023 };
00024 
00025 static const int indexTable4[8] = {
00026     -1, -1, -1, -1, 2, 4, 6, 8,
00027 };
00028 
00029 static const int indexTable5[16] = {
00030  -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
00031 };
00032 
00033 static const int* indexTables[] = {
00034  indexTable2,
00035  indexTable3,
00036  indexTable4,
00037  indexTable5
00038 };
00039 
00040 static const int stepsizeTable[89] = {
00041     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
00042     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
00043     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
00044     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
00045     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
00046     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
00047     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
00048     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
00049     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
00050 };
00051 
00052 long
00053 Adpcm::GetBits(int n)
00054 {
00055         if ( bitPos < n ) FillBuffer();
00056 
00057         assert(bitPos >= n);
00058 
00059         long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
00060         bitPos -= n;
00061 
00062         return v;
00063 }
00064 
00065 long
00066 Adpcm::GetSBits(int n)
00067 {
00068         if ( bitPos < n ) FillBuffer();
00069 
00070         assert(bitPos >= n);
00071 
00072         long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
00073         bitPos -= n;
00074 
00075         return v;
00076 }
00077 
00078 //
00079 // The Decompressor
00080 //
00081 
00082 // Constructor
00083 Adpcm::Adpcm(unsigned char *buffer, long isStereo)
00084 {
00085         stereo = isStereo;
00086         src = buffer;
00087 
00088         nBits = 0; // flag that it is not inited
00089         nSamples = 0;
00090 
00091         bitPos = 0;
00092         bitBuf = 0;
00093 }
00094 
00095 void
00096 Adpcm::FillBuffer()
00097 {
00098         while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
00099                 bitBuf = (bitBuf<<8) | *src++;
00100                 bitPos += 8;
00101         }
00102 }
00103 
00104 void
00105 Adpcm::Decompress(short *dst, long n)
00106 {
00107         if ( nBits == 0 ) {
00108                 // Get the compression header
00109                 nBits = (int)GetBits(2)+2;
00110         }
00111 
00112         const int* indexTable = indexTables[nBits-2];
00113         int k0 = 1 << (nBits-2);
00114         int signmask = 1 << (nBits-1);
00115 
00116         if ( !stereo ) {
00117                 // Optimize for mono
00118                 long            vp = valpred[0]; // maybe these can get into registers...
00119                 int             ind = index[0];
00120                 long            ns = nSamples;
00121 
00122                 while ( n-- > 0 ) {
00123                         ns++;
00124 
00125                         if ( (ns & 0xFFF) == 1 ) {
00126                                 // Get a new block header
00127                                 *dst++ = (short)(vp = GetSBits(16));
00128 
00129                                 ind = (int)GetBits(6); // The first sample in a block does not have a delta
00130                         } else {
00131                                 // Process a delta value
00132                                 int delta = (int)GetBits(nBits);
00133 
00134                                 // Compute difference and new predicted value
00135                                 // Computes 'vpdiff = (delta+0.5)*step/4'
00136                                 int step = stepsizeTable[ind];
00137                                 long vpdiff = 0;
00138                                 int k = k0;
00139 
00140                                 do {
00141                                         if ( delta & k )
00142                                         vpdiff += step;
00143                                         step >>= 1;
00144                                         k >>= 1;
00145                                 } while ( k );
00146 
00147                                 vpdiff += step; // add 0.5
00148 
00149                                 if ( delta & signmask ) // the sign bit
00150                                         vp -= vpdiff;
00151                                 else
00152                                         vp += vpdiff;
00153 
00154                                 // Find new index value
00155                                 ind += indexTable[delta&(~signmask)];
00156 
00157                                 if ( ind < 0 )
00158                                         ind = 0;
00159                                 else if ( ind > 88 )
00160                                         ind = 88;
00161 
00162                                 // clamp output value
00163                                 if ( vp != (short)vp )
00164                                         vp = vp < 0 ? -32768 : 32767;
00165 
00166                                 /* Step 7 - Output value */
00167                                 *dst++ = (short)vp;
00168                         }
00169                 }
00170 
00171                 valpred[0] = vp;
00172                 index[0] = ind;
00173                 nSamples = ns;
00174 
00175         } else {
00176                 int sn = stereo ? 2 : 1;
00177 
00178                 // Stereo
00179                 while ( n-- > 0 ) {
00180 
00181                         nSamples++;
00182 
00183                         if ( (nSamples & 0xFFF) == 1 ) {
00184                                 // Get a new block header
00185                                 for ( int i = 0; i < sn; i++ ) {
00186 
00187                                         *dst++ = (short)(valpred[i] = GetSBits(16));
00188 
00189                                         // The first sample in a block does not have a delta
00190                                         index[i] = (int)GetBits(6);
00191                                 }
00192                         } else {
00193                                 // Process a delta value
00194                                 for ( int i = 0; i < sn; i++ ) {
00195                                         int delta = (int)GetBits(nBits);
00196 
00197                                         // Compute difference and new predicted value
00198                                         // Computes 'vpdiff = (delta+0.5)*step/4'
00199 
00200                                         int step = stepsizeTable[index[i]];
00201                                         long vpdiff = 0;
00202                                         int k = k0;
00203 
00204                                         do {
00205                                                 if ( delta & k ) vpdiff += step;
00206                                                 step >>= 1;
00207                                                 k >>= 1;
00208                                         } while ( k );
00209                                         vpdiff += step; // add 0.5
00210 
00211 
00212                                         if ( delta & signmask ) // the sign bit
00213                                                 valpred[i] -= vpdiff;
00214                                         else
00215                                                 valpred[i] += vpdiff;
00216 
00217                                         // Find new index value
00218                                         index[i] += indexTable[delta&(~signmask)];
00219 
00220                                         if ( index[i] < 0 )
00221                                                 index[i] = 0;
00222                                         else if ( index[i] > 88 )
00223                                                 index[i] = 88;
00224 
00225                                         // clamp output value
00226                                         if ( valpred[i] != (short)valpred[i] )
00227                                                 valpred[i] = valpred[i] < 0 ? -32768 : 32767;
00228 
00229                                         /* Step 7 - Output value */
00230                                         *dst++ = (short)valpred[i];
00231                                 }
00232                         }
00233                 }
00234         }
00235 }

Generated on Sat Nov 5 16:15:34 2005 for OPIE by  doxygen 1.4.2