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


/* celp_fxp.c */ 
 
/**********************/ 
/* CELP-CODEC (FIXED) */ 
/* for Secure-Phone   */ 
/* Version 1.01,20.12 */ 
/* (C) 2002 by NAH6   */ 
/**********************/ 
 
  // how to profile this code: 
  // 
  // uncomment the following line, and link with profiling enabled codec 
  //     ( compiled with '-pg' and without '-fomit-frame-pointer' ) 
 
  //  #define _USE_PROFILER 
 
  // make sure you don't compile the profiling code with profiling enabled!! 
  // the profiling code consists of 2 objects: mcount.o and mcountinit.o 
 
  // profiling information is gathered while using the codec ( = making a call ) 
  // 
  //  to get the profiling data, the 'secure phone.exe' app must be restarted, 
  //  (this makes the machine call codec_enc_destroy, which then writes \gmon.out ) 
  // 
  //  a perl script exists (gmon.pl) which reads the profiling data, combines it with 
  //  the corresponding map file, and outputs percentages of times spent in all functions. 
 
 
/*------------*/ 
/*  INCLUDES  */ 
/*------------*/ 
 
#include  
 
#include "celp_fxp.h" 
 
/*-----------*/ 
/*  DEFINES  */ 
/*-----------*/ 
 
#define CELP_FRAME_LENGTH   (240) 
#define CELP_WIREREP_BITS   (144) 
#define CELP_WIREREP_BYTES   (18) 
 
/*--------------*/ 
/*  PROTOTYPES  */ 
/*--------------*/ 
 
extern void celp_init   (void); 
extern void celp_encode (unsigned char *data, const signed short *audio); 
extern void celp_decode (signed short *audio, const unsigned char *data); 
 
extern void ACBGainEncode (void); 
 
/*-------------*/ 
/*  VARIABLEN  */ 
/*-------------*/ 
 
static HINSTANCE codec_inst; 
 
static LONG      codec_enc_free; 
static int       codec_enc_frame; 
 
static LONG      codec_dec_free; 
static int       codec_dec_frame; 
 
/************************************************************************** 
*                                                                         * 
*       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 [4200] */ 
BOOL APIENTRY DllMain (HINSTANCE inst, DWORD reason, LPVOID reserved) 
{ 
  BOOL b; 
 
  if (reason == DLL_PROCESS_ATTACH) 
  { 
    b = DisableThreadLibraryCalls ((HMODULE)inst); 
    if (!b) 
      return FALSE; 
    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; 
} 
 
/*----*/ 
 
void abort (void)                                              /* Codec-Abort */ 
{ 
  RaiseException (0xFFFFFFFFL, EXCEPTION_NONCONTINUABLE, 0L, NULL); 
  while (42) {} 
} 
 
/*-------------*/ 
/*  API-CALLS  */ 
/*-------------*/ 
                                                     /* Get Codec-Info [4201] */ 
EXPORT signed short CALLBACK codec_getinfo (struct codec_info *info) 
{ 
  /* Check pointer */ 
  if (info == NULL) 
    return E_CELP_FXP_NULLPTR; 
 
  /* Write info */ 
  FillMemory (info, sizeof (struct codec_info), 0x00); 
  info->magic = K_CELP_FXP_MAGIC; 
  info->ifver = K_CELP_FXP_IFVER; 
  info->ifrev = K_CELP_FXP_IFREV; 
  info->ifopt = K_CELP_FXP_IFOPT; 
  info->enc_mask[0] = 0x40; 
  info->dec_mask[0] = 0x40; 
  info->code = (void *)ACBGainEncode; 
  return 0; 
} 
 
/*----*/ 
                                                       /* Get Revision [4202] */ 
EXPORT signed short CALLBACK codec_getrev (unsigned char codec) 
{ 
  /* Check codec */ 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
  /* Return revision */ 
  return K_CELP_FXP_REV0; 
} 
 
/*----------------------------------------------------------------------------*/ 
#ifdef _USE_PROFILER 
void monexit(); 
void monstartup(int ndepth, int nentries); 
int mon_initialized= 0; 
#endif 
 
#ifdef DEBUG_CELP 
FILE *f_audioin; 
FILE *f_audioout; 
FILE *f_celpin; 
FILE *f_celpout; 
#endif 
/*-----------*/ 
/*  ENCODER  */ 
/*-----------*/ 
                                                       /* Open Encoder [4210] */ 
EXPORT signed short CALLBACK codec_enc_create (unsigned char codec,            \ 
                                               void **state) 
{ 
  LONG d; 
 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FXP_NULLPTR; 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
  /* Check unused */ 
  d = InterlockedExchange (&codec_enc_free, 0L); 
  if (!d) 
    return E_CELP_FXP_INUSE; 
 
  /* Init state-ptr */ 
  codec_enc_frame = 1; 
  *state = &codec_enc_frame; 
 
#ifdef DEBUG_CELP 
  f_audioin= fopen("audioin.raw", "w+b"); 
  f_celpout= fopen("celpout.raw", "w+b"); 
#endif 
 
#ifdef _USE_PROFILER 
  if (!mon_initialized) { 
	monstartup(64, 1024); 
	mon_initialized= 1; 
  } 
#endif 
 
  /* Init celp */ 
  celp_init (); 
  return 0; 
} 
 
/*----*/ 
                                                      /* Close Encoder [4211] */ 
EXPORT signed short CALLBACK codec_enc_destroy (unsigned char codec,           \ 
                                                void *state) 
{ 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FXP_NULLPTR; 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
#ifdef _USE_PROFILER 
  if (mon_initialized) { 
	monexit(); 
	mon_initialized= 0; 
  } 
#endif 
 
#ifdef DEBUG_CELP 
  fclose(f_audioin); 
  fclose(f_celpout); 
#endif 
 
  /* Free encoder */ 
  codec_enc_free = 1L; 
  return 0; 
} 
 
/*====*/ 
                                                     /* Compress Audio [4212] */ 
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 long a,d; 
 
  /* Check arguments */ 
  if ((state == NULL) || (audio == NULL) || (data == NULL) \ 
   || (alen == NULL)  || (dlen == NULL)) 
    return E_CELP_FXP_NULLPTR; 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
  /* Convert data */ 
  a = *alen; 
  d = *dlen; 
  while ((a >= CELP_FRAME_LENGTH) && (d >= CELP_WIREREP_BYTES)) 
  { 
#ifdef DEBUG_CELP 
	fwrite(audio, sizeof(short), CELP_FRAME_LENGTH, f_audioin); 
#endif 
    /* Compress frame */ 
    celp_encode (data, audio); 
#ifdef DEBUG_CELP 
	fwrite(data, 1, CELP_WIREREP_BYTES, f_celpout); 
#endif 
 
    audio += CELP_FRAME_LENGTH; 
    data  += CELP_WIREREP_BYTES; 
    a -= CELP_FRAME_LENGTH; 
    d -= CELP_WIREREP_BYTES; 
    codec_enc_frame++; 
  } 
  *alen = *alen - a; 
  *dlen = *dlen - d; 
  return 0; 
} 
 
/*----------------------------------------------------------------------------*/ 
 
/*-----------*/ 
/*  DECODER  */ 
/*-----------*/ 
                                                       /* Open Decoder [4220] */ 
EXPORT signed short CALLBACK codec_dec_create (unsigned char codec,            \ 
                                               void **state) 
{ 
  LONG d; 
 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FXP_NULLPTR; 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
  /* Check unused */ 
  d = InterlockedExchange (&codec_dec_free, 0L); 
  if (!d) 
    return E_CELP_FXP_INUSE; 
 
  /* Init state-ptr */ 
  codec_dec_frame = 1; 
  *state = &codec_dec_frame; 
 
#ifdef DEBUG_CELP 
  f_audioout= fopen("audioout.raw", "w+b"); 
  f_celpin= fopen("celpin.raw", "w+b"); 
#endif 
 
#ifdef _USE_PROFILER 
  if (!mon_initialized) { 
	monstartup(64, 1024); 
	mon_initialized= 1; 
  } 
#endif 
 
  /* Init celp */ 
  celp_init (); 
  return 0; 
} 
 
/*----*/ 
                                                      /* Close Decoder [4221] */ 
EXPORT signed short CALLBACK codec_dec_destroy (unsigned char codec,           \ 
                                                void *state) 
{ 
  /* Check arguments */ 
  if (state == NULL) 
    return E_CELP_FXP_NULLPTR; 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
#ifdef DEBUG_CELP 
  fclose(f_audioout); 
  fclose(f_celpin); 
#endif 
 
#ifdef _USE_PROFILER 
  if (mon_initialized) { 
	monexit(); 
	mon_initialized= 0; 
  } 
#endif 
 
  /* Free decoder */ 
  codec_dec_free = 1L; 
  return 0; 
} 
 
/*====*/ 
                                                       /* Expand Audio [4222] */ 
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 long a,d; 
 
  /* Check arguments */ 
  if ((state == NULL) || (data == NULL) || (audio == NULL) \ 
   || (dlen == NULL)  || (alen == NULL)) 
    return E_CELP_FXP_NULLPTR; 
  if (codec != K_CELP_FXP_ID0) 
    return E_CELP_FXP_CODEC; 
 
  /* Convert data */ 
  d = *dlen; 
  a = *alen; 
  while ((d >= CELP_WIREREP_BYTES) && (a >= CELP_FRAME_LENGTH)) 
  { 
#ifdef DEBUG_CELP 
	fwrite(data, 1, CELP_WIREREP_BYTES, f_celpin); 
#endif 
    /* Expand frame */ 
    celp_decode (audio, data); 
#ifdef DEBUG_CELP 
	fwrite(audio, sizeof(short), CELP_FRAME_LENGTH, f_audioout); 
#endif 
 
    data  += CELP_WIREREP_BYTES; 
    audio += CELP_FRAME_LENGTH; 
    d -= CELP_WIREREP_BYTES; 
    a -= CELP_FRAME_LENGTH; 
    codec_dec_frame++; 
  } 
  *dlen = *dlen - d; 
  *alen = *alen - a; 
  return 0; 
} 
 
 
/*** EOF ***/