📄 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 <windows.h>
#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 ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -