IMA_ADPCM.cpp

Go to the documentation of this file.
00001 /*
00002 This program is distributed under the terms of the 'MIT license'. The text
00003 of this licence follows...
00004 
00005 Copyright (c) 2005 J.D.Medhurst (a.k.a. Tixy)
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a copy
00008 of this software and associated documentation files (the "Software"), to deal
00009 in the Software without restriction, including without limitation the rights
00010 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00011 copies of the Software, and to permit persons to whom the Software is
00012 furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00020 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00022 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00023 THE SOFTWARE.
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 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 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 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 unsigned IMA_ADPCM::Encode(uint8_t* dst, int dstOffset, const int16_t* src, size_t srcSize)
00168     {
00169     // use given bit offset
00170     dst += dstOffset>>3;
00171     unsigned bitOffset = dstOffset&4;
00172 
00173     // make sure srcSize represents a whole number of samples
00174     srcSize &= ~1;
00175 
00176     // calculate end of input buffer
00177     const int16_t* end = (const int16_t*)((const uint8_t*)src+srcSize);
00178 
00179     while(src<end)
00180         {
00181         // encode a pcm value from input buffer
00182         unsigned adpcm = Encode(*src++);
00183 
00184         // pick which nibble to write adpcm value to...
00185         if(!bitOffset)
00186             *dst = adpcm;       // write adpcm value to low nibble
00187         else
00188             {
00189             unsigned b = *dst;      // get byte from ouput
00190             b &= 0x0f;          // clear bits of high nibble
00191             b |= adpcm<<4;      // or adpcm value into the high nibble
00192             *dst++ = (uint8_t)b;    // write value back to output and move on to next byte
00193             }
00194 
00195         // toggle which nibble in byte to write to next
00196         bitOffset ^= 4;
00197         }
00198 
00199     // return number bits written to dst
00200     return srcSize*2;
00201     }
00202 
00203 
00204 unsigned IMA_ADPCM::Decode(int16_t* dst, const uint8_t* src, int srcOffset, unsigned srcSize)
00205     {
00206     // use given bit offset
00207     src += srcOffset>>3;
00208 
00209     // calculate pointers to iterate output buffer
00210     int16_t* out = dst;
00211     int16_t* end = out+(srcSize>>2);
00212 
00213     while(out<end)
00214         {
00215         // get byte from src
00216         unsigned adpcm = *src;
00217 
00218         // pick which nibble holds a adpcm value...
00219         if(srcOffset&4)
00220             {
00221             adpcm >>= 4;  // use high nibble of byte
00222             ++src;        // move on a byte for next sample
00223             }
00224 
00225         *out++ = Decode(adpcm);  // decode value and store it
00226 
00227         // toggle which nibble in byte to write to next
00228         srcOffset ^= 4;
00229         }
00230 
00231     // return number of bytes written to dst
00232     return (unsigned)out-(unsigned)dst;
00233     }

Generated by  doxygen 1.6.1