www.pudn.com > CryptoPhone-src-031122.zip > celp_flp.c


/* Copyright 2001,2002,2003 NAH6 
 * All Rights Reserved 
 * 
 * Parts Copyright DoD, Parts Copyright Starium 
 * 
 */ 
/* celp_flp.c */ 
 
/**********************/ 
/* CELP-CODEC (FLOAT) */ 
/* for Crypto-Phone   */ 
/* (C) 2002 by NAH6   */ 
/**********************/ 
 
/*------------*/ 
/*  INCLUDES  */ 
/*------------*/ 
 
#include  
#include  
#include  
 
#include "celp_flp.h" 
 
#include "celpfilt.h" 
#include "analysis.h" 
#include "codeparm.h" 
#include "synth.h" 
 
/*-------------*/ 
/*  VARIABLEN  */ 
/*-------------*/ 
 
static HINSTANCE codec_inst; 
 
static LONG      codec_enc_free; 
static int       codec_enc_frame; 
static float     codec_enc_in[F_LEN]; 
static TX_PARAM  codec_enc_par; 
static int      *codec_enc_out; 
 
static LONG      codec_dec_free; 
static int       codec_dec_frame; 
static int       codec_dec_in[CELP_BITS]; 
static TX_PARAM  codec_dec_par; 
static float     codec_dec_out[F_LEN]; 
 
/************************************************************************** 
*                                                                         * 
*	U.S. Department of Defense 			                  * 
*	CELP Voice Coder                                                  * 
*	Version 3.3c	                                                  * 
*	1 June 1994	                                                  * 
*                                                                         * 
*	FOR OFFICIAL U.S. GOVERNMENT CONTRACT USE ONLY                    * 
*									  * 
*	The U.S. Government shall not be held liable for any damages      * 
*	resulting from this code.  Further reproduction or distribution   * 
*	of this code without prior written permission of the U.S.         * 
*	Government is prohibited.  R224 may be contacted at:              * 
*                                                                         * 
*		DIRNSA, R224                                              * 
*		9800 Savage Road                                          * 
*		Fort Meade, MD 20755-6000 USA                             * 
*                                                                         * 
*========================================================================== 
* 
* REFERENCES 
* 
*	"Details to Assist in Implementation of Federal Standard 1016 CELP," 
*	Technical Information Bulletin 92-1, National Communications System, 
*	(included as a Postscript file in CELP 3.3 Release) 
* 
*	"Federal Standard 1016," Telecommunications: Analog-to-Digital  
*	Conversion of Voice by 4800 bit/second Code Excited Linear 
*	Predictive (CELP) Coding, National Communications System, distributed 
*	by the General Services Administration: 
*	    GSA Federal Supply Service Bureau 
*	    Specification Section, Suite 8100 
*	    470 E. L'Enfant Place, S.W. 
*	    Washington, DC 20407 
*	    (202)755-0325 
* 
*      Misc: The following articles describe the Federal-Standard-1016 
*       4.8-kbps CELP coder (it's unnecessary to read more than one): 
*          + Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. 
*            Welch, "The Federal Standard 1016 4800 bps CELP Voice Coder," 
*            Digital Signal Processing, Academic Press, 1991, Vol. 1, No. 
*            3, p. 145-155. 
*          + Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. 
*            Welch, "The DoD 4.8 kbps Standard (Proposed Federal Standard 
*            1016)," in Advances in Speech Coding, ed. Atal, Cuperman and 
*            Gersho, Kluwer Academic Publishers, 1991, Chapter 12, p. 
*            121-133. 
*          + Campbell, Joseph P. Jr., Thomas E. Tremain and Vanoy C. 
*            Welch, "The Proposed Federal Standard 1016 4800 bps Voice 
*            Coder: CELP," Speech Technology Magazine, April/May 1990, p. 
*            58-64. 
*	    
* 
* 
*******************************************************************************/ 
 
/*-------------*/ 
/*  WIN-ENTRY  */ 
/*-------------*/ 
                                                             /* Windows-Entry */ 
BOOL APIENTRY DllMain (HINSTANCE inst, DWORD reason, LPVOID reserved) 
{ 
  if (reason == DLL_PROCESS_ATTACH) 
  { 
    codec_inst = inst; 
    codec_enc_free = 1L; 
    codec_dec_free = 1L; 
  } 
  else if (reason == DLL_PROCESS_DETACH) 
  { 
    codec_inst = NULL; 
    codec_enc_free = 0L; 
    codec_dec_free = 0L; 
  } 
  return TRUE; 
} 
 
/*-------------*/ 
/*  API-CALLS  */ 
/*-------------*/ 
                                                            /* Get Codec-Info */ 
EXPORT signed short CALLBACK codec_getinfo (struct codec_info *info) 
{ 
  /* Check pointer */ 
  if (info == NULL) 
    return E_CELP_FLP_NULLPTR; 
 
  /* Write info */ 
  memset (info, 0, sizeof (struct codec_info)); 
  info->magic = K_CELP_FLP_MAGIC; 
  info->ifver = K_CELP_FLP_IFVER; 
  info->ifrev = K_CELP_FLP_IFREV; 
  info->ifopt = K_CELP_FLP_IFOPT; 
  info->enc_mask[0] = 0x40; 
  info->dec_mask[0] = 0x40; 
  return 0; 
} 
 
/*----*/ 
                                                              /* Get Revision */ 
EXPORT signed short CALLBACK codec_getrev (unsigned char codec) 
{ 
  /* Check codec */ 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Return revision */ 
  return K_CELP_FLP_REV0; 
} 
 
/*----------------------------------------------------------------------------*/ 
 
/*-----------*/ 
/*  ENCODER  */ 
/*-----------*/ 
                                                              /* Open Encoder */ 
EXPORT signed short CALLBACK codec_enc_create (unsigned char codec,            \ 
                                               void **state) 
{ 
  LONG d; 
 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FLP_NULLPTR; 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Check unused */ 
  d = InterlockedExchange (&codec_enc_free, 0L); 
  if (!d) 
    return E_CELP_FLP_INUSE; 
 
  /* Init state-ptr */ 
  codec_enc_frame = 1; 
  *state = &codec_enc_frame; 
 
  /* Setup Analysis Filters */ 
  /* High Pass filter for input speech */ 
  InputHPFZ = makefilt (InputHPFCoefsZ, InputHPFOrder, InputHPFLength); 
  InputHPFP = makefilt (InputHPFCoefsP, InputHPFOrder, InputHPFLength); 
  /* Variable filters for determination of residual after LP analysis */ 
  LP_ResZ  = makefilt_dynamic (ORDER, RES_LEN); 
  LP_ResP  = makefilt_dynamic (ORDER, RES_LEN); 
  LP_ResP2 = makefilt_dynamic (ORDER, RES_LEN); 
  /* Variable filters for determination of residual after Adaptive analysis */ 
  Adapt_ResZ  = makefilt_dynamic (ORDER, RES_LEN); 
  Adapt_ResP  = makefilt_dynamic (ORDER, RES_LEN); 
  Adapt_ResP2 = makefilt_dynamic (ORDER, RES_LEN); 
  /* Variable filters for updating status of LP and Adaptive residual filters */ 
  Update_ResZ  = makefilt_dynamic (ORDER, RES_LEN); 
  Update_ResP  = makefilt_dynamic (ORDER, RES_LEN); 
  Update_ResP2 = makefilt_dynamic (ORDER, RES_LEN); 
  return 0; 
} 
 
/*----*/ 
                                                             /* Close Encoder */ 
EXPORT signed short CALLBACK codec_enc_destroy (unsigned char codec,           \ 
                                                void *state) 
{ 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FLP_NULLPTR; 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Free encoder */ 
  codec_enc_free = 1L; 
  return 0; 
} 
 
/*====*/ 
                                                            /* Compress Audio */ 
EXPORT signed short CALLBACK codec_enc_data (unsigned char codec, void *state, \ 
                                             const signed short *audio,        \ 
                                             unsigned char *data,              \ 
                                             unsigned long *alen,              \ 
                                             unsigned long *dlen) 
{ 
  unsigned char b,x,y; 
  unsigned long a,d; 
  const int *pi; 
  float *pf; 
 
  /* Check arguments */ 
  if ((state == NULL) || (audio == NULL) || (data == NULL) \ 
   || (alen == NULL)  || (dlen == NULL)) 
    return E_CELP_FLP_NULLPTR; 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Convert data */ 
  a = *alen; 
  d = *dlen; 
  while ((a >= F_LEN) && (d >= (CELP_BITS>>3))) 
  { 
    /* Integer to float */ 
    pf = codec_enc_in; 
    for (x=0; x>3); x++) 
    { 
      b = 0x00; 
      for (y=0; y<8; y++) 
      { 
        b >>= 1; 
        if (*pi++) 
          b |= 0x80; 
      } 
      *data++ = b; 
    } 
    codec_enc_frame++; 
    a -= F_LEN; 
    d -= (CELP_BITS>>3); 
  } 
  *alen = *alen - a; 
  *dlen = *dlen - d; 
  return 0; 
} 
 
/*----------------------------------------------------------------------------*/ 
 
/*-----------*/ 
/*  DECODER  */ 
/*-----------*/ 
                                                              /* Open Decoder */ 
EXPORT signed short CALLBACK codec_dec_create (unsigned char codec,            \ 
                                               void **state) 
{ 
  LONG d; 
 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FLP_NULLPTR; 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Check unused */ 
  d = InterlockedExchange (&codec_dec_free, 0L); 
  if (!d) 
    return E_CELP_FLP_INUSE; 
 
  /* Init state-ptr */ 
  codec_dec_frame = 1; 
  *state = &codec_dec_frame; 
 
  /* Setup Synthesis Filters */ 
  /* Variable filter for LP synthesis */ 
  LP_Filt = makefilt_dynamic (ORDER, SF_LEN); 
  /* Variable filter for post filter */ 
  PostZ  = makefilt_dynamic (ORDER, SF_LEN); 
  PostZ2 = makefilt_dynamic (1, SF_LEN); 
  PostP  = makefilt_dynamic (ORDER, SF_LEN); 
  /* High Pass filter for output speech */ 
  OutputHPFZ = makefilt (InputHPFCoefsZ, 2, SF_LEN); 
  OutputHPFP = makefilt (InputHPFCoefsP, 2, SF_LEN); 
  return 0; 
} 
 
/*----*/ 
                                                             /* Close Decoder */ 
EXPORT signed short CALLBACK codec_dec_destroy (unsigned char codec,           \ 
                                                void *state) 
{ 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FLP_NULLPTR; 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Free decoder */ 
  codec_dec_free = 1L; 
  return 0; 
} 
 
/*====*/ 
                                                              /* Expand Audio */ 
EXPORT signed short CALLBACK codec_dec_data (unsigned char codec, void *state, \ 
                                             const unsigned char *data,        \ 
                                             signed short *audio,              \ 
                                             unsigned long *dlen,              \ 
                                             unsigned long *alen) 
{ 
  unsigned char b,x,y; 
  unsigned long a,d; 
  const float *pf; 
  float f; 
  int *pi; 
 
  /* Check arguments */ 
  if ((state == NULL) || (data == NULL) || (audio == NULL) \ 
   || (dlen == NULL)  || (alen == NULL)) 
    return E_CELP_FLP_NULLPTR; 
  if (codec != K_CELP_FLP_ID0) 
    return E_CELP_FLP_CODEC; 
 
  /* Convert data */ 
  d = *dlen; 
  a = *alen; 
  while ((d >= (CELP_BITS>>3)) && (a >= F_LEN)) 
  { 
    /* Unpack bits */ 
    pi = codec_dec_in; 
    for (x=0; x<(CELP_BITS>>3); x++) 
    { 
      b = *data++; 
      for (y=0; y<8; y++) 
      { 
        *pi++ = b & 0x01; 
        b >>= 1; 
      } 
    } 
    /* Get parameters from bitstream */ 
    DecodeParameters (codec_dec_in, CELP_BITS, NULL, FALSE, codec_dec_frame, \ 
                      TRUE, &codec_dec_par); 
    /* Synthesize parameters into output speech */ 
    Synthesis (codec_dec_par, codec_dec_frame, codec_dec_out); 
    /* Float to integer */ 
    pf = codec_dec_out; 
    for (x=0; x 32767) 
        f = 32767; 
      else if (f < -32768) 
        f = -32768; 
      *audio++ = (signed short)f; 
    } 
    codec_dec_frame++; 
    d -= (CELP_BITS>>3); 
    a -= F_LEN; 
  } 
  *dlen = *dlen - d; 
  *alen = *alen - a; 
  return 0; 
} 
 
 
/*** EOF ***/