00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00032 #include "common.h"
00033 #include "IMA_ADPCM.h"
00034
00035
00036 static const uint16_t IMA_ADPCMStepTable[89] =
00037 {
00038 7, 8, 9, 10, 11, 12, 13, 14,
00039 16, 17, 19, 21, 23, 25, 28, 31,
00040 34, 37, 41, 45, 50, 55, 60, 66,
00041 73, 80, 88, 97, 107, 118, 130, 143,
00042 157, 173, 190, 209, 230, 253, 279, 307,
00043 337, 371, 408, 449, 494, 544, 598, 658,
00044 724, 796, 876, 963, 1060, 1166, 1282, 1411,
00045 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
00046 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
00047 7132, 7845, 8630, 9493,10442,11487,12635,13899,
00048 15289,16818,18500,20350,22385,24623,27086,29794,
00049 32767
00050 };
00051
00052
00053 static const int IMA_ADPCMIndexTable[8] =
00054 {
00055 -1, -1, -1, -1, 2, 4, 6, 8,
00056 };
00057
00058
00059 EXPORT void IMA_ADPCM::EncodeInit(int16_t sample1,int16_t sample2)
00060 {
00061 PredictedValue = sample1;
00062 int delta = sample2-sample1;
00063 if(delta<0)
00064 delta = - delta;
00065 if(delta>32767)
00066 delta = 32767;
00067 int stepIndex = 0;
00068 while(IMA_ADPCMStepTable[stepIndex]<(unsigned)delta)
00069 stepIndex++;
00070 StepIndex = stepIndex;
00071 }
00072
00073
00074 EXPORT unsigned IMA_ADPCM::Encode(int16_t pcm16)
00075 {
00076 int predicedValue = PredictedValue;
00077 int stepIndex = StepIndex;
00078
00079 int delta = pcm16-predicedValue;
00080 unsigned value;
00081 if(delta>=0)
00082 value = 0;
00083 else
00084 {
00085 value = 8;
00086 delta = -delta;
00087 }
00088
00089 int step = IMA_ADPCMStepTable[stepIndex];
00090 int diff = step>>3;
00091 if(delta>step)
00092 {
00093 value |= 4;
00094 delta -= step;
00095 diff += step;
00096 }
00097 step >>= 1;
00098 if(delta>step)
00099 {
00100 value |= 2;
00101 delta -= step;
00102 diff += step;
00103 }
00104 step >>= 1;
00105 if(delta>step)
00106 {
00107 value |= 1;
00108 diff += step;
00109 }
00110
00111 if(value&8)
00112 predicedValue -= diff;
00113 else
00114 predicedValue += diff;
00115 if(predicedValue<-0x8000)
00116 predicedValue = -0x8000;
00117 else if(predicedValue>0x7fff)
00118 predicedValue = 0x7fff;
00119 PredictedValue = predicedValue;
00120
00121 stepIndex += IMA_ADPCMIndexTable[value&7];
00122 if(stepIndex<0)
00123 stepIndex = 0;
00124 else if(stepIndex>88)
00125 stepIndex = 88;
00126 StepIndex = stepIndex;
00127
00128 return value;
00129 }
00130
00131
00132 EXPORT int IMA_ADPCM::Decode(unsigned adpcm)
00133 {
00134 int stepIndex = StepIndex;
00135 int step = IMA_ADPCMStepTable[stepIndex];
00136
00137 stepIndex += IMA_ADPCMIndexTable[adpcm&7];
00138 if(stepIndex<0)
00139 stepIndex = 0;
00140 else if(stepIndex>88)
00141 stepIndex = 88;
00142 StepIndex = stepIndex;
00143
00144 int diff = step>>3;
00145 if(adpcm&4)
00146 diff += step;
00147 if(adpcm&2)
00148 diff += step>>1;
00149 if(adpcm&1)
00150 diff += step>>2;
00151
00152 int predicedValue = PredictedValue;
00153 if(adpcm&8)
00154 predicedValue -= diff;
00155 else
00156 predicedValue += diff;
00157 if(predicedValue<-0x8000)
00158 predicedValue = -0x8000;
00159 else if(predicedValue>0x7fff)
00160 predicedValue = 0x7fff;
00161 PredictedValue = predicedValue;
00162
00163 return predicedValue;
00164 }
00165
00166
00167 EXPORT unsigned IMA_ADPCM::Encode(uint8_t* dst, int dstOffset, const int16_t* src, size_t srcSize)
00168 {
00169
00170 dst += dstOffset>>3;
00171 unsigned bitOffset = dstOffset&4;
00172
00173
00174 srcSize &= ~1;
00175
00176
00177 const int16_t* end = (const int16_t*)((const uint8_t*)src+srcSize);
00178
00179 while(src<end)
00180 {
00181
00182 unsigned adpcm = Encode(*src++);
00183
00184
00185 if(!bitOffset)
00186 *dst = adpcm;
00187 else
00188 {
00189 unsigned b = *dst;
00190 b &= 0x0f;
00191 b |= adpcm<<4;
00192 *dst++ = (uint8_t)b;
00193 }
00194
00195
00196 bitOffset ^= 4;
00197 }
00198
00199
00200 return srcSize*2;
00201 }
00202
00203
00204 EXPORT unsigned IMA_ADPCM::Decode(int16_t* dst, const uint8_t* src, int srcOffset, unsigned srcSize)
00205 {
00206
00207 src += srcOffset>>3;
00208
00209
00210 int16_t* out = dst;
00211 int16_t* end = out+(srcSize>>2);
00212
00213 while(out<end)
00214 {
00215
00216 unsigned adpcm = *src;
00217
00218
00219 if(srcOffset&4)
00220 {
00221 adpcm >>= 4;
00222 ++src;
00223 }
00224
00225 *out++ = Decode(adpcm);
00226
00227
00228 srcOffset ^= 4;
00229 }
00230
00231
00232 return (unsigned)out-(unsigned)dst;
00233 }