Mercurial > hg > audiostuff
diff intercom/g711/g711.c @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intercom/g711/g711.c Fri Jun 25 09:57:52 2010 +0200 @@ -0,0 +1,314 @@ +/* Version 3.01 - 31.Jan.2000 +============================================================================= + + U U GGG SSS TTTTT + U U G S T + U U G GG SSS T + U U G G S T + UUUU GGG SSS T + + ======================================== + ITU-T - USER'S GROUP ON SOFTWARE TOOLS + ======================================== + + + ============================================================= + COPYRIGHT NOTE: This source code, and all of its derivations, + is subject to the "ITU-T General Public License". Please have + it read in the distribution disk, or in the ITU-T + Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO + CODING STANDARDS". + ============================================================= + + +MODULE: G711.C, G.711 ENCODING/DECODING FUNCTIONS + +ORIGINAL BY: + + Simao Ferraz de Campos Neto Rudolf Hofmann + CPqD/Telebras PHILIPS KOMMUNIKATIONS INDUSTRIE AG + DDS/Pr.11 Kommunikationssysteme + Rd. Mogi Mirim-Campinas Km.118 Thurn-und-Taxis-Strasse 14 + 13.085 - Campinas - SP (Brazil) D-8500 Nuernberg 10 (Germany) + + Phone : +55-192-39-6396 Phone : +49 911 526-2603 + FAX : +55-192-53-4754 FAX : +49 911 526-3385 + EMail : tdsimao@venus.cpqd.ansp.br EMail : HF@PKINBG.UUCP + + +FUNCTIONS: + +alaw_compress: ... compands 1 vector of linear PCM samples to A-law; + uses 13 Most Sig.Bits (MSBs) from input and 8 Least + Sig. Bits (LSBs) on output. + +alaw_expand: ..... expands 1 vector of A-law samples to linear PCM; + use 8 Least Sig. Bits (LSBs) from input and + 13 Most Sig.Bits (MSBs) on output. + +ulaw_compress: ... compands 1 vector of linear PCM samples to u-law; + uses 14 Most Sig.Bits (MSBs) from input and 8 Least + Sig. Bits (LSBs) on output. + +ulaw_expand: ..... expands 1 vector of u-law samples to linear PCM + use 8 Least Sig. Bits (LSBs) from input and + 14 Most Sig.Bits (MSBs) on output. + +PROTOTYPES: in g711.h + +HISTORY: +Apr/91 1.0 First version of the G711 module +10/Dec/1991 2.0 Break-up in individual functions for A,u law; + correction of bug in compression routines (use of 1 + and 2 complement); Demo program inside module. +08/Feb/1992 3.0 Demo as separate file; +31/Jan/2000 3.01 Updated documentation text; no change in functions + <simao.campos@labs.comsat.com> +13jan2005 Byte for compressed data +============================================================================= +*/ + +/* + * .......... I N C L U D E S .......... + */ + +/* Global prototype functions */ +#include "g711.h" + +/* + * .......... F U N C T I O N S .......... + */ + +/* ................... Begin of alaw_compress() ..................... */ +/* + ========================================================================== + + FUNCTION NAME: alaw_compress + + DESCRIPTION: ALaw encoding rule according ITU-T Rec. G.711. + + PROTOTYPE: void alaw_compress(long lseg, short *linbuf, short *logbuf) + + PARAMETERS: + lseg: (In) number of samples + linbuf: (In) buffer with linear samples (only 12 MSBits are taken + into account) + logbuf: (Out) buffer with compressed samples (8 bit right justified, + without sign extension) + + RETURN VALUE: none. + + HISTORY: + 10.Dec.91 1.0 Separated A-law compression function + + ========================================================================== +*/ +void alaw_compress(long lseg, short *linbuf, Byte *logbuf) +{ + short ix, iexp; + long n; + + for (n = 0; n < lseg; n++) { + ix = linbuf[n] < 0 /* 0 <= ix < 2048 */ + ? (~linbuf[n]) >> 4 /* 1's complement for negative values */ + : (linbuf[n]) >> 4; + + /* Do more, if exponent > 0 */ + if (ix > 15) { /* exponent=0 for ix <= 15 */ + iexp = 1; /* first step: */ + while (ix > 16 + 15) { /* find mantissa and exponent */ + ix >>= 1; + iexp++; + } + ix -= 16; /* second step: remove leading '1' */ + + ix += iexp << 4; /* now compute encoded value */ + } + if (linbuf[n] >= 0) + ix |= (0x0080); /* add sign bit */ + + logbuf[n] = ix ^ (0x0055); /* toggle even bits */ + } +} + +/* ................... End of alaw_compress() ..................... */ + + +/* ................... Begin of alaw_expand() ..................... */ +/* + ========================================================================== + + FUNCTION NAME: alaw_expand + + DESCRIPTION: ALaw decoding rule according ITU-T Rec. G.711. + + PROTOTYPE: void alaw_expand(long lseg, short *logbuf, short *linbuf) + + PARAMETERS: + lseg: (In) number of samples + logbuf: (In) buffer with compressed samples (8 bit right justified, + without sign extension) + linbuf: (Out) buffer with linear samples (13 bits left justified) + + RETURN VALUE: none. + + HISTORY: + 10.Dec.91 1.0 Separated A-law expansion function + + ============================================================================ +*/ +void alaw_expand(long lseg, Byte *logbuf, short *linbuf) +{ + short ix, mant, iexp; + long n; + + for (n = 0; n < lseg; n++) { + ix = logbuf[n] ^ (0x0055); /* re-toggle toggled bits */ + + ix &= (0x007F); /* remove sign bit */ + iexp = ix >> 4; /* extract exponent */ + mant = ix & (0x000F); /* now get mantissa */ + if (iexp > 0) + mant = mant + 16; /* add leading '1', if exponent > 0 */ + + mant = (mant << 4) + (0x0008); /* now mantissa left justified and */ + /* 1/2 quantization step added */ + if (iexp > 1) /* now left shift according exponent */ + mant = mant << (iexp - 1); + + linbuf[n] = logbuf[n] > 127 /* invert, if negative sample */ + ? mant : -mant; + } +} + +/* ................... End of alaw_expand() ..................... */ + + +/* ................... Begin of ulaw_compress() ..................... */ +/* + ========================================================================== + + FUNCTION NAME: ulaw_compress + + DESCRIPTION: Mu law encoding rule according ITU-T Rec. G.711. + + PROTOTYPE: void ulaw_compress(long lseg, short *linbuf, short *logbuf) + + PARAMETERS: + lseg: (In) number of samples + linbuf: (In) buffer with linear samples (only 12 MSBits are taken + into account) + logbuf: (Out) buffer with compressed samples (8 bit right justified, + without sign extension) + + RETURN VALUE: none. + + HISTORY: + 10.Dec.91 1.0 Separated mu-law compression function + + ========================================================================== +*/ +void ulaw_compress(long lseg, short *linbuf, Byte *logbuf) +{ + long n; /* samples's count */ + short i; /* aux.var. */ + short absno; /* absolute value of linear (input) sample */ + short segno; /* segment (Table 2/G711, column 1) */ + short low_nibble; /* low nibble of log companded sample */ + short high_nibble; /* high nibble of log companded sample */ + + for (n = 0; n < lseg; n++) { + /* -------------------------------------------------------------------- */ + /* Change from 14 bit left justified to 14 bit right justified */ + /* Compute absolute value; adjust for easy processing */ + /* -------------------------------------------------------------------- */ + absno = linbuf[n] < 0 /* compute 1's complement in case of */ + ? ((~linbuf[n]) >> 2) + 33 /* negative samples */ + : ((linbuf[n]) >> 2) + 33; /* NB: 33 is the difference value */ + /* between the thresholds for */ + /* A-law and u-law. */ + if (absno > (0x1FFF)) /* limitation to "absno" < 8192 */ + absno = (0x1FFF); + + /* Determination of sample's segment */ + i = absno >> 6; + segno = 1; + while (i != 0) { + segno++; + i >>= 1; + } + + /* Mounting the high-nibble of the log-PCM sample */ + high_nibble = (0x0008) - segno; + + /* Mounting the low-nibble of the log PCM sample */ + low_nibble = (absno >> segno) /* right shift of mantissa and */ + &(0x000F); /* masking away leading '1' */ + low_nibble = (0x000F) - low_nibble; + + /* Joining the high-nibble and the low-nibble of the log PCM sample */ + logbuf[n] = (high_nibble << 4) | low_nibble; + + /* Add sign bit */ + if (linbuf[n] >= 0) + logbuf[n] = logbuf[n] | (0x0080); + } +} + +/* ................... End of ulaw_compress() ..................... */ + + + +/* ................... Begin of ulaw_expand() ..................... */ +/* + ========================================================================== + + FUNCTION NAME: ulaw_expand + + DESCRIPTION: Mu law decoding rule according ITU-T Rec. G.711. + + PROTOTYPE: void ulaw_expand(long lseg, short *logbuf, short *linbuf) + + PARAMETERS: + lseg: (In) number of samples + logbuf: (In) buffer with compressed samples (8 bit right justified, + without sign extension) + linbuf: (Out) buffer with linear samples (14 bits left justified) + + RETURN VALUE: none. + + HISTORY: + 10.Dec.91 1.0 Separated mu law expansion function + + ============================================================================ +*/ + +void ulaw_expand(long lseg, Byte *logbuf, short *linbuf) +{ + long n; /* aux.var. */ + short segment; /* segment (Table 2/G711, column 1) */ + short mantissa; /* low nibble of log companded sample */ + short exponent; /* high nibble of log companded sample */ + short sign; /* sign of output sample */ + short step; + + for (n = 0; n < lseg; n++) { + sign = logbuf[n] < (0x0080) /* sign-bit = 1 for positiv values */ + ? -1 : 1; + mantissa = ~logbuf[n]; /* 1's complement of input value */ + exponent = (mantissa >> 4) & (0x0007); /* extract exponent */ + segment = exponent + 1; /* compute segment number */ + mantissa = mantissa & (0x000F); /* extract mantissa */ + + /* Compute Quantized Sample (14 bit left justified!) */ + step = (4) << segment; /* position of the LSB */ + /* = 1 quantization step) */ + linbuf[n] = sign * /* sign */ + (((0x0080) << exponent) /* '1', preceding the mantissa */ + +step * mantissa /* left shift of mantissa */ + + step / 2 /* 1/2 quantization step */ + - 4 * 33); + } +} + +/* ................... End of ulaw_expand() ..................... */