⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
 * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
 * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
 *
 * 68K assembler routines by Curve Software, 6/95. To turn on 68K assembler,
 * #define TARGET_68K.
 */
#include        <stdio.h>
#define NDEBUG
#include        <assert.h>
#include        <stdlib.h>
#include		<string.h>

#include        "gsm.private.h"
#include        "gsm.h"

#ifdef PGP_MACINTOSH
#include "PGPfone.h"
#endif

/*
 * #define BUG_FIX to correct bug in the C version of Short_term_synthesis_filtering().
 */
#define BUG_FIX

/*
 * Set TARGET_X86 for 80x86 assembler routines.
 */
#ifdef PGP_WIN32
#define TARGET_X86
#endif

#define MIN_WORD        ((-32767)-1)
#define MAX_WORD        ( 32767)

#define MIN_LONGWORD    ((-2147483647L)-1L)
#define MAX_LONGWORD    ( 2147483647L)

#define SASR(x, by)     ((x) >> (by))

#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \
        (SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))

# define GSM_MULT(a,b)   /* word a, word b, !(a == b == MIN_WORD) */  \
        (SASR( ((longword)(a) * (longword)(b)), 15 ))

# define GSM_L_MULT(a, b) /* word a, word b     */                       \
        (((longword)(a) * (longword)(b)) << 1)

#ifdef PGP_WIN32
#define pgpAssert assert
#endif

#ifdef TARGET_X86
# include        "asmcode.h"*/
# define GSM_L_ADD(a, b)        Fgsm_L_add(a, b)
# define GSM_L_SUB(a, b)        Fgsm_L_sub(a,b)
# define GSM_ADD(a, b)          Fgsm_add(a, b)
# define GSM_SUB(a, b)          Fgsm_sub(a, b)
# define GSM_ABS(a)             Fgsm_abs(a)
# define GSM_ST_ANAL_FILT       FShort_term_analysis_filtering
# define GSM_ST_SYNTH_FILT      FShort_term_synthesis_filtering
# define GSM_LTP_LOOP           FLTP_loop_internal
#else
# define GSM_L_ADD(a,b)         gsm_l_add(a,b)
# define GSM_L_SUB(a,b)         gsm_l_sub(a,b)
# define GSM_ADD(a,b)           gsm_add(a,b)
# define GSM_SUB(a,b)           gsm_sub(a,b)
# define GSM_ABS(a)             gsm_abs(a)
# define GSM_ST_ANAL_FILT       Short_term_analysis_filtering
# define GSM_ST_SYNTH_FILT      Short_term_synthesis_filtering
# define GSM_LTP_LOOP           LTP_loop_internal

#ifdef __MC68K__

asm word  gsm_add(word warg1, word warg2)
{
    fralloc+
    move.w warg1,d0
    add.w warg2,d0
    bvc @end
    bmi @pos
    move.w #-0x8000,d0
    bra @end
@pos:
    move.w #0x7FFF, d0
@end:
    frfree
    rts
}

asm word  gsm_sub(word warg1, word warg2)
{
	fralloc+
    move.w warg1,d0
    sub.w warg2, d0
    bvc @end
    bmi @pos
    move.w #-0x8000,d0
    bra @end
@pos:
    move.w #0x7FFF, d0
@end:
	frfree
	rts
}

asm longword  gsm_l_add(longword warg1, longword warg2)
{
	fralloc+
    move.l warg1,d0
    add.l warg2,d0
    bvc @end
    bmi @pos
    move.l #0x8000000,d0
    bra @end
@pos:
    move.l #0x7FFFFFFF, d0
@end:
	frfree
	rts
}

asm longword  gsm_l_sub(longword warg1, longword warg2)
{
    fralloc+
    move.l warg1,d0
    sub.l warg2, d0
    bvc @end
    bmi @pos
    move.l #0x80000000,d0
    bra @end
@pos:
    move.l #0x7FFFFFFF, d0
@end:
    frfree
    rts
}

#else	/*	__MC68K__	*/

static word  gsm_add(word warg1, word warg2) {
  long x;
  x = ((long) warg1) + ((long) warg2);
  if (x<MIN_WORD) return MIN_WORD;
  if (x>MAX_WORD) return MAX_WORD;
  return x;
}

static word  gsm_sub(word warg1, word warg2) {
  long x;
  x = ((long) warg1) - ((long) warg2);
  if (x<MIN_WORD) return MIN_WORD;
  if (x>MAX_WORD) return MAX_WORD;
  return x;
}

static longword  gsm_l_add(longword a, longword b)
{
        if (a < 0) {
                if (b >= 0) return a + b;
                else {
                        ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
                        return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
                }
        }
        else if (b <= 0) return a + b;
        else {
                ulongword A = (ulongword)a + (ulongword)b;
                return A > MAX_LONGWORD ? MAX_LONGWORD : A;
        }
}

static longword  gsm_l_sub(longword a, longword b) {
        if (a >= 0) {
                if (b >= 0) return a - b;
                else {
                        /* a>=0, b<0 */

                        ulongword A = (ulongword)a + -(b + 1);
                        return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
                }
        }
        else if (b <= 0) return a - b;
        else {
                /* a<0, b>0 */

                ulongword A = (ulongword)-(a + 1) + b;
                return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
        }
}


#endif	/*	__MC68K__	*/

static word  gsm_abs(word a)
{
        return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
}

#endif	/*	TARGET_X86	*/

static void Gsm_LPC_Analysis(
        word             * s,           /* 0..159 signals       IN/OUT  */
        word             * LARc);       /* 0..7   LARc's        OUT     */
static void Gsm_Short_Term_Analysis_Filter(
        struct gsm_state * S,
        word    * LARc,         /* coded log area ratio [0..7]  IN      */
        word    * s);           /* signal [0..159]              IN/OUT  */
static void Gsm_Long_Term_Predictor(
        struct gsm_state        * S,
        word    * d,    /* [0..39]   residual signal    IN      */
        word    * dp,   /* [-120..-1] d'                IN      */
        word    * e,    /* [0..39]                      OUT     */
        word    * dpp,  /* [0..39]                      OUT     */
        word    * Nc,   /* correlation lag              OUT     */
        word    * bc);  /* gain factor                  OUT     */
static void Gsm_RPE_Encoding(
        word    * e,            /* -5..-1][0..39][40..44        IN/OUT  */
        word    * xmaxc,        /*                              OUT */
        word    * Mc,           /*                              OUT */
        word    * xMc);         /* [0..12]                      OUT */
static void Gsm_RPE_Decoding(
        word            xmaxcr,
        word            Mcr,
        word            * xMcr,  /* [0..12], 3 bits             IN      */
        word            * erp ); /* [0..39]                     OUT     */
static void Gsm_Long_Term_Synthesis_Filtering(
        struct gsm_state        * S,
        word                    Ncr,
        word                    bcr,
        register word           * erp,          /* [0..39]                IN */
        register word           * drp           /* [-120..-1] IN, [0..40] OUT */
);
static void Gsm_Short_Term_Synthesis_Filter(
        struct gsm_state * S,
        word    * LARcr,        /* received log area ratios [0..7] IN  */
        word    * wt,           /* received d [0..159]             IN  */
        word    * s             /* signal   s [0..159]            OUT  */
);
static void Quantization_and_coding(
        register word * LAR     /* [0..7]       IN/OUT  */
);

static unsigned char bitoff[ 256 ] = {
         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

short gsm_option( gsm r, short opt, short * val)
{
	short 	result = -1;

	switch (opt) {
	case GSM_OPT_LTP_CUT:
#ifdef 	LTP_CUT
		result = r->ltp_cut;
		if (val) r->ltp_cut = *val;
#endif
		break;

	case GSM_OPT_VERBOSE:
#ifndef	NDEBUG
		result = r->verbose;
		if (val) r->verbose = *val;
#endif
		break;

	case GSM_OPT_FAST:

#if	defined(FAST) && defined(USE_FLOAT_MUL)
		result = r->fast;
		if (val) r->fast = !!*val;
#endif
		break;

	default:
		break;
	}
	return result;
}

static word  gsm_norm(longword a )
/*
 * the number of left shifts needed to normalize the 32 bit
 * variable L_var1 for positive values on the interval
 *
 * with minimum of
 * minimum of 1073741824  (01000000000000000000000000000000) and
 * maximum of 2147483647  (01111111111111111111111111111111)
 *
 *
 * and for negative values on the interval with
 * minimum of -2147483648 (-10000000000000000000000000000000) and
 * maximum of -1073741824 ( -1000000000000000000000000000000).
 *
 * in order to normalize the result, the following
 * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
 *
 * (That's 'ffs', only from the left, not the right..)
 */
{
        pgpAssert(a != 0);

        if (a < 0) {
                if (a <= -1073741824L) return 0;
                a = ~a;
        }

        return    a & 0xffff0000L
                ? ( a & 0xff000000L
                  ?  -1 + bitoff[ 0xFF & (a >> 24) ]
                  :   7 + bitoff[ 0xFF & (a >> 16) ] )
                : ( a & 0xff00
                  ?  15 + bitoff[ 0xFF & (a >> 8) ]
                  :  23 + bitoff[ 0xFF & a ] );
}

static word  gsm_asr( word a, int n)
{
        if (n >= 16) return -(a < 0);
        if (n <= -16) return 0;
        if (n < 0) return a << -n;
        return a >> n;
}

static word  gsm_asl(word a, int n)
{
        if (n >= 16) return 0;
        if (n <= -16) return -(a < 0);
        if (n < 0) return gsm_asr(a, -n);
        return a << n;
}

/*
 *  (From p. 46, end of section 4.2.5)
 *
 *  NOTE: The following lines gives [sic] one correct implementation
 *        of the div(num, denum) arithmetic operation.  Compute div
 *        which is the integer division of num by denum: with denum
 *        >= num > 0
 */

static word  gsm_div(word num, word denum)
{
        longword        L_num   = num;
        longword        L_denum = denum;
        word            div     = 0;
        int             k       = 15;

        /* The parameter num sometimes becomes zero.
         * Although this is explicitly guarded against in 4.2.5,
         * we assume that the result should then be zero as well.
         */

        /* assert(num != 0); */

        pgpAssert(num >= 0 && denum >= num);
        if (num == 0)
            return 0;

        while (k--) {
                div   <<= 1;
                L_num <<= 1;

                if (L_num >= L_denum) {
                        L_num -= L_denum;
                        div++;
                }
        }

        return div;
}

/*  4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
 *      CODER AND DECODER
 *
 *      (Most of them inlined, so watch out.)
 */

/*   Table 4.3a  Decision level of the LTP gain quantizer
 */
/*  bc                0         1         2          3                  */
word gsm_DLB[4] = {  6554,    16384,    26214,     32767        };


/*   Table 4.3b   Quantization levels of the LTP gain quantizer
 */
/* bc                 0          1        2          3                  */
static word gsm_QLB[4] = {  3277,    11469,     21299,     32767        };

/*   Table 4.5   Normalized inverse mantissa used to compute xM/xmax
 */
/* i                    0        1    2      3      4      5     6      7   */
static word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };


/*   Table 4.6   Normalized direct mantissa used to compute xM/xmax
 */
/* i                  0      1       2      3      4      5      6      7   */
static word gsm_FAC[8]  = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };

/*      4.2.0 .. 4.2.3  PREPROCESSING SECTION
 *  
 *      After A-law to linear conversion (or directly from the
 *      Ato D converter) the following scaling is assumed for
 *      input to the RPE-LTP algorithm:
 *
 *      in:  0.1.....................12
 *           S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
 *
 *      Where S is the sign bit, v a valid bit, and * a "don't care" bit.
 *      The original signal is called sop[..]
 *
 *      out:   0.1................... 12 
 *           S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
 */


static void Gsm_Preprocess(
        struct gsm_state * S,
        word             * s,
        word             * so )         /* [0..159]     IN/OUT  */
{

        word       z1 = S->z1;
        longword L_z2 = S->L_z2;
        word       mp = S->mp;

        word            s1;
        longword      L_s2;

        longword      L_temp;

        word            msp, lsp;
        word            SO;

/*      longword        ltmp;           /* for   ADD */
/*      ulongword       utmp;           /* for L_ADD */

        register int            k = 160;

        while (k--) {

        /*  4.2.1   Downscaling of the input signal
         */
                SO = SASR( *s, 3 ) << 2;
                s++;

                pgpAssert (SO >= -0x4000); /* downscaled by     */
                pgpAssert (SO <=  0x3FFC); /* previous routine. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -