Listing 2: Partial listing of decoder.cpp
class TDecoder { private: TDecoder(); // no default constructor wanted public: TDecoder(vector<int> &tiDestination); // init the TDecoder and pass a vector whereto decoded data shall // be written; public: void Decode(WORD wCode); // decode the word wCode and push_back the result into tiDestination private: int DeltaDecode(int iDelta); int miXsample; // the untouched fraction of the last 16-bit code passed to Decode() int miXbitsTaken; // denotes what number of bits are valid in miXsample int miBitWidthOfCode; // holds the bit width of the code int miAbsValueCoded; // this holds the number of WORDs left that code an absolute value int mpiLastSamplesDiv3[3]; // usually holds the last 3 decoded samples int miSamples2MSBidentical; // this counter is used for the reduction of the bit width (in // the adaption) vector<int> *mptiDestination; // pointer to the result vector static const int mpiABSCODE[17]; static const int mpiOVFLCODE[16]; static const int mpiALIGNCODE[16]; static const int mpiSIGNEXTENSION[16]; }; const int TDecoder::mpiABSCODE[17] = { ... }; // as in listing 1 const int TDecoder::mpiOVFLCODE[16] = { ... }; // as in listing 1 const int TDecoder::mpiALIGNCODE[16] = { ... }; // as in listing 1 const int TDecoder::mpiSIGNEXTENSION[16] = { // the value at index i denotes a bitmask for 32-bits sign extension // for an i-bits value 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8, 0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80, 0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800, 0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000, 0xFFFF0000 }; TDecoder::TDecoder(vector<int> &tiDestination): miXsample(0), miXbitsTaken(0), miBitWidthOfCode(6), miAbsValueCoded(0), miSamples2MSBidentical(0), mptiDestination(&tiDestination) { assert( sizeof(int) >= 4 ); // TDecoder does not run on 16-bit // platforms for(int i = 0; i < 3; i++) mpiLastSamplesDiv3[i] = 0; } int TDecoder::DeltaDecode(int iDelta) { int iPrediction = 4 * mpiLastSamplesDiv3[2] + mpiLastSamplesDiv3[1] - 2 * mpiLastSamplesDiv3[0]; int iDecodedSample = iPrediction + iDelta; mpiLastSamplesDiv3[0] = mpiLastSamplesDiv3[1]; mpiLastSamplesDiv3[1] = mpiLastSamplesDiv3[2]; mpiLastSamplesDiv3[2] = iDecodedSample / 3; return iDecodedSample; } void TDecoder::Decode(WORD wCode) { unsigned uiCode = wCode; // use full 32-bit register width if( miAbsValueCoded == 1 ) { miXsample = uiCode; if (uiCode & 0x8000) miXsample -=0x10000; // unsigned -> int16 // conversion (*mptiDestination).push_back(miXsample); mpiLastSamplesDiv3[0] = miXsample/3; // update for // delta encoding mpiLastSamplesDiv3[1] = miXsample/3; mpiLastSamplesDiv3[2] = miXsample/3; miAbsValueCoded--; // switch back to delta // encoding miXsample = 0x0000; // reset buffered sub-word } else { // a delta encoded value, not necessarily aligned with a word // boundary has been received uiCode <<= miXbitsTaken; // shift it left to and combine it with miXsample |= uiCode; // a buffered rest of preceding iCode:s miXbitsTaken += 16; // 16 new bits to decode were passed while( miXbitsTaken >= miBitWidthOfCode ) { // cut out a complete code; reduce contents of the buffer by // the code cut out; reduce number of valid bits accordingly int iSubword = miXsample & mpiABSCODE[miBitWidthOfCode]; int iSignBitMask = 1 << (miBitWidthOfCode - 1); miXsample >>= miBitWidthOfCode; miXbitsTaken -= miBitWidthOfCode; int iMaxBitMask = 3 << (miBitWidthOfCode - 2); if( iSignBitMask & iSubword) { // a negative number was coded; sign extension is needed // as well for the comparison to mpiALIGNCODE[] as for // delta decoding iSubword |= mpiSIGNEXTENSION[miBitWidthOfCode - 1]; } if( iSubword == mpiOVFLCODE[miBitWidthOfCode - 1] ) { miBitWidthOfCode++; // increase bit width of code miSamples2MSBidentical = 0; } else if( iSubword == mpiABSCODE[miBitWidthOfCode - 1] ) { miAbsValueCoded = 1; miXbitsTaken = 0; miXsample = 0; } else if( iSubword == mpiALIGNCODE[miBitWidthOfCode - 1] ) { miXbitsTaken = 0; miXsample = 0; } else { if( (iSubword & iMaxBitMask) == 0x0000 || (iSubword & iMaxBitMask) == iMaxBitMask) { miSamples2MSBidentical++; if ((miSamples2MSBidentical == BIT_REDUCTION_LENGTH) && (miBitWidthOfCode > MIN_BIT_WIDTH)) { miBitWidthOfCode--; miSamples2MSBidentical = 0; } } else { miSamples2MSBidentical = 0; } int iNewSample = DeltaDecode( iSubword ); (*mptiDestination).push_back( iNewSample ); } } // while } } // TDecoder::Decode()