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 ***/