Ejemplo n.º 1
0
/*********************************************************************
**
** Name:  deqnt_msvq()
**
** Description:
**
**	Dequantization using codebook indices with multi-stages
**
** Arguments:
**
**	int16_t	qout[]	---- (output) quantized data (Q15/Q17)
**	int16_t	codebook[] 	---- codebooks,	 cb[0..numStages-1] (Q15/Q17)
**	int16_t 	tos 	----	the number of stages
**	short	*index	----	codebook index
**
** Return value:	None
**
***********************************************************************/
void deqnt_msvq(int16_t qout[], const int16_t codebook[], int16_t tos,
                const int16_t cb_size[], int16_t index[], int16_t dim)
{
    register int16_t i;
    const int16_t *cdbk_ptr;
    int16_t temp;
    int32_t L_temp;

    /* ====== Clear output ====== */
    v_zap(qout, dim);

    /* ====== Add each stage ====== */
    cdbk_ptr = codebook;
    for (i = 0; i < tos; i++) {
        /*      v_add(qout, cdbk_ptr + index[i]*dim, dim); */
        L_temp = melpe_L_mult(index[i], dim);
        L_temp = melpe_L_shr(L_temp, 1);
        temp = melpe_extract_l(L_temp);
        v_add(qout, cdbk_ptr + temp, dim);
        /*      cdbk_ptr += cb_size[i] * dim; */
        L_temp = melpe_L_mult(cb_size[i], dim);
        L_temp = melpe_L_shr(L_temp, 1);
        temp = melpe_extract_l(L_temp);
        cdbk_ptr += temp;
    }
}
Ejemplo n.º 2
0
/********************************************************************
**
** Function: lspVQ ()
**
** Description:
**		Vector quantizes a set of int term filter coefficients
**		using a multi-stage M-L tree search algorithm.
**
** Arguments:
**
**	int16_t	target[]	: the target coefficients to be quantized (Q15/Q17)
**	int16_t	weight[]	: weights for mse calculation (Q11)
**	int16_t	qout[]		: the output array (Q15/Q17)
**	int16_t	codebook[]	: codebooks,   cb[0..numStages-1] (Q15/Q17)
**	int16_t	tos 		: the number of stages
**  int16_t	cb_size[]	: codebook size (multistages)
**	int16_t	cb_index[]	: codebook indeces; cb_index[0..numStages-1]
**                            (output)
**  int16_t	dim
**  BOOLEAN		flag
**
** Return value:	None
**
***********************************************************************/
static void lspVQ(int16_t target[], int16_t weight[], int16_t qout[],
                  const int16_t codebook[], int16_t tos,
                  const int16_t cb_size[], int16_t cb_index[],
                  int16_t dim, BOOLEAN flag)
{
    register int16_t i, entry;
    register int16_t c1, s1;
    const int16_t *cdbk_ptr, *cdbk_ptr2, *ptr1;
    int16_t index[LSP_VQ_CAND][LSP_VQ_STAGES];
    int16_t nextIndex[LSP_VQ_CAND][LSP_VQ_STAGES];
    int16_t ncPrev;
    int16_t cand[LSP_VQ_CAND][2 * LPC_ORD];
    int16_t max_dMin, dMin[LSP_VQ_CAND], distortion;
    int16_t *cand_target;
    int32_t L_temp;
    int16_t ptr_offset = 0;
    int16_t temp1, temp2;

    /*==================================================================*
    *	Initialize the data before starting the tree search.			*
    *	  - the number of candidates from the "previous" stage is set	*
    *		to 1 since there is no previous stage!						*
    *	  - the candidate vector from the previous stage is set to zero *
    *	  - the list of indeces for each candidate is set to 1			*
    *==================================================================*/
    for (i = 0; i < LSP_VQ_CAND; i++) {
        v_zap(cand[i], dim);
        v_zap(index[i], LSP_VQ_STAGES);
        v_zap(nextIndex[i], LSP_VQ_STAGES);
    }
    cand_target = v_get(dim);
    ncPrev = 1;

    /*==================================================================*
    *	Now we start the search:										*
    *		For each stage												*
    *			For each candidate from the previous stage				*
    *				For each entry in the current stage codebook		*
    *					* add codebook vector to current candidate		*
    *					* compute the distortion with the target		*
    *					* retain candidate if one of the best so far	*
    *==================================================================*/
    cdbk_ptr = codebook;

    /* An observation for lspVQ() shows that if "flag" is FALSE, then we only */
    /* need to keep track of the best one (instead of the best LSP_VQ_CAND,   */
    /* 8) cand[][] and index[][].  This has significant influence on          */
    /* execution speed.                                                       */

    for (s1 = 0; s1 < tos; s1++) {
        /* set the distortions to huge values */
        fill(dMin, SW_MAX, LSP_VQ_CAND);
        max_dMin = SW_MAX;

        /* Loop for each previous candidate selected, and try each entry */
        for (c1 = 0; c1 < ncPrev; c1++) {
            ptr_offset = 0;

            /* cand_target[] is the target vector with cand[c1] removed.      */
            /* This moves some operations from the for-entry loop here.       */
            /* save_saturation(); */
            v_equ(cand_target, target, dim);
            v_sub(cand_target, cand[c1], dim);
            /* restore_saturation(); */

            for (entry = 0; entry < cb_size[s1]; entry++) {
                ptr1 = cdbk_ptr + ptr_offset;	/* Pointer arithmetics. */

                /* compute the distortion */
                distortion =
                    WeightedMSE(dim, weight, ptr1, cand_target,
                                max_dMin);

                /*======================================================*
                * If the error for this entry is less than the worst	*
                * retained candidate so far, keep it. Note that the 	*
                * error list is maintained in order of best to worst.	*
                *=======================================================*/
                if (distortion < max_dMin) {
                    max_dMin =
                        InsertCand(c1, s1, dMin, distortion,
                                   entry, nextIndex[0],
                                   index[0]);
                }
                ptr_offset = melpe_add(ptr_offset, dim);
            }
        }

        /* At this point ptr_offset is (cb_size[s1]*dim).                     */

        /*==================================================================*
        *	Compute the number of candidate vectors which we kept for the	*
        *	next stage. Note that if the size of the stages is less than	*
        *	the number of candidates, we build them up using all entries	*
        *	until we have kept numCand candidates.  On the other hand, if   *
        *   flag is FALSE and (s1 == tos - 1), then we only need to use     *
        *   ncPrev = 1 because we only copy the best candidate before       *
        *   exiting lspVQ().                                                *
        *==================================================================*/

        if (!flag && s1 == tos - 1)
            ncPrev = 1;
        else {
            /* ncPrev = Min(ncPrev*cb_size[s1], LSP_VQ_CAND) for regular      */
            /* loops, and ncPrev = Min(ncPrev*cb_size[s1], LSP_INP_CAND) for  */
            /* the last lap.  Explanations are available near the end of this *//* function.                                                      */

            L_temp = melpe_L_mult(ncPrev, cb_size[s1]);
            L_temp = melpe_L_shr(L_temp, 1);
            temp1 = melpe_extract_l(L_temp);	/* temp1 = ncPrev * cb_size[s1] */
            if (s1 == tos - 1)
                temp2 = LSP_INP_CAND;
            else
                temp2 = LSP_VQ_CAND;
            if (temp1 < temp2)
                ncPrev = temp1;
            else
                ncPrev = temp2;
        }

        /*==================================================================*
        *	We now have the  best indices for the stage just completed, so	*
        *	compute the new candidate vectors for the next stage... 		*
        *==================================================================*/
        for (c1 = 0; c1 < ncPrev; c1++) {
            v_zap(cand[c1], dim);
            cdbk_ptr2 = codebook;
            temp1 = melpe_add(s1, 1);
            v_equ(index[c1], nextIndex[c1], temp1);
            for (i = 0; i < temp1; i++) {
                /*      v_add(cand[c1], cdbk_ptr2 + index[c1][i]*dim, dim); */
                L_temp = melpe_L_mult(index[c1][i], dim);
                L_temp = melpe_L_shr(L_temp, 1);
                temp2 = melpe_extract_l(L_temp);
                ptr1 = cdbk_ptr2 + temp2;
                v_add(cand[c1], ptr1, dim);
                /*      cdbk_ptr2 += cb_size[i]*dim; */
                L_temp = melpe_L_mult(cb_size[i], dim);
                L_temp = melpe_L_shr(L_temp, 1);
                temp2 = melpe_extract_l(L_temp);
                cdbk_ptr2 += temp2;
            }
        }

        /*      cdbk_ptr += cb_size[s1] * dim; */
        cdbk_ptr += ptr_offset;
    }

    /* Copy best candidate and indices into output.  Here we use temp1 and    */
    /* temp2 to compute (c1*tos) and (c1*dim).                                */

    /* Originally this function copies LSP_VQ_CAND (== 8) vectors before      */
    /* exiting if flag is TRUE.  However, in the calling environment of       */
    /* lspVQ() when flag is passed in as TRUE, we only used LSP_INP_CAND      */
    /* (== 5).                                                                */

    temp1 = 0;
    temp2 = 0;
    for (i = 0; i < ncPrev; i++) {
        v_equ(&(cb_index[temp1]), index[i], tos);
        v_equ(&qout[temp2], cand[i], dim);
        temp1 = melpe_add(temp1, tos);
        temp2 = melpe_add(temp2, dim);
    }

    v_free(cand_target);
}
Ejemplo n.º 3
0
void find_harm(int16_t input[], int16_t fsmag[], int16_t pitch,
	       int16_t num_harm, int16_t length)
{
	register int16_t i, j, k;
	int16_t find_hbuf[2 * FFTLENGTH];
	int16_t iwidth, i2;
	int16_t fwidth, mult_fwidth, shift, max;
	int32_t *L_fsmag;
	int32_t L_temp, L_max;
	int64_t avg;
	int16_t temp1, temp2;

	L_fsmag = L_v_get(num_harm);

	/* Find normalization factor of frame and scale input to maximum          */
	/* precision. */
	max = 0;
	for (i = 0; i < length; i++) {
		temp1 = melpe_abs_s(input[i]);
		if (temp1 > max)
			max = temp1;
	}
	shift = melpe_norm_s(max);

	/* initialize fsmag */
	fill(fsmag, ONE_Q13, num_harm);

	/* Perform peak-picking on FFT of input signal */
	/* Calculate FFT of complex signal in scratch buffer */
	v_zap(find_hbuf, 2 * FFTLENGTH);
	for (i = 0; i < length; i++) {
		find_hbuf[i] = melpe_shl(input[i], shift);
	}
	rfft(find_hbuf, FFTLENGTH);

	/* Implement pitch dependent staircase function */
	/* Harmonic bin width fwidth = Q6 */

	fwidth = melpe_shr(melpe_divide_s(FFTLENGTH, pitch), 2);
	/* iwidth = (int) fwidth */
	iwidth = melpe_shr(fwidth, 6);

	/* Originally here we have a check for setting iwidth to be at least 2.   */
	/* This is not necessary because FFTLENGTH (== 512) divided by PITCHMAX   */
	/* (== 160) will be at least 3.                                           */

	i2 = melpe_shr(iwidth, 1);

	/* if (num_harm > 0.25*pitch) num_harm = 0.25*pitch */
	/* temp1 = 0.25*pitch in Q0 */

	temp1 = melpe_shr(pitch, 9);
	if (num_harm > temp1)
		num_harm = temp1;

	/* initialize avg to make sure that it is non-zero */
	mult_fwidth = fwidth;	/* (k + 1)*fwidth, Q6 */
	for (k = 0; k < num_harm; k++) {
		/*      i = ((k + 1) * fwidth) - i2 + 0.5 *//* Start at peak-i2 */
		i = melpe_sub(melpe_shr(melpe_add(mult_fwidth, X05_Q6), 6), i2);

		/* Calculate magnitude squared of coefficients */
		L_max = 0;
		for (j = 0; j < iwidth; j++) {
			/*      temp1 = find_hbuf[2*(j + i)]; */
			/*      temp2 = find_hbuf[2*(j + i) + 1]; */
			temp2 = melpe_add(i, j);
			temp1 = find_hbuf[2 * temp2];
			temp2 = find_hbuf[2 * temp2 + 1];
			L_temp =
			    melpe_L_add(melpe_L_mult(temp1, temp1), melpe_L_mult(temp2, temp2));
			L_max = Max(L_max, L_temp);
		}

		L_fsmag[k] = L_max;
		mult_fwidth = melpe_add(mult_fwidth, fwidth);
	}

	/* Normalize Fourier series values to average magnitude */
	avg = 1;
	for (k = 0; k < num_harm; k++)
		avg = melpe_L40_add(avg, L_fsmag[k]);
	temp1 = melpe_norm32(avg);
	L_temp = (int32_t) melpe_L40_shl(avg, temp1);	/* man. of avg */
	temp1 = melpe_sub(31, temp1);	/* exp. of avg */
	/* now compute num_harm/avg. avg = L_temp(Q31) x 2^temp1 */
	temp2 = melpe_shl(num_harm, 10);
	/* num_harm = temp2(Q15) x 2^5 */
	temp2 = melpe_divide_s(temp2, melpe_extract_h(L_temp));
	/* now think fs as Q15 x 2^31. The constant below should be 31 */
	/* but consider Q5 for num_harm and fsmag before sqrt Q11, and */
	/* add two guard bits  30 = 31 + 5 - 4 - 2                     */
	shift = melpe_sub(30, temp1);
	/* the sentence above is just for clarity. temp1 = sub(31, temp1) */
	/* and shift = sub(30, temp1) can be shift = sub(temp1, 1)        */

	for (i = 0; i < num_harm; i++) {
		/*      temp1 = num_harm/(avg + 0.0001) */
		/*      fsmag[i] = sqrt(temp1*fsmag[i]) */
		temp1 = melpe_extract_h(melpe_L_shl(L_fsmag[i], shift));
		temp1 = melpe_extract_h(melpe_L_shl(melpe_L_mult(temp1, temp2), 2));	/* Q11 */
		fsmag[i] = sqrt_Q15(temp1);
	}

	v_free(L_fsmag);
}
Ejemplo n.º 4
0
void main(int argc, char **argv)

{
    void parse(int argc, char **argv);

    int length, frame, eof_reached;
    int num_frames = 0;
    float speech_in[FRAME];
    float speech_out[FRAME];
    static struct melp_param melp_par;      /* melp parameters */
    unsigned int chbuf[CHSIZE];
    FILE *fp_in, *fp_out;

    /* Print user message */
    printf("\n2.4 kb/s Proposed Federal Standard MELP speech coder\n");
    printf("  C simulation, version 1.2\n\n");

    /* Get input parameters from command line */
    parse(argc, argv);

    /* Open input, output, and parameter files */
    if (( fp_in = fopen(in_name,"rb")) == NULL ) {
	printf("  ERROR: cannot read file %s.\n",in_name);
	exit(1);
    }
    if (( fp_out = fopen(out_name,"wb")) == NULL ) {
	printf("  ERROR: cannot write file %s.\n",out_name);
	exit(1);
    }

    /* Check length of channel input if needed */
    if (melpmode == SYNTHESIS) {
	fseek(fp_in,0L,2);
	length = ftell(fp_in);
	rewind(fp_in);

	num_frames = 0.5 + length * (8.0 / NUM_CH_BITS) * (6.0/32);
	
    }

    /* Initialize MELP analysis and synthesis */
    if (melpmode != SYNTHESIS)
      melp_ana_init();
    if (melpmode != ANALYSIS)
      melp_syn_init();

    /* Run MELP coder on input signal */
    frame = 0;
    melp_par.chptr = chbuf;
    melp_par.chbit = 0;
    eof_reached = 0;
    while (eof_reached == 0) {

	/* Perform MELP analysis */
	if (melpmode != SYNTHESIS) {
	    /* read input speech */
	    length = readbl(speech_in,fp_in,FRAME);
	    if (length < FRAME) {
		v_zap(&speech_in[length],FRAME-length);
		eof_reached = 1;
	    }

	    /* Run MELP analyzer */
	    if (melpmode == ANA_SYN) {
		/* reset pointers to short channel buffer */
		melp_par.chptr = chbuf;
		melp_par.chbit = 0;
	    }

	    melp_ana(speech_in,&melp_par);
 
	    /* Write channel output if needed */
	    if (melpmode == ANALYSIS && melp_par.chbit == 0) {
		fwrite((void *) chbuf,sizeof(int),melp_par.chptr-chbuf,fp_out);

		/* reset pointer to short channel buffer */
		melp_par.chptr = chbuf;
	    }

	    if (melp_par.chptr >= &chbuf[CHSIZE] && melp_par.chbit > 0) {
		printf("\nERROR: Ran out of channel buffer memory.\n");
		exit(1);
	    }

	}          

	/* Perform MELP synthesis (skip first frame) */
	if (melpmode != ANALYSIS) {

	    if (melpmode == ANA_SYN) {
		/* reset pointers to short channel buffer */
		melp_par.chptr = chbuf;
		melp_par.chbit = 0;
	    }

	    /* Read channel input if needed */
	    if (melpmode == SYNTHESIS && melp_par.chbit == 0) {
		fread((void *) chbuf,sizeof(int),CHSIZE,fp_in);

		/* reset pointer to short channel buffer */
		melp_par.chptr = chbuf;
	    }

	    melp_syn(&melp_par,speech_out);
	    if (frame > 0)
	      writebl(speech_out,fp_out,FRAME);
	}

	frame++; 
	if (melpmode == SYNTHESIS) {
	    if (frame >= num_frames)
	      eof_reached = 1;
	}
    }
 
    /* Write channel output if needed */
    if (melpmode == ANALYSIS) {
	if (melp_par.chbit > 0)
	  fwrite((void *) chbuf,sizeof(int),melp_par.chptr-chbuf+1,fp_out);
	else
	  fwrite((void *) chbuf,sizeof(int),melp_par.chptr-chbuf,fp_out);
    }

    fclose(fp_in);
    fclose(fp_out);

}
Ejemplo n.º 5
0
void melp_ana_init()
{

    int j;

    bpvc_ana_init(FRAME,PITCHMIN,PITCHMAX,NUM_BANDS,2,MINLENGTH);
    pitch_ana_init(PITCHMIN,PITCHMAX,FRAME,LPF_ORD,MINLENGTH);
    p_avg_init(PDECAY,DEFAULT_PITCH,3);

    v_zap(speech,IN_BEG+FRAME);
    pitch_avg=DEFAULT_PITCH;
    fill(fpitch,DEFAULT_PITCH,2);
    v_zap(lpfsp_del,LPF_ORD);
	
    /* Initialize multi-stage vector quantization (read codebook) */
	
    vq_par.num_best = MSVQ_M;
    vq_par.num_stages = 4;
    vq_par.dimension = 10;

    /* 
     * Allocate memory for number of levels per stage and indices
     * and for number of bits per stage 
     */
 
    MEM_ALLOC(MALLOC,vq_par.num_levels,vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,vq_par.indices,vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,vq_par.num_bits,vq_par.num_stages,int);
	
    vq_par.num_levels[0] = 128;
    vq_par.num_levels[1] = 64;
    vq_par.num_levels[2] = 64;
    vq_par.num_levels[3] = 64;
	
    vq_par.num_bits[0] = 7;
    vq_par.num_bits[1] = 6;
    vq_par.num_bits[2] = 6;
    vq_par.num_bits[3] = 6;
	
    vq_par.cb = msvq_cb;
	
    /* Scale codebook to 0 to 1 */
    v_scale(vq_par.cb,(2.0/FSAMP),3200);

    /* Initialize Fourier magnitude vector quantization (read codebook) */
	
    fs_vq_par.num_best = 1;
    fs_vq_par.num_stages = 1;
    fs_vq_par.dimension = NUM_HARM;

    /* 
     * Allocate memory for number of levels per stage and indices
     * and for number of bits per stage 
     */
 
    MEM_ALLOC(MALLOC,fs_vq_par.num_levels,fs_vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,fs_vq_par.indices,fs_vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,fs_vq_par.num_bits,fs_vq_par.num_stages,int);

    fs_vq_par.num_levels[0] = FS_LEVELS;
    fs_vq_par.num_bits[0] = FS_BITS;
    fs_vq_par.cb = fsvq_cb;
	
    /* Initialize fixed MSE weighting and inverse of weighting */
	
    vq_fsw(w_fs, NUM_HARM, 60.0);
	
    /* Pre-weight codebook (assume single stage only) */
	
    if (fsvq_weighted == 0)
      {
	  fsvq_weighted = 1;
	  for (j = 0; j < fs_vq_par.num_levels[0]; j++)
	    window(&fs_vq_par.cb[j*NUM_HARM],w_fs,&fs_vq_par.cb[j*NUM_HARM],
		   NUM_HARM);
      }

}