G726.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) 2004 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 "G726.h"
00034 #include "G711.h"
00035 
00056 #define CHECK_SM(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
00057 
00063 #define CHECK_UM(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
00064 
00070 #define CHECK_TC(x,bits) ASSERT_DEBUG(((x)>>(bits-1))==((x)<0?-1:0))
00071 
00077 #define CHECK_FL(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
00078 
00084 #define CHECK_UNSIGNED(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
00085  // End of group
00087 
00088 
00092 static void EXPAND(unsigned S,unsigned LAW,int& SL)
00093     {
00094     CHECK_UNSIGNED(S,8);
00095     CHECK_UNSIGNED(LAW,1);
00096     int linear;
00097     if(LAW)
00098         linear = G711::ALawDecode(S);
00099     else
00100         linear = G711::ULawDecode(S);
00101     SL = linear>>2;
00102     CHECK_TC(SL,14);
00103     }
00104 
00105 
00109 inline static void SUBTA(int SL,int SE,int& D)
00110     {
00111     CHECK_TC(SL,14);
00112     CHECK_TC(SE,15);
00113     D = SL-SE;
00114     CHECK_TC(D,16);
00115     }
00116 
00117 
00121 static void LOG(int D,unsigned& DL,int& DS)
00122     {
00123     CHECK_TC(D,16);
00124 
00125     DS = D>>15;
00126 
00127     unsigned DQM = (D<0) ? -D : D;
00128     DQM &= 0x7fff;
00129 
00130     unsigned EXP = 0;
00131     unsigned x = DQM;
00132     if(x>=(1<<8))
00133         {
00134         EXP |= 8;
00135         x >>= 8;
00136         }
00137     if(x>=(1<<4))
00138         {
00139         EXP |= 4;
00140         x >>= 4;
00141         }
00142     if(x>=(1<<2))
00143         {
00144         EXP |= 2;
00145         x >>= 2;
00146         }
00147     EXP |= x>>1;
00148 
00149     unsigned MANT = ((DQM<<7)>>EXP)&0x7f;
00150     DL = (EXP<<7) + MANT;
00151 
00152     CHECK_UM(DL,11);
00153     CHECK_TC(DS,1);
00154     }
00155 
00156 
00160 static void QUAN(unsigned RATE,int DLN,int DS,unsigned& I)
00161     {
00162     CHECK_TC(DLN,12);
00163     CHECK_TC(DS,1);
00164 
00165     int x;
00166 
00167     if(RATE==2)
00168         x = (DLN>=261);
00169     else
00170         {
00171         static const int16_t quan3[4] = {8,218,331,0x7fff};
00172         static const int16_t quan4[8] = {3972-0x1000,80,178,246,300,349,400,0x7fff};
00173         static const int16_t quan5[16] = {3974-0x1000,4080-0x1000,68,139,198,250,298,339,378,413,445,475,502,528,553,0x7fff};
00174         static const int16_t* const quan[3] = {quan3,quan4,quan5};
00175 
00176         const int16_t* levels = quan[RATE-3];
00177         const int16_t* levels0 = levels;
00178 
00179         while(DLN>=*levels++) {}
00180 
00181         x = levels-levels0-1;
00182         if(!x)
00183             x = ~DS;
00184         }
00185     int mask = (1<<RATE)-1;
00186     I = (x^DS)&mask;
00187 
00188     CHECK_UNSIGNED(I,RATE);
00189     }
00190 
00191 
00195 inline static void SUBTB(unsigned DL,unsigned Y,int& DLN)
00196     {
00197     CHECK_UM(DL,11);
00198     CHECK_UM(Y,13);
00199     DLN = DL-(Y>>2);
00200     CHECK_TC(DLN,12);
00201     }
00202 
00203 
00207 inline static void ADDA(int DQLN,unsigned Y,int& DQL)
00208     {
00209     CHECK_TC(DQLN,12);
00210     CHECK_UM(Y,13);
00211     DQL = DQLN+(Y>>2);
00212     CHECK_TC(DQL,12);
00213     }
00214 
00215 
00219 inline static void ANTILOG(int DQL,int DQS,unsigned& DQ)
00220     {
00221     CHECK_TC(DQL,12);
00222     CHECK_TC(DQS,1);
00223     unsigned DEX = (DQL >> 7) & 15;
00224     unsigned DMN = DQL & 127;
00225     unsigned DQT = (1 << 7) + DMN;
00226 
00227     unsigned DQMAG;
00228     if(DQL>=0)
00229         DQMAG = (DQT << 7) >> (14 - DEX);
00230     else
00231         DQMAG = 0;
00232 
00233     DQ = DQS ? DQMAG+(1<<15) : DQMAG;
00234 
00235     CHECK_SM(DQ,16);
00236     }
00237 
00238 
00242 inline static void RECONST(unsigned RATE,unsigned I,int& DQLN,int& DQS)
00243     {
00244     CHECK_UNSIGNED(I,RATE);
00245 
00246     // Tables 11-14
00247     static const int16_t reconst2[2] = {116,365};
00248     static const int16_t reconst3[4] = {2048-4096,135,273,373};
00249     static const int16_t reconst4[8] = {2048-4096,4,135,213,273,323,373,425};
00250     static const int16_t reconst5[16] = {2048-4096,4030-4096,28,104,169,224,274,318,358,395,429,459,488,514,539,566};
00251     static const int16_t* const reconst[4] = {reconst2,reconst3,reconst4,reconst5};
00252 
00253     int x = I;
00254     int m = 1<<(RATE-1);
00255     if(x&m)
00256         {
00257         DQS = -1;
00258         x = ~x;
00259         }
00260     else
00261         DQS = 0;
00262     DQLN = reconst[RATE-2][x&(m-1)];
00263 
00264     CHECK_TC(DQLN,12);
00265     CHECK_TC(DQS,1);
00266     }
00267 
00268 
00272 inline static void FILTD(int WI,unsigned Y,unsigned& YUT)
00273     {
00274     CHECK_TC(WI,12);
00275     CHECK_UM(Y,13);
00276     int DIF = (WI<<5)-Y;
00277     int DIFSX = DIF>>5;
00278     YUT = (Y+DIFSX); // & 8191
00279     CHECK_UM(YUT,13);
00280     }
00281 
00282 
00286 inline static void FILTE(unsigned YUP,unsigned YL,unsigned& YLP)
00287     {
00288     CHECK_UM(YUP,13);
00289     CHECK_UM(YL,19);
00290     int DIF = (YUP<<6)-YL;
00291     int DIFSX = DIF>>6;
00292     YLP = (YL+DIFSX); // & 524287
00293     CHECK_UM(YLP,19);
00294     }
00295 
00296 
00300 inline static void FUNCTW(unsigned RATE,unsigned I,int& WI)
00301     {
00302     CHECK_UNSIGNED(I,RATE);
00303 
00304     static const int16_t functw2[2] = {4074-4096,439};
00305     static const int16_t functw3[4] = {4092-4096,30,137,582};
00306     static const int16_t functw4[8] = {4084-4096,18,41,64,112,198,355,1122};
00307     static const int16_t functw5[16] = {14,14,24,39,40,41,58,100,141,179,219,280,358,440,529,696};
00308     static const int16_t* const functw[4] = {functw2,functw3,functw4,functw5};
00309 
00310     unsigned signMask = 1<<(RATE-1);
00311     unsigned n = (I&signMask) ? (2*signMask-1)-I : I;
00312     WI = functw[RATE-2][n];
00313 
00314     CHECK_TC(WI,12);
00315     }
00316 
00317 
00321 inline static void LIMB(unsigned YUT,unsigned& YUP)
00322     {
00323     CHECK_UM(YUT,13);
00324     unsigned GEUL = (YUT+11264)&(1<<13);
00325     unsigned GELL = (YUT+15840)&(1<<13);
00326     if(GELL)
00327         YUP = 544;
00328     else if (!GEUL)
00329         YUP = 5120;
00330     else
00331         YUP = YUT;
00332     CHECK_UM(YUP,13);
00333     }
00334 
00335 
00339 inline static void MIX(unsigned AL,unsigned YU,unsigned YL,unsigned& Y)
00340     {
00341     CHECK_UM(AL,7);
00342     CHECK_UM(YU,13);
00343     CHECK_UM(YL,19);
00344     int DIF = YU-(YL>>6);
00345     int PROD = DIF*AL;
00346     if(DIF<0) PROD += (1<<6)-1; // Force round towards zero for following shift
00347     PROD >>= 6;
00348     Y = ((YL>>6)+PROD); // & 8191;
00349     CHECK_UM(Y,13);
00350     }
00351 
00352 
00356 inline static void FILTA(unsigned FI,unsigned DMS,unsigned& DMSP)
00357     {
00358     CHECK_UM(FI,3);
00359     CHECK_UM(DMS,12);
00360     int DIF = (FI<<9)-DMS;
00361     int DIFSX = (DIF>>5);
00362     DMSP = (DIFSX+DMS); // & 4095;
00363     CHECK_UM(DMSP,12);
00364     }
00365 
00366 
00370 inline static void FILTB(unsigned FI,unsigned DML,unsigned& DMLP)
00371     {
00372     CHECK_UM(FI,3);
00373     CHECK_UM(DML,14);
00374     int DIF = (FI<<11)-DML;
00375     int DIFSX = (DIF>>7);
00376     DMLP = (DIFSX+DML); // & 16383;
00377     CHECK_UM(DMLP,14);
00378     }
00379 
00380 
00384 inline static void FILTC(unsigned AX,unsigned AP,unsigned& APP)
00385     {
00386     CHECK_UM(AX,1);
00387     CHECK_UM(AP,10);
00388     int DIF = (AX<<9)-AP;
00389     int DIFSX = (DIF>>4);
00390     APP = (DIFSX+AP); // & 1023;
00391     CHECK_UM(APP,10);
00392     }
00393 
00394 
00398 inline static void FUNCTF(unsigned RATE,unsigned I,unsigned& FI)
00399     {
00400     CHECK_UNSIGNED(I,RATE);
00401 
00402     static const int16_t functf2[2] = {0,7};
00403     static const int16_t functf3[4] = {0,1,2,7};
00404     static const int16_t functf4[8] = {0,0,0,1,1,1,3,7};
00405     static const int16_t functf5[16] = {0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6};
00406     static const int16_t* const functf[4] = {functf2,functf3,functf4,functf5};
00407 
00408     unsigned x = I;
00409     int mask=(1<<(RATE-1));
00410     if(x&mask)
00411         x = ~x;
00412     x &= mask-1;
00413     FI = functf[RATE-2][x];
00414 
00415     CHECK_UM(FI,3);
00416     }
00417 
00418 
00422 inline static void LIMA(unsigned AP,unsigned& AL)
00423     {
00424     CHECK_UM(AP,10);
00425     AL = (AP>256) ? 64 : AP>>2;
00426     CHECK_UM(AL,7);
00427     }
00428 
00429 
00433 inline static void SUBTC(unsigned DMSP,unsigned DMLP,unsigned TDP,unsigned Y,unsigned& AX)
00434     {
00435     CHECK_UM(DMSP,12);
00436     CHECK_UM(DMLP,14);
00437     CHECK_UNSIGNED(TDP,1);
00438     CHECK_UM(Y,13);
00439     int DIF = (DMSP<<2)-DMLP;
00440     unsigned DIFM;
00441     if(DIF<0)
00442         DIFM = -DIF;
00443     else
00444         DIFM = DIF;
00445     unsigned DTHR = DMLP >> 3;
00446     AX = (Y>=1536 && DIFM<DTHR) ? TDP : 1;
00447     CHECK_UM(AX,1);
00448     }
00449 
00450 
00454 inline static void TRIGA(unsigned TR,unsigned APP,unsigned& APR)
00455     {
00456     CHECK_UNSIGNED(TR,1);
00457     CHECK_UM(APP,10);
00458     APR = TR ? 256 : APP;
00459     CHECK_UM(APR,10);
00460     }
00461 
00465 inline static void ACCUM(int WAn[2],int WBn[6],int& SE,int& SEZ)
00466     {
00467     CHECK_TC(WAn[0],16);
00468     CHECK_TC(WAn[1],16);
00469     CHECK_TC(WBn[0],16);
00470     CHECK_TC(WBn[1],16);
00471     CHECK_TC(WBn[2],16);
00472     CHECK_TC(WBn[3],16);
00473     CHECK_TC(WBn[4],16);
00474     CHECK_TC(WBn[5],16);
00475     int16_t SEZI = (int16_t)(WBn[0]+WBn[1]+WBn[2]+WBn[3]+WBn[4]+WBn[5]);
00476     int16_t SEI = (int16_t)(SEZI+WAn[0]+WAn[1]);
00477     SEZ = SEZI >> 1;
00478     SE = SEI >> 1;
00479     CHECK_TC(SE,15);
00480     CHECK_TC(SEZ,15);
00481     }
00482 
00483 
00487 inline static void ADDB(unsigned DQ,int SE,int& SR)
00488     {
00489     CHECK_SM(DQ,16);
00490     CHECK_TC(SE,15);
00491     int DQI;
00492     if(DQ&(1<<15))
00493         DQI = (1<<15)-DQ;
00494     else
00495         DQI = DQ;
00496     SR = (int16_t)(DQI+SE);
00497     CHECK_TC(SR,16);
00498     }
00499 
00500 
00504 inline static void ADDC(unsigned DQ,int SEZ,int& PK0,unsigned& SIGPK)
00505     {
00506     CHECK_SM(DQ,16);
00507     CHECK_TC(SEZ,15);
00508     int DQI;
00509     if(DQ&(1<<15))
00510         DQI = (1<<15)-DQ;
00511     else
00512         DQI = DQ;
00513     int DQSEZ = (int16_t)(DQI+SEZ);
00514     PK0 = DQSEZ>>15;
00515     SIGPK = DQSEZ ? 0 : 1;
00516     CHECK_TC(PK0,1);
00517     CHECK_UNSIGNED(SIGPK,1);
00518     }
00519 
00520 
00521 static void MagToFloat(unsigned mag,unsigned& exp,unsigned& mant)
00522     {
00523     unsigned e = 0;
00524     unsigned m = mag<<1;
00525     if(m>=(1<<8))
00526         {
00527         e |= 8;
00528         m >>= 8;
00529         }
00530     if(m>=(1<<4))
00531         {
00532         e |= 4;
00533         m >>= 4;
00534         }
00535     if(m>=(1<<2))
00536         {
00537         e |= 2;
00538         m >>= 2;
00539         }
00540     e |= m>>1;
00541     exp = e;
00542     mant = mag ? (mag<<6)>>e : 1<<5;
00543     }
00544 
00545 
00549 inline static void FLOATA(unsigned DQ, unsigned& DQ0)
00550     {
00551     CHECK_SM(DQ,16);
00552     unsigned DQS = (DQ>>15);
00553     unsigned MAG = DQ&32767;
00554     unsigned EXP;
00555     unsigned MANT;
00556     MagToFloat(MAG,EXP,MANT);
00557     DQ0 = (DQS<<10) + (EXP<<6) + MANT;
00558     CHECK_FL(DQ0,11);
00559     }
00560 
00561 
00565 inline static void FLOATB(int SR, unsigned& SR0)
00566     {
00567     CHECK_TC(SR,16);
00568     unsigned SRS = (SR>>15)&1;
00569     unsigned MAG = SRS ? (-SR)&32767 : SR;
00570     unsigned EXP;
00571     unsigned MANT;
00572     MagToFloat(MAG,EXP,MANT);
00573     SR0 = (SRS<<10) + (EXP<<6) + MANT;
00574     CHECK_FL(SR0,11);
00575     }
00576 
00577 
00581 static void FMULT(int An,unsigned SRn,int& WAn)
00582     {
00583     CHECK_TC(An,16);
00584     CHECK_FL(SRn,11);
00585     unsigned AnS = (An>>15)&1;
00586     unsigned AnMAG = AnS ? (-(An>>2))&8191 : An>>2;
00587     unsigned AnEXP;
00588     unsigned AnMANT;
00589     MagToFloat(AnMAG,AnEXP,AnMANT);
00590 
00591     unsigned SRnS = SRn>>10;
00592     unsigned SRnEXP = (SRn>>6) & 15;
00593     unsigned SRnMANT = SRn&63;
00594 
00595     unsigned WAnS = SRnS^AnS;
00596     unsigned WAnEXP = SRnEXP+AnEXP;
00597     unsigned WAnMANT = ((SRnMANT*AnMANT)+48)>>4;
00598     unsigned WAnMAG;
00599     if(WAnEXP<=26)
00600         WAnMAG = (WAnMANT<<7) >> (26-WAnEXP);
00601     else
00602         WAnMAG = ((WAnMANT<<7) << (WAnEXP-26)) & 32767;
00603     WAn = WAnS ? -(int)WAnMAG : WAnMAG;
00604     CHECK_TC(WAn,16);
00605     }
00606 
00607 
00611 inline static void LIMC(int A2T,int& A2P)
00612     {
00613     CHECK_TC(A2T,16);
00614     const int A2UL = 12288;
00615     const int A2LL = 53248-65536;
00616     if(A2T<=A2LL)
00617         A2P = A2LL;
00618     else if(A2T>=A2UL)
00619         A2P = A2UL;
00620     else
00621         A2P = A2T;
00622     CHECK_TC(A2P,16);
00623     }
00624 
00625 
00629 inline static void LIMD(int A1T,int A2P,int& A1P)
00630     {
00631     CHECK_TC(A1T,16);
00632     CHECK_TC(A2P,16);
00633     const int OME = 15360;
00634     int A1UL = (int16_t)(OME-A2P);
00635     int A1LL = (int16_t)(A2P-OME);
00636     if(A1T<=A1LL)
00637         A1P = A1LL;
00638     else if(A1T>=A1UL)
00639         A1P = A1UL;
00640     else
00641         A1P = A1T;
00642     CHECK_TC(A1P,16);
00643     }
00644 
00645 
00649 inline static void TRIGB(unsigned TR,int AnP,int& AnR)
00650     {
00651     CHECK_UNSIGNED(TR,1);
00652     CHECK_TC(AnP,16);
00653     AnR = TR ? 0 : AnP;
00654     CHECK_TC(AnR,16);
00655     }
00656 
00657 
00661 inline static void UPA1(int PK0,int PK1,int A1,unsigned SIGPK,int& A1T)
00662     {
00663     CHECK_TC(PK0,1);
00664     CHECK_TC(PK1,1);
00665     CHECK_TC(A1,16);
00666     CHECK_UNSIGNED(SIGPK,1);
00667     int UGA1;
00668     if(SIGPK==0)
00669         {
00670         if(PK0^PK1)
00671             UGA1 = -192;
00672         else
00673             UGA1 = 192;
00674         }
00675     else
00676         UGA1 = 0;
00677     A1T = (int16_t)(A1+UGA1-(A1>>8));
00678     CHECK_TC(A1T,16);
00679     }
00680 
00681 
00685 inline static void UPA2(int PK0,int PK1,int PK2,int A1,int A2,unsigned SIGPK,int& A2T)
00686     {
00687     CHECK_TC(PK0,1);
00688     CHECK_TC(PK1,1);
00689     CHECK_TC(PK2,1);
00690     CHECK_TC(A1,16);
00691     CHECK_TC(A2,16);
00692     CHECK_UNSIGNED(SIGPK,1);
00693 
00694     unsigned UGA2;
00695     if(SIGPK==0)
00696         {
00697         int UGA2A = (PK0^PK2) ? -16384 : 16384;
00698 
00699         int FA1;
00700         if(A1<-8191)     FA1 = -8191<<2;
00701         else if(A1>8191) FA1 = 8191<<2;
00702         else             FA1 = A1<<2;
00703 
00704         int FA = (PK0^PK1) ? FA1 : -FA1;
00705 
00706         UGA2 = (UGA2A+FA) >> 7;
00707         }
00708     else
00709         UGA2 = 0;
00710     A2T = (int16_t)(A2+UGA2-(A2>>7));
00711 
00712     CHECK_TC(A2T,16);
00713     }
00714 
00715 
00719 inline static void UPB(unsigned RATE,int Un,int Bn,unsigned DQ,int& BnP)
00720     {
00721     CHECK_TC(Un,1);
00722     CHECK_TC(Bn,16);
00723     CHECK_SM(DQ,16);
00724     int UGBn;
00725     if(DQ&32767)
00726         UGBn = Un ? -128 : 128;
00727     else
00728         UGBn = 0;
00729     int ULBn = (RATE==5) ? Bn>>9 : Bn>>8;
00730     BnP = (int16_t)(Bn+UGBn-ULBn);
00731     CHECK_TC(BnP,16);
00732     }
00733 
00734 
00738 inline static void XOR(unsigned DQn,unsigned DQ,int& Un)
00739     {
00740     CHECK_FL(DQn,11);
00741     CHECK_SM(DQ,16);
00742     Un = -(int)((DQn>>10)^(DQ>>15));
00743     CHECK_TC(Un,1);
00744     }
00745 
00746 
00750 inline static void TONE(int A2P,unsigned& TDP)
00751     {
00752     CHECK_TC(A2P,16);
00753     TDP = A2P<(53760-65536);
00754     CHECK_UNSIGNED(TDP,1);
00755     }
00756 
00757 
00761 inline static void TRANS(unsigned TD,unsigned YL,unsigned DQ,unsigned& TR)
00762     {
00763     CHECK_UNSIGNED(TD,1);
00764     CHECK_UM(YL,19);
00765     CHECK_SM(DQ,16);
00766     unsigned DQMAG = DQ&32767;
00767     unsigned YLINT = YL>>15;
00768     unsigned YLFRAC = (YL>>10) & 31;
00769     unsigned THR1 = (32+YLFRAC)<<YLINT;
00770     unsigned THR2;
00771     if(YLINT>9)
00772         THR2 = 31<<10;
00773     else
00774         THR2 = THR1;
00775     unsigned DQTHR = (THR2+(THR2>>1)) >> 1;
00776     TR = DQMAG>DQTHR && TD;
00777     CHECK_UNSIGNED(TR,1);
00778     }
00779 
00780 
00784 inline static void COMPRESS(int SR,unsigned LAW,unsigned& SP)
00785     {
00786     CHECK_TC(SR,16);
00787     CHECK_UNSIGNED(LAW,1);
00788     int x = SR;
00789 
00790 #ifdef IMPLEMENT_G191_BUGS
00791     // reproduce bugs in G191 reference implementation...
00792     if(x==-0x8000)
00793         x=-1;
00794     else
00795         if(!LAW && x<0) x--;
00796 #endif
00797 
00798     // Clamp to 14 bits...
00799     if(x>=(1<<13))
00800         x = (1<<13)-1;
00801     else if(x<-(1<<13))
00802         x = -(1<<13);
00803 
00804     if(LAW)
00805         SP = G711::ALawEncode(x<<2);
00806     else
00807         SP = G711::ULawEncode(x<<2);
00808 
00809     CHECK_UNSIGNED(SP,8);
00810     }
00811 
00812 
00816 inline static void SYNC(unsigned RATE,unsigned I,unsigned SP,int DLNX,int DSX,unsigned LAW,unsigned& SD)
00817     {
00818     CHECK_UNSIGNED(SP,8);
00819     CHECK_TC(DLNX,12);
00820     CHECK_TC(DSX,1);
00821     CHECK_UNSIGNED(LAW,1);
00822 
00823     unsigned ID;
00824     unsigned IM;
00825     QUAN(RATE,DLNX,DSX,ID);
00826     unsigned signMask = 1<<(RATE-1);
00827     ID = ID^signMask;
00828     IM = I^signMask;
00829 
00830     unsigned s;
00831     if(LAW)
00832         {
00833         s = SP^0x55;
00834         if(!(s&0x80))
00835             s = s^0x7f;
00836         }
00837     else
00838         {
00839         s = SP;
00840         if(s&0x80)
00841             s = s^0x7f;
00842         }
00843     // s = ALAW/uLAW code converted to range 0x00..0xff
00844     // where 0x00 is most-negative and 0xff is most-positive
00845 
00846     if(ID<IM)
00847         {
00848         if(s<0xff)
00849             ++s;
00850         }
00851     else if(ID>IM)
00852         {
00853         if(s>0x00)
00854             {
00855             --s;
00856             if(s==0x7f && !LAW) --s; // TABLE 20/G.726 says uLaw 0xFF decrements to 0x7e and not 0x7f (!?)
00857             }
00858         }
00859 
00860     // convert s back to ALAW/uLAW code
00861     if(LAW)
00862         {
00863         if(!(s&0x80))
00864             s = s^0x7f;
00865         s = s^0x55;
00866         }
00867     else
00868         {
00869         if(s&0x80)
00870             s = s^0x7f;
00871         }
00872     SD = s;
00873     CHECK_UNSIGNED(SD,8);
00874     }
00875 
00876 
00880 inline static void LIMO(int SR,int& SO)
00881     {
00882     CHECK_TC(SR,16);
00883     if(SR>=(1<<13))
00884         SO = (1<<13)-1;
00885     else if(SR<-(1<<13))
00886         SO = -(1<<13);
00887     else
00888         SO = SR;
00889     CHECK_TC(SO,14);
00890     }
00891 
00892  // End of group
00894 
00895 
00908 inline void G726::InputPCMFormatConversionAndDifferenceSignalComputation(unsigned S,int SE,int& D)
00909     {
00910     int SL;
00911     EXPAND(S,LAW,SL);
00912     SUBTA(SL,SE,D);
00913     }
00914 
00915 
00919 inline void G726::AdaptiveQuantizer(int D,unsigned Y,unsigned& I)
00920     {
00921     unsigned DL;
00922     int DS;
00923     LOG(D,DL,DS);
00924 
00925     int DLN;
00926     SUBTB(DL,Y,DLN);
00927 
00928     QUAN(RATE,DLN,DS,I);
00929     }
00930 
00931 
00935 inline void G726::InverseAdaptiveQuantizer(unsigned I,unsigned Y,unsigned& DQ)
00936     {
00937     int DQLN;
00938     int DQS;
00939     RECONST(RATE,I,DQLN,DQS);
00940 
00941     int DQL;
00942     ADDA(DQLN,Y,DQL);
00943 
00944     ANTILOG(DQL,DQS,DQ);
00945     }
00946 
00947 
00951 inline void G726::QuantizerScaleFactorAdaptation1(unsigned AL,unsigned& Y)
00952     {
00953     MIX(AL,YU,YL,Y);
00954     }
00958 inline void G726::QuantizerScaleFactorAdaptation2(unsigned I,unsigned Y)
00959     {
00960     int WI;
00961     FUNCTW(RATE,I,WI);
00962 
00963     unsigned YUT;
00964     FILTD(WI,Y,YUT);
00965 
00966     unsigned YUP;
00967     LIMB(YUT,YUP);
00968 
00969     unsigned YLP;
00970     FILTE(YUP,YL,YLP);
00971 
00972     YU = YUP; // Delay
00973     YL = YLP; // Delay
00974     }
00975 
00976 
00980 inline void G726::AdaptationSpeedControl1(unsigned& AL)
00981     {
00982     LIMA(AP,AL);
00983     }
00987 inline void G726::AdaptationSpeedControl2(unsigned I,unsigned Y,unsigned TDP,unsigned TR)
00988     {
00989     unsigned FI;
00990     FUNCTF(RATE,I,FI);
00991 
00992     FILTA(FI,DMS,DMS); // Result 'DMSP' straight to delay storage 'DMS'
00993     FILTB(FI,DML,DML); // Result 'DMSP' straight to delay storage 'DMS'
00994 
00995     unsigned AX;
00996     SUBTC(DMS,DML,TDP,Y,AX); // DMSP and DMLP are read from delay storage 'DMS' and 'DML'
00997 
00998     unsigned APP;
00999     FILTC(AX,AP,APP);
01000 
01001     TRIGA(TR,APP,AP); // Result 'APR' straight to delay storage 'AP'
01002     }
01003 
01004 
01008 inline void G726::AdaptativePredictorAndReconstructedSignalCalculator1(int& SE,int& SEZ)
01009     {
01010     int WBn[6];
01011     for(int i=0; i<6; i++)
01012         FMULT(Bn[i],DQn[i],WBn[i]);
01013     int WAn[2];
01014     FMULT(A1,SR1,WAn[0]);
01015     FMULT(A2,SR2,WAn[1]);
01016     ACCUM(WAn,WBn,SE,SEZ);
01017     }
01021 inline void G726::AdaptativePredictorAndReconstructedSignalCalculator2(unsigned DQ,unsigned TR,int SE,int SEZ,int& SR,int& A2P)
01022     {
01023     int PK0;
01024     unsigned SIGPK;
01025     ADDC(DQ,SEZ,PK0,SIGPK);
01026 
01027     ADDB(DQ,SE,SR);
01028     SR2 = SR1; // Delay
01029     FLOATB(SR,SR1);  // Result 'SR0' straight to delay storage 'SR1'
01030 
01031     unsigned DQ0;
01032     FLOATA(DQ,DQ0);
01033 
01034     int i;
01035     for(i=0; i<6; i++)
01036         {
01037         int Un;
01038         XOR(DQn[i],DQ,Un);
01039         int BnP;
01040         UPB(RATE,Un,Bn[i],DQ,BnP);
01041         TRIGB(TR,BnP,Bn[i]); // Result 'BnR' straight to delay storage 'Bn'
01042         }
01043 
01044     int A2T;
01045     UPA2(PK0,PK1,PK2,A1,A2,SIGPK,A2T);
01046     LIMC(A2T,A2P);
01047     TRIGB(TR,A2P,A2); // Result 'A2R' straight to delay storage 'A2'
01048 
01049     int A1T;
01050     UPA1(PK0,PK1,A1,SIGPK,A1T);
01051     int A1P;
01052     LIMD(A1T,A2P,A1P);
01053     TRIGB(TR,A1P,A1); // Result 'A1R' straight to delay storage 'A1'
01054 
01055     PK2 = PK1; // Delay
01056     PK1 = PK0; // Delay
01057 
01058     for(i=5; i>0; i--)
01059         DQn[i] = DQn[i-1]; // Delay
01060     DQn[0] = DQ0; // Delay
01061     }
01062 
01063 
01067 inline void G726::ToneAndTransitionDetector1(unsigned DQ,unsigned& TR)
01068     {
01069     TRANS(TD,YL,DQ,TR);
01070     }
01074 inline void G726::ToneAndTransitionDetector2(int A2P,unsigned TR,unsigned& TDP)
01075     {
01076     TONE(A2P,TDP);
01077     TRIGB(TR,TDP,(int&)TD);  // Result 'TDR' straight to delay storage 'TD'
01078     }
01079 
01080 
01084 inline void G726::OutputPCMFormatConversionAndSynchronousCodingAdjustment(int SR,int SE,unsigned Y,unsigned I,unsigned& SD)
01085     {
01086     unsigned SP;
01087     COMPRESS(SR,LAW,SP);
01088     int SLX;
01089     EXPAND(SP,LAW,SLX);
01090     int DX;
01091     SUBTA(SLX,SE,DX);
01092     unsigned DLX;
01093     int DSX;
01094     LOG(DX,DLX,DSX);
01095     int DLNX;
01096     SUBTB(DLX,Y,DLNX);
01097     SYNC(RATE,I,SP,DLNX,DSX,LAW,SD);
01098     }
01099 
01100 
01104 inline void G726::DifferenceSignalComputation(int SL,int SE,int& D)
01105     {
01106     SUBTA(SL,SE,D);
01107     }
01108 
01109 
01113 inline void G726::OutputLimiting(int SR,int& SO)
01114     {
01115     LIMO(SR,SO);
01116     }
01117 
01118  // End of group
01120 
01121 
01130 unsigned G726::EncodeDecode(unsigned input,bool encode)
01131     {
01132     unsigned AL;
01133     AdaptationSpeedControl1(AL);
01134     unsigned Y;
01135     QuantizerScaleFactorAdaptation1(AL,Y);
01136     int SE;
01137     int SEZ;
01138     AdaptativePredictorAndReconstructedSignalCalculator1(SE,SEZ);
01139 
01140     unsigned I;
01141     if(encode)
01142         {
01143         int D;
01144         if(LAW==G726::PCM16)
01145             {
01146             int SL = (int16_t)input;
01147             SL >>= 2; // Convert input from 16bit to 14bit
01148             DifferenceSignalComputation(SL,SE,D);
01149             }
01150         else
01151             InputPCMFormatConversionAndDifferenceSignalComputation(input,SE,D);
01152         AdaptiveQuantizer(D,Y,I);
01153         }
01154     else
01155         I = input;
01156 
01157     unsigned DQ;
01158     InverseAdaptiveQuantizer(I,Y,DQ);
01159     unsigned TR;
01160     ToneAndTransitionDetector1(DQ,TR);
01161     int SR;
01162     int A2P;
01163     AdaptativePredictorAndReconstructedSignalCalculator2(DQ,TR,SE,SEZ,SR,A2P);
01164     unsigned TDP;
01165     ToneAndTransitionDetector2(A2P,TR,TDP);
01166     AdaptationSpeedControl2(I,Y,TDP,TR);
01167     QuantizerScaleFactorAdaptation2(I,Y);
01168 
01169     if(encode)
01170         return I;
01171 
01172     if(LAW==G726::PCM16)
01173         {
01174         int SO;
01175         OutputLimiting(SR,SO);
01176         return SO<<2; // Convert result from 14bit to 16 bit
01177         }
01178     else
01179         {
01180         unsigned SD;
01181         OutputPCMFormatConversionAndSynchronousCodingAdjustment(SR,SE,Y,I,SD);
01182         return SD;
01183         }
01184     }
01185 
01186 
01187 /*
01188 Public members of class G726
01189 */
01190 
01191 
01192 void G726::Reset()
01193     {
01194     int i;
01195     for(i=0; i<6; i++)
01196         {
01197         Bn[i] = 0;
01198         DQn[i] = 32;
01199         }
01200     A1 = 0;
01201     A2 = 0;
01202     AP = 0;
01203     DML = 0;
01204     DMS = 0;
01205     PK1 = 0;
01206     PK2 = 0;
01207     SR1 = 32;
01208     SR2 = 32;
01209     TD = 0;
01210     YL = 34816;
01211     YU = 544;
01212     }
01213 
01214 
01215 void G726::SetLaw(Law law)
01216     {
01217     ASSERT_DEBUG((unsigned)law<=PCM16);
01218     LAW = law;
01219     }
01220 
01221 
01222 void G726::SetRate(Rate rate)
01223     {
01224     ASSERT_DEBUG((unsigned)(rate-Rate16kBits)<=(unsigned)(Rate40kBits-Rate16kBits));
01225     RATE = rate;
01226     }
01227 
01228 
01229 unsigned G726::Encode(unsigned S)
01230     {
01231     return EncodeDecode(S,true);
01232     }
01233 
01234 
01235 unsigned G726::Decode(unsigned I)
01236     {
01237     I &= (1<<RATE)-1; // Mask off un-needed bits
01238     return EncodeDecode(I,false);
01239     }
01240 
01241 
01242 unsigned G726::Encode(void* dst, int dstOffset, const void* src, size_t srcSize)
01243     {
01244     // convert pointers into more useful types
01245     uint8_t* out = (uint8_t*)dst;
01246     union
01247         {
01248     const uint8_t* ptr8;
01249     const uint16_t* ptr16;
01250         }
01251     in;
01252     in.ptr8 = (const uint8_t*)src;
01253 
01254     // use given bit offset
01255     out += dstOffset>>3;
01256     unsigned bitOffset = dstOffset&7;
01257 
01258     unsigned bits = RATE;           // bits per adpcm sample
01259     unsigned mask = (1<<bits)-1;    // bitmask for an adpcm sample
01260 
01261     // calculate number of bits to be written
01262     unsigned outBits;
01263     if(LAW!=PCM16)
01264         outBits = bits*srcSize;
01265     else
01266         {
01267         outBits = bits*(srcSize>>1);
01268         srcSize &= ~1; // make sure srcSize represents a whole number of samples
01269         }
01270 
01271     // calculate end of input buffer
01272     const uint8_t* end = in.ptr8+srcSize;
01273 
01274     while(in.ptr8<end)
01275         {
01276         // read a single PCM value from input
01277         unsigned pcm;
01278         if(LAW==PCM16)
01279             pcm = *in.ptr16++;
01280         else
01281             pcm = *in.ptr8++;
01282 
01283         // encode the pcm value as an adpcm value
01284         unsigned adpcm = Encode(pcm);
01285         // shift it to the required output position
01286         adpcm <<= bitOffset;
01287 
01288         // write adpcm value to buffer...
01289         unsigned b = *out;          // get byte from ouput
01290         b &= ~(mask<<bitOffset);    // clear bits which we want to write to
01291         b |= adpcm;                 // or in adpcm value
01292         *out = (uint8_t)b;          // write value back to output
01293 
01294         // update bitOffset for next adpcm value
01295         bitOffset += bits;
01296 
01297         // loop if not moved on to next byte
01298         if(bitOffset<8)
01299             continue;
01300 
01301         // move pointers on to next byte
01302         ++out;
01303         bitOffset &= 7;
01304 
01305         // write any left-over bits from the last adpcm value
01306         if(bitOffset)
01307             *out = (uint8_t)(adpcm>>8);
01308         }
01309 
01310     // return number bits written to dst
01311     return outBits;
01312     }
01313 
01314 
01315 unsigned G726::Decode(void* dst, const void* src, int srcOffset, unsigned srcSize)
01316     {
01317     // convert pointers into more useful types
01318     union
01319         {
01320     uint8_t* ptr8;
01321     uint16_t* ptr16;
01322         }
01323     out;
01324     out.ptr8 = (uint8_t*)dst;
01325     const uint8_t* in = (const uint8_t*)src;
01326 
01327     // use given bit offset
01328     in += srcOffset>>3;
01329     unsigned bitOffset = srcOffset&7;
01330 
01331     unsigned bits = RATE;       // bits per adpcm sample
01332 
01333     while(srcSize>=bits)
01334         {
01335         // read adpcm value from input
01336         unsigned adpcm = *in;
01337         if(bitOffset+bits>8)
01338             adpcm |= in[1]<<8;  // need bits from next byte as well
01339 
01340         // allign adpcm value to bit 0
01341         adpcm >>= bitOffset;
01342 
01343         // decode the adpcm value into a pcm value
01344         unsigned pcm = Decode(adpcm);
01345 
01346         // write pcm value to output
01347         if(LAW==PCM16)
01348             *out.ptr16++ = (int16_t)pcm;
01349         else
01350             *out.ptr8++ = (uint8_t)pcm;
01351 
01352         // update bit values for next adpcm value
01353         bitOffset += bits;
01354         srcSize -= bits;
01355 
01356         // move on to next byte of input if required
01357         if(bitOffset>=8)
01358             {
01359             bitOffset &= 7;
01360             ++in;
01361             }
01362         }
01363 
01364     // return number of bytes written to dst
01365     return out.ptr8-(uint8_t*)dst;
01366     }
01367 
01368 

Generated by  doxygen 1.6.1