home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / openh323.tar.gz / openh323.tar / openh323 / src / lpc10codec.cxx < prev    next >
C/C++ Source or Header  |  2003-06-05  |  6KB  |  216 lines

  1. /*
  2.  * lpc10codec.cxx
  3.  *
  4.  * H.323 protocol handler
  5.  *
  6.  * Open H323 Library
  7.  *
  8.  * Copyright (c) 1998-2000 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Open H323 Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Contributor(s): ______________________________________.
  25.  *
  26.  * $Log: lpc10codec.cxx,v $
  27.  * Revision 1.11  2003/06/05 23:44:20  rjongbloed
  28.  * Minor optimisations. Extremely minor.
  29.  *
  30.  * Revision 1.10  2003/04/27 23:51:19  craigs
  31.  * Fixed possible problem with context deletion
  32.  *
  33.  * Revision 1.9  2002/09/03 06:01:16  robertj
  34.  * Added globally accessible functions for media format name.
  35.  *
  36.  * Revision 1.8  2002/08/05 10:03:48  robertj
  37.  * Cosmetic changes to normalise the usage of pragma interface/implementation.
  38.  *
  39.  * Revision 1.7  2001/09/21 02:51:29  robertj
  40.  * Added default session ID to media format description.
  41.  *
  42.  * Revision 1.6  2001/05/14 05:56:28  robertj
  43.  * Added H323 capability registration system so can add capabilities by
  44.  *   string name instead of having to instantiate explicit classes.
  45.  *
  46.  * Revision 1.5  2001/02/09 05:13:56  craigs
  47.  * Added pragma implementation to (hopefully) reduce the executable image size
  48.  * under Linux
  49.  *
  50.  * Revision 1.4  2001/01/25 07:27:16  robertj
  51.  * Major changes to add more flexible OpalMediaFormat class to normalise
  52.  *   all information about media types, especially codecs.
  53.  *
  54.  * Revision 1.3  2000/07/12 10:25:37  robertj
  55.  * Renamed all codecs so obvious whether software or hardware.
  56.  *
  57.  * Revision 1.2  2000/06/17 04:09:49  craigs
  58.  * Fixed problem with (possibly bogus) underrun errors being reported in debug mode
  59.  *
  60.  * Revision 1.1  2000/06/05 04:45:11  robertj
  61.  * Added LPC-10 2400bps codec
  62.  *
  63.  */
  64.  
  65. #include <ptlib.h>
  66.  
  67. #ifdef __GNUC__
  68. #pragma implementation "lpc10codec.h"
  69. #endif
  70.  
  71. #include "lpc10codec.h"
  72.  
  73. #include "rtp.h"
  74.  
  75. extern "C" {
  76. #include "lpc10/lpc10.h"
  77. };
  78.  
  79.  
  80. #define new PNEW
  81.  
  82.  
  83. enum {
  84.   SamplesPerFrame = 180,    // 22.5 milliseconds
  85.   BitsPerFrame = 54,        // Encoded size
  86.   BytesPerFrame = (BitsPerFrame+7)/8
  87. };
  88.  
  89.  
  90. #define H323_NAME OPAL_LPC10 "{sw}"
  91.  
  92.  
  93. H323_REGISTER_CAPABILITY_EP(H323_LPC10Capability, H323_NAME);
  94.  
  95. OpalMediaFormat const OpalLPC10(OPAL_LPC10,
  96.                                 OpalMediaFormat::DefaultAudioSessionID,
  97.                                 RTP_DataFrame::LPC,
  98.                                 TRUE,  // Needs jitter
  99.                                 2400,  // bits/sec
  100.                                 BytesPerFrame,
  101.                                 SamplesPerFrame,
  102.                                 OpalMediaFormat::AudioTimeUnits);
  103.  
  104.  
  105. H323_LPC10Capability::H323_LPC10Capability(H323EndPoint & endpoint)
  106.   : H323NonStandardAudioCapability(7, 4, endpoint,
  107.                                    (const BYTE *)(const char *)OpalLPC10,
  108.                                    OpalLPC10.GetLength())
  109. {
  110. }
  111.  
  112.  
  113. PObject * H323_LPC10Capability::Clone() const
  114. {
  115.   return new H323_LPC10Capability(*this);
  116. }
  117.  
  118.  
  119. PString H323_LPC10Capability::GetFormatName() const
  120. {
  121.   return H323_NAME;
  122. }
  123.  
  124.  
  125. H323Codec * H323_LPC10Capability::CreateCodec(H323Codec::Direction direction) const
  126. {
  127.   return new H323_LPC10Codec(direction);
  128. }
  129.  
  130.  
  131. /////////////////////////////////////////////////////////////////////////////
  132.  
  133. H323_LPC10Codec::H323_LPC10Codec(Direction dir)
  134.   : H323FramedAudioCodec(OpalLPC10, dir)
  135. {
  136.   if (dir == Encoder) {
  137.     decoder = NULL;
  138.     encoder = (struct lpc10_encoder_state *)malloc((unsigned)sizeof(struct lpc10_encoder_state));
  139.     if (encoder != 0) 
  140.       ::init_lpc10_encoder_state(encoder);
  141.   }
  142.   else {
  143.     encoder = NULL;
  144.     decoder = (struct lpc10_decoder_state *)malloc((unsigned)sizeof(struct lpc10_decoder_state));
  145.     if (decoder != 0) 
  146.       ::init_lpc10_decoder_state(decoder);
  147.   }
  148.  
  149.   PTRACE(3, "Codec\tLPC-10 " << (dir == Encoder ? "en" : "de")
  150.          << "coder created");
  151. }
  152.  
  153.  
  154. H323_LPC10Codec::~H323_LPC10Codec()
  155. {
  156.   if (encoder != NULL)
  157.     free(encoder);
  158.   if (decoder != NULL)
  159.     free(decoder);
  160. }
  161.  
  162.  
  163. const real SampleValueScale = 32768.0;
  164. const real MaxSampleValue = 32767.0;
  165. const real MinSampleValue = -32767.0;
  166.  
  167. BOOL H323_LPC10Codec::EncodeFrame(BYTE * buffer, unsigned &)
  168. {
  169.   PINDEX i;
  170.  
  171.   real speech[SamplesPerFrame];
  172.   for (i = 0; i < SamplesPerFrame; i++)
  173.     speech[i] = sampleBuffer[i]/SampleValueScale;
  174.  
  175.   INT32 bits[BitsPerFrame];
  176.   lpc10_encode(speech, bits, encoder);
  177.  
  178.   memset(buffer, 0, BytesPerFrame);
  179.   for (i = 0; i < BitsPerFrame; i++) {
  180.     if (bits[i])
  181.       buffer[i>>3] |= 1 << (i&7);
  182.   }
  183.  
  184.   return TRUE;
  185. }
  186.  
  187.  
  188. BOOL H323_LPC10Codec::DecodeFrame(const BYTE * buffer, unsigned length, unsigned &)
  189. {
  190.   if (length < BytesPerFrame)
  191.     return FALSE;
  192.  
  193.   PINDEX i;
  194.  
  195.   INT32 bits[BitsPerFrame];
  196.   for (i = 0; i < BitsPerFrame; i++)
  197.     bits[i] = (buffer[i>>3]&(1<<(i&7))) != 0;
  198.  
  199.   real speech[SamplesPerFrame];
  200.   lpc10_decode(bits, speech, decoder);
  201.  
  202.   for (i = 0; i < SamplesPerFrame; i++) {
  203.     real sample = speech[i]*SampleValueScale;
  204.     if (sample < MinSampleValue)
  205.       sample = MinSampleValue;
  206.     else if (sample > MaxSampleValue)
  207.       sample = MaxSampleValue;
  208.     sampleBuffer[i] = (short)sample;
  209.   }
  210.  
  211.   return TRUE;
  212. }
  213.  
  214.  
  215. /////////////////////////////////////////////////////////////////////////////
  216.