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