sl@0: // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "rpeltp.h" sl@0: #include "codec.h" sl@0: #include "gsm610fr.h" sl@0: sl@0: /* sl@0: ** LPC analysis part of the RPE-LTP-coder sl@0: ** sl@0: ** Input: sl@0: ** sop[0..159] sl@0: ** unprocessed sample frame sl@0: ** Output: sl@0: ** d[0..159] sl@0: ** residual sl@0: ** LARc[0..7] sl@0: ** coded reflection coefficients sl@0: ** *SP_flag: sl@0: ** decision of tx DTX (boolean) sl@0: ** *VAD_flag: sl@0: ** decision of VAD (boolean) sl@0: ** sl@0: ** Return value: sl@0: ** None sl@0: */ sl@0: void LPC_analysis(CGSM610FR_Encoder* aEncoder, int2 ibuf[], struct codes *ecodes) sl@0: { sl@0: sl@0: int4 L_ACF[9]; sl@0: int2 LAR[8]; /* used for r[], LAR[], LARpp */ sl@0: int2 rp[8]; /* used for LARp[], rp[] */ sl@0: // int2 scalauto; /* returned from autoc to be used by vad */ sl@0: sl@0: sl@0: prepr( aEncoder, ibuf, ibuf ); /* sof <- so */ sl@0: preemp( aEncoder, ibuf, ibuf ); /* s <- sof */ sl@0: // scalauto = autoc( L_ACF, ibuf ); /* L_ACF <- , s <- s */ sl@0: autoc( L_ACF, ibuf ); /* L_ACF <- , s <- s */ sl@0: sl@0: /* sl@0: ** VAD decision could be computed here when L_ACF and scalauto are available. sl@0: ** In current version vad is executed after LAR computation sl@0: */ sl@0: sl@0: schur( LAR, L_ACF ); /* r <- L_ACF */ sl@0: sl@0: larcomp( LAR, LAR ); /* LAR <- r */ sl@0: sl@0: codlar( ecodes->LARc, LAR ); /* LARc <- LAR */ sl@0: declar( LAR, ecodes->LARc ); /* LARpp <- LARc */ sl@0: sl@0: cparc1( rp, aEncoder->LARpp_prev, LAR ); /* LARp <- LARpp_prev, LARpp */ sl@0: crp( rp, rp ); /* rp <- LARp */ sl@0: invfil( aEncoder, ibuf, ibuf, rp, 0, 12 ); /* d <- s */ sl@0: sl@0: cparc2( rp, aEncoder->LARpp_prev, LAR ); /* LARp <- LARpp_prev, LARpp */ sl@0: crp( rp, rp ); /* rp <- LARp */ sl@0: invfil( aEncoder, ibuf, ibuf, rp, 13, 26 ); /* d <- s */ sl@0: sl@0: cparc3( rp, aEncoder->LARpp_prev, LAR ); /* LARp <- LARpp_prev, LARpp */ sl@0: crp( rp, rp ); /* rp <- LARp */ sl@0: invfil( aEncoder, ibuf, ibuf, rp, 27, 39 ); /* d <- s*/ sl@0: sl@0: cparc4( rp, aEncoder->LARpp_prev, LAR ); /* LARp <- LARpp_prev, LARpp */ sl@0: crp( rp, rp ); /* rp <- LARp */ sl@0: invfil( aEncoder, ibuf, ibuf, rp, 40, 159 ); /* d <- s */ sl@0: return; sl@0: } sl@0: sl@0: /* sl@0: ** Encoding of the residual signal of the LPC analysis filter sl@0: ** Input: sl@0: ** sl@0: ** d[k_start..k_start+39] sl@0: ** LPC residual (output of LPC analysis filter) sl@0: ** sl@0: ** Output: sl@0: ** sl@0: ** bc, Nc sl@0: ** encoded LTP parameters (gain and lag) sl@0: ** xmaxc sl@0: ** block maximum of the encoded subframe. sl@0: ** xMc[0..12] sl@0: ** coded normalized RPE pulses sl@0: ** sl@0: ** return xmax for SID computation sl@0: */ sl@0: int2 residual_encoder( CGSM610FR_Encoder* aEncoder, int sf_nro, int2 d[], struct sfcodes *sfc ) sl@0: { sl@0: int k_start; sl@0: int2 xmax; /* return value */ sl@0: sl@0: /* Note: d[] is used also for for x[] and e[] */ sl@0: sl@0: int2 xM[13]; /* used for xM[], xMp[] */ sl@0: /* xM[] is required simultaneously with xMc because LTP sl@0: * also decodes xMc sl@0: */ sl@0: int2 dpp[40]; /* required simultaneously with ep[] that is sl@0: * stored into d[] sl@0: */ sl@0: int2 Exp; sl@0: int2 mant; sl@0: sl@0: k_start = sf_nro * 40; sl@0: sl@0: ltpcomp( aEncoder, &(sfc->Nc), &(sfc->bc), d, k_start ); sl@0: ltpfil( aEncoder, &d[k_start], dpp, d, sfc->bc, sfc->Nc, k_start ); /* e, dpp <- d */ sl@0: weight( &d[k_start], &d[k_start] ); /* x <- e */ sl@0: sfc->Mc = gridsel( xM, &d[k_start] ); /* xM <- x */ sl@0: sl@0: /* sl@0: ** quatize residual and store unquantized xmax for SID sl@0: ** computation sl@0: */ sl@0: xmax = apcm( &(sfc->xmaxc), xM, sfc->xMc, &Exp, &mant); sl@0: /* EXP, mant computed int APCM */ sl@0: sl@0: iapcm( xM, sfc->xMc, Exp, mant ); /* xMp <- xMc */ sl@0: gridpos( &d[k_start], xM, sfc->Mc ); /* ep <- xMc,Mc */ sl@0: ltpupd( aEncoder, dpp, &d[k_start] ); /* dp <- dpp, x */ sl@0: sl@0: return( xmax ); sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** Decoding of the coded LPC-residual sl@0: ** sl@0: ** Input: sl@0: ** xmaxcr sl@0: ** coded block maxmimum sl@0: ** xMcr[0..12] sl@0: ** coded normalized RPE pulses sl@0: ** sl@0: ** Output: sl@0: ** drp[k_start..k_start+39] sl@0: ** decoded LPC residual (input signal for LPC-synthesis filter) sl@0: */ sl@0: void residual_decoder(CGSM610FR_Decoder* aDecoder, int sf_nro, struct sfcodes *sfc, int2 wt[]) sl@0: { sl@0: int k_start; sl@0: sl@0: int2 EXP; sl@0: int2 mant; sl@0: int2 xMrp[13]; sl@0: int2 erp[40]; sl@0: sl@0: k_start = sf_nro * 40; sl@0: sl@0: /* in decoder EXP ja mant must be computed from xmaxcr */ sl@0: expman( &EXP, &mant, sfc->xmaxc ); /* EXP, mant <- xmaxc */ sl@0: iapcm( xMrp, sfc->xMc, EXP, mant ); /* xMrp <- xMc */ sl@0: gridpos( erp, xMrp, sfc->Mc ); /* erp <- xMc,Mc */ sl@0: sl@0: ltpsyn( aDecoder, erp, &wt[k_start], sfc->bc, sfc->Nc ); sl@0: } sl@0: sl@0: /* sl@0: ** LPC synthesis part of the RPE-LTP-coder sl@0: ** sl@0: ** Input: sl@0: ** LARcr[0..7] sl@0: ** coded reflection coefficients sl@0: ** wt[0..159] sl@0: ** decoded residual sl@0: ** sl@0: ** Output: sl@0: ** srop[0..159] sl@0: ** decoded speech sl@0: */ sl@0: void LPC_synthesis(CGSM610FR_Decoder* aDecoder, struct codes *dcodes, int2 wt[], int2 obuf[]) sl@0: { sl@0: int2 LARr[8]; /* used for LARr[], LARpp */ sl@0: int2 rrp[8]; /* used for LARp[], rrp[] */ sl@0: sl@0: declar(LARr, dcodes->LARc); /* LARrpp <- LARc */ sl@0: sl@0: cparc1( rrp, aDecoder->LARrpp_prev, LARr ); /* LARp <- LARrpp_prev, LARr */ sl@0: crp( rrp, rrp ); /* rrp <- LARp */ sl@0: synfil( aDecoder, obuf, wt, rrp, 0, 12 ); /* sr <- wt */ sl@0: sl@0: cparc2( rrp, aDecoder->LARrpp_prev, LARr ); /* LARp <- LARrpp_prev, LARr */ sl@0: crp( rrp, rrp ); /* rrp <- LARp */ sl@0: synfil( aDecoder, obuf, wt, rrp, 13, 26 ); /* sr <- wt */ sl@0: sl@0: cparc3( rrp, aDecoder->LARrpp_prev, LARr ); /* LARp <- LARrpp_prev, LARr */ sl@0: crp( rrp, rrp ); /* rrp <- LARp */ sl@0: synfil( aDecoder, obuf, wt, rrp, 27, 39 ); /* sr <- wt */ sl@0: sl@0: cparc4( rrp, aDecoder->LARrpp_prev, LARr ); /* LARp <- LARrpp_prev, LARr */ sl@0: crp( rrp, rrp ); /* rrp <- LARp */ sl@0: synfil( aDecoder, obuf, wt, rrp, 40, 159 ); /* sr <- wt */ sl@0: postpr( aDecoder, obuf, obuf ); sl@0: /* combines deemphasis, upscaling and truncation */ sl@0: sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** RPE-LTP Encoder sl@0: ** sl@0: ** void RPELTP_encoder(CGSM610FR_Encoder* aEncoder, int2 ibuf[], struct codes *ecodes) sl@0: ** sl@0: ** Input: sl@0: ** ibuf[0..159] sl@0: ** Original speech to be coded sl@0: ** sl@0: ** Output: sl@0: ** ecodes sl@0: ** encoded speech stored as codewords sl@0: */ sl@0: void RPELTP_encoder(CGSM610FR_Encoder* aEncoder, int2 ibuf[], struct codes *ecodes) sl@0: { sl@0: int i; sl@0: // int2 xmax[4]; /* collect unquantized xmax data for dtx */ sl@0: sl@0: LPC_analysis( aEncoder, ibuf, ecodes ); sl@0: for (i = 0; i < 4; i++) sl@0: // xmax[i] = residual_encoder( aEncoder, i, ibuf, &(ecodes->sfc[i]) ); sl@0: residual_encoder( aEncoder, i, ibuf, &(ecodes->sfc[i]) ); sl@0: } sl@0: sl@0: sl@0: /* sl@0: ** RPE-LTP Decoder sl@0: ** sl@0: ** void RPELTP_decoder(struct codes *dcodes, int2 obuf[]) sl@0: ** Input: sl@0: ** dcodes sl@0: ** encoded speech stored as codewords to be decoded sl@0: ** sl@0: ** Output: sl@0: ** obuf[0..159] sl@0: ** Decoded speech sl@0: */ sl@0: void RPELTP_decoder(CGSM610FR_Decoder* aDecoder, struct codes *dcodes, int2 obuf[]) sl@0: { sl@0: int i; sl@0: sl@0: dcodes->LARc[0] &= 0x7fff; /* VAD flag in sequences */ sl@0: dcodes->LARc[1] &= 0x7fff; /* SP flag in sequences */ sl@0: sl@0: for (i = 0; i < 4; i++) sl@0: residual_decoder(aDecoder, i, &(dcodes->sfc[i]), obuf); /* -> wt */ sl@0: sl@0: LPC_synthesis(aDecoder, dcodes, obuf, obuf); /* wt -> srop */ sl@0: } sl@0: