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
00009
00010
00011
00012
00013
00014
00015
00016 static const int indexTable2[2] = {
00017 -1, 2,
00018 };
00019
00020
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
00080
00081
00082
00083 Adpcm::Adpcm(unsigned char *buffer, long isStereo)
00084 {
00085 stereo = isStereo;
00086 src = buffer;
00087
00088 nBits = 0;
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
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
00118 long vp = valpred[0];
00119 int ind = index[0];
00120 long ns = nSamples;
00121
00122 while ( n-- > 0 ) {
00123 ns++;
00124
00125 if ( (ns & 0xFFF) == 1 ) {
00126
00127 *dst++ = (short)(vp = GetSBits(16));
00128
00129 ind = (int)GetBits(6);
00130 } else {
00131
00132 int delta = (int)GetBits(nBits);
00133
00134
00135
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;
00148
00149 if ( delta & signmask )
00150 vp -= vpdiff;
00151 else
00152 vp += vpdiff;
00153
00154
00155 ind += indexTable[delta&(~signmask)];
00156
00157 if ( ind < 0 )
00158 ind = 0;
00159 else if ( ind > 88 )
00160 ind = 88;
00161
00162
00163 if ( vp != (short)vp )
00164 vp = vp < 0 ? -32768 : 32767;
00165
00166
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
00179 while ( n-- > 0 ) {
00180
00181 nSamples++;
00182
00183 if ( (nSamples & 0xFFF) == 1 ) {
00184
00185 for ( int i = 0; i < sn; i++ ) {
00186
00187 *dst++ = (short)(valpred[i] = GetSBits(16));
00188
00189
00190 index[i] = (int)GetBits(6);
00191 }
00192 } else {
00193
00194 for ( int i = 0; i < sn; i++ ) {
00195 int delta = (int)GetBits(nBits);
00196
00197
00198
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;
00210
00211
00212 if ( delta & signmask )
00213 valpred[i] -= vpdiff;
00214 else
00215 valpred[i] += vpdiff;
00216
00217
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
00226 if ( valpred[i] != (short)valpred[i] )
00227 valpred[i] = valpred[i] < 0 ? -32768 : 32767;
00228
00229
00230 *dst++ = (short)valpred[i];
00231 }
00232 }
00233 }
00234 }
00235 }