• Main Page
  • Related Pages
  • Packages
  • Classes
  • Files
  • File List

audio/AudioCodecUlaw.java

Go to the documentation of this file.
00001 
00002 package audio;
00003 
00004 import utils.OctetBuffer;
00005 
00006 /**
00007  *  Converts a 16-bit linear PCM stream from and to 8-bit u-law.
00008  *  
00009  *  @author Mikica B Kocic, based on Craig Reese's and Joe Campbell's C source code.
00010  */
00011 public class AudioCodecUlaw extends AbstractCODEC 
00012 {
00013     private int sampleSize;
00014 
00015     /**
00016      *  Constructs A-Law CODEC above existing PCM audio interface
00017      */
00018     public AudioCodecUlaw( AudioInterfacePCM audio ) 
00019     {
00020         this.audio = audio;
00021         this.sampleSize = this.audio.getSampleSize ();
00022         this.outputPcmBuf = new byte[ this.sampleSize ];
00023         this.inputPcmBuf = new byte[ this.sampleSize ];
00024     }
00025 
00026     /**
00027      * Gets the VoicePDU subclass attribute of the AbstractAudio object
00028      */
00029     public int getVoicePduSubclass () 
00030     {
00031         return protocol.VoicePDU.ULAW;
00032     }
00033 
00034     /**
00035      *  Returns the minimum sample size for use in creating buffers etc.
00036      */
00037     public int getSampleSize ()
00038     {
00039         return 160;
00040     }
00041 
00042     /**
00043      *  Encodes data to PCM, i.e. converts samples from u-Law to CODEC format.
00044      */
00045     public void convertToPCM( byte[] in, byte[] out )
00046     {
00047         OctetBuffer bb = OctetBuffer.wrap(out);
00048         for (int i = 0; i < in.length; i++) {
00049           bb.putShort( ulaw2linear( in[i] ) );
00050         }
00051     }
00052 
00053     /**
00054      *  Decodes data from PCM, i.e. converts samples from u-Law to PCM format.
00055      */
00056     public void convertFromPCM( byte[] in, byte[] out )
00057     {
00058         OctetBuffer bb = OctetBuffer.wrap(in);
00059         for ( int i = 0; i < out.length; ++i )
00060         {
00061             out[i] = linear2ulaw( bb.getShort () );
00062         }
00063     }
00064 
00065     ///////////////////////////////////////////////////////////// ALGORITHM //////////////
00066     /*
00067      *  Craig Reese: IDA/Supercomputing Research Center
00068      *  Joe Campbell: Department of Defense
00069      *  29 September 1989
00070      * 
00071      *  References:
00072      *  1) CCITT Recommendation G.711  (very difficult to follow)
00073      *  2) "A New Digital Technique for Implementation of Any
00074      *      Continuous PCM Companding Law," Villeret, Michel,
00075      *      et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
00076      *      1973, pg. 11.12-11.17
00077      *  3) MIL-STD-188-113,"Interoperability and Performance Standards
00078      *      for Analog-to_Digital Conversion Techniques,"
00079      *      17 February 1987
00080      */
00081 
00082     private static final boolean ZEROTRAP = true;
00083     private static final short   BIAS = 0x84;
00084     private static final int     CLIP = 32635;
00085     
00086     private static final int exp_lut1 [] = 
00087     {
00088         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
00089         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00090         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00091         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00092         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00093         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00094         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00095         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00096         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00097         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00098         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00099         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00100         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00101         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00102         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00103         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
00104     };
00105 
00106     /**
00107      * Converts a linear signed 16bit sample to a uLaw byte.
00108      */
00109     public static byte linear2ulaw( int sample )
00110     {
00111         int sign, exponent, mantissa, ulawbyte;
00112 
00113         if ( sample > 32767 ) {
00114             sample = 32767;
00115         }
00116         else if ( sample < -32768 ) {
00117             sample = -32768;
00118             /* Get the sample into sign-magnitude. */
00119         }
00120         
00121         sign = (sample >> 8) & 0x80; /* set aside the sign */
00122         if ( sign != 0 ) {
00123             sample = -sample; /* get magnitude */
00124         }
00125         
00126         if ( sample > CLIP ) {
00127             sample = CLIP; /* clip the magnitude */
00128             /* Convert from 16 bit linear to ulaw. */
00129         }
00130         
00131         sample = sample + BIAS;
00132         exponent = exp_lut1[ (sample >> 7) & 0xFF];
00133         mantissa = (sample >> (exponent + 3)) & 0x0F;
00134         ulawbyte = ~ (sign | (exponent << 4) | mantissa);
00135         
00136         if ( ZEROTRAP ) {
00137             if ( ulawbyte == 0 ) {
00138                 ulawbyte = 0x02; /* optional CCITT trap */
00139             }
00140         }
00141         
00142         return (byte) ulawbyte;
00143     }
00144 
00145     /* u-Law to linear conversion table
00146      */
00147     private static short[] ulaw2lin_table = 
00148     {
00149         -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
00150         -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
00151         -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
00152         -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
00153          -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
00154          -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
00155          -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
00156          -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
00157          -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
00158          -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
00159           -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
00160           -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
00161           -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
00162           -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
00163           -120,   -112,   -104,    -96,    -88,    -80,   - 72,    -64,
00164            -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
00165          32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
00166          23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
00167          15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
00168          11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
00169           7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
00170           5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
00171           3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
00172           2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
00173           1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
00174           1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
00175            876,    844,    812,    780,    748,    716,    684,    652,
00176            620,    588,    556,    524,    492,    460,    428,    396,
00177            372,    356,    340,    324,    308,    292,    276,    260,
00178            244,    228,    212,    196,    180,    164,    148,    132,
00179            120,    112,    104,     96,     88,     80,     72,     64,
00180             56,     48,     40,     32,     24,     16,      8,      0
00181     };
00182     
00183     /**
00184      *  Converts an 8-bit u-law value to 16-bit linear PCM
00185      */
00186     public static short ulaw2linear( byte ulawbyte )
00187     {
00188         return ulaw2lin_table[ ulawbyte & 0xFF ];
00189     }
00190 }

Generated on Thu Dec 16 2010 14:44:42 for VoIP Kryptofon by  doxygen 1.7.2