📄 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 <math.h>
#include <string.h>
#include <windows.h>
#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<F_LEN; x++)
*pf++ = *audio++;
/* Analyze input speech and calculate parameters */
Analysis (codec_enc_in, &codec_enc_par, codec_enc_frame);
/* Put analysis parameters into bitstream */
EncodeParameters (codec_enc_par, CELP_BITS, NULL, FALSE, codec_enc_frame, \
&codec_enc_out);
/* Pack bits */
pi = codec_enc_out;
for (x=0; x<(CELP_BITS>>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<F_LEN; x++)
{
f = *pf++;
if (f > 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 ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -