Listing 1: ADPCM Encoder /* Table of index changes */ const char IndexTable[16] = {-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8}; /* Quantizer step size lookup table */ const long 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}; signed int diff; // Diff. between sample and predicted sample int step; // Quantizer step size signed int predsample,diffq; // ADPCM predictor output, Predicted diff. char index; // Index into step size table char ADPCMEncoder( signed int sample ) { char code; // ADPCM output value predsample = state.prevsample; // Restore previous values of predicted index = state.previndex; // sample and quantizer step size index step = StepSizeTable[index]; diff = sample - predsample; // Compute diff. between actual sample if(diff >= 0) // and the predicted sample code = 0; else { code = 8; diff = -diff; } diffq = step >> 3; // Quantize the diff. into 4-bit ADPCM code if( diff >= step ) // using the quantizer step size { code |= 4; // Inverse quantize the ADPCM code into a diff -= step; // predicted diff. using the quantizer step diffq += step; // size } step >>= 1; if( diff >= step ) { code |= 2; diff -= step; diffq += step; } step >>= 1; if( diff >= step ) { code |= 1; diffq += step; } if( code & 8 ) // Compute new predicted sample by adding predsample -= diffq; // the old predicted sample to new diff. else predsample += diffq; if( predsample > 32767 ) // Check if overflow of the new pred. sample predsample = 32767; else if( predsample < -32768 ) predsample = -32768; index += IndexTable[code]; // Find new quantizer stepsize if( index < 0 ) // Check if overflow of new quantizer step index = 0; if( index > 88 ) index = 88; state.prevsample = predsample; // Save values for next iteration state.previndex = index; return ( code & 0x0f ); // Return the ADPCM code }