vencode.c 5.12 KB
#include "vadpcm.h"

int
vencodeframe(FILE *ofile, short *inBuffer, int *state, int ***coefTable, int order, int npredictors, int nsam)

{
    short
        ix[FRAMESIZE];
    
    int
        prediction[FRAMESIZE],
        inVector[FRAMESIZE],
        saveState[FRAMESIZE],
        optimalp,
        scale,
        llevel,
        ulevel,
        i,
        j,
        k,
        ie[FRAMESIZE],
        nIter,
        max,
        cV,
        maxClip;
    
    unsigned char
        header,
        c;
    
    float
        e[FRAMESIZE],
        se,
        min;

    /*
     * Clear input for nsam less than FRAMESIZE
     */
    for (i=nsam; i<FRAMESIZE; i++)
        inBuffer[i] = 0;
    
    /*
     * Maximum and minimum allowable levels
     */
    llevel = - (short) (1L<<(SAMPLEBITS-1));
    ulevel = -llevel - 1;

    /*
     * Find the prediction error for each possible predictor. Uses the
     * vector method.
     */
    min = 1e30; optimalp = 0;
    for (k=0; k<npredictors; k++){
            
        /*
         * Set up previous frame outputs - use quantized outputs
         */
        for (i=0; i<order; i++)
            inVector[i] = state[FRAMESIZE-order+i];
            
        for (i=0; i<VECTORSIZE; i++){
            prediction[i] = inner_product(order+i, coefTable[k][i], inVector);
            inVector[i+order] = inBuffer[i] - prediction[i];
            e[i] = (float) inVector[i+order];
        }
            
        /*
         * Set up previous vector outputs, for next lot of VECTORSIZE
         */
        for (i=0; i<order; i++)
            inVector[i] = prediction[VECTORSIZE-order+i]+inVector[VECTORSIZE+i];
        for (i=0; i<VECTORSIZE; i++){
            prediction[i+VECTORSIZE] = inner_product(order+i, coefTable[k][i], inVector);
            inVector[i+order] = inBuffer[VECTORSIZE+i] - prediction[i+VECTORSIZE];
            e[i+VECTORSIZE] = (float) inVector[i+order];
        }

        /*
         * Now find the error measure for this frame and check
         * against the current best.
         */
        se = 0;
        for (j=0; j<FRAMESIZE; j++)
            se += e[j]*e[j];
        if (se<min){
            min=se;
            optimalp = k;
        }
    }

    /*
     * Re-calculate final prediction error using optimal predictor
     */
    
    for (i=0; i<order; i++)
        inVector[i] = state[FRAMESIZE-order+i];
    for (i=0; i<VECTORSIZE; i++){
        prediction[i] = inner_product(order+i, coefTable[optimalp][i], inVector);
        inVector[i+order] = inBuffer[i] - prediction[i];
        e[i] = (float) inVector[i+order];
    }
    for (i=0; i<order; i++)
        inVector[i] = prediction[VECTORSIZE-order+i]+inVector[VECTORSIZE+i];
    for (i=0; i<VECTORSIZE; i++){
        prediction[i+VECTORSIZE] = inner_product(order+i, coefTable[optimalp][i], inVector);
        inVector[i+order] = inBuffer[VECTORSIZE+i] - prediction[i+VECTORSIZE];
        e[i+VECTORSIZE] = (float) inVector[i+order];
    }

    /*
     * Find range value
     */
    clamp(FRAMESIZE, e, ie, 16);
    max = 0;
    for (i=0; i<FRAMESIZE; i++)
        if (fabs(ie[i])>fabs(max))
            max = ie[i];

    for (scale=0; scale<=MAXSCALE; scale++){
        if ((max<=ulevel) && (max>=llevel))
            break;
        max /= 2;
    }
    
    /*
     * Final prediction error with a quantizer in the loop
     */
    for (i=0; i<FRAMESIZE; i++)
        saveState[i] = state[i];

    scale--;
    nIter = 0;
    do {
        nIter++;
        maxClip = 0;
        scale++;
        if (scale > MAXSCALE)
            scale = MAXSCALE;
        for (i=0; i<order; i++)
            inVector[i] = saveState[FRAMESIZE-order+i];
        for (i=0; i<VECTORSIZE; i++){
            prediction[i] = inner_product(order+i, coefTable[optimalp][i], inVector);
            se = (float) inBuffer[i] - prediction[i];
            ix[i] = qsample(se, 1<<scale);
            cV = (short) clip((int) ix[i], llevel, ulevel) - ix[i];
            if (abs(cV) > maxClip)
                maxClip = abs(cV);
            ix[i] += cV;
            inVector[i+order] = ix[i]*(1<<scale);
            /*
             * Decoder output
             */
            state[i] = prediction[i] + inVector[i+order];
        }
        for (i=0; i<order; i++)
            inVector[i] = state[VECTORSIZE-order+i];
        for (i=0; i<VECTORSIZE; i++){
            prediction[i+VECTORSIZE] = inner_product(order+i, coefTable[optimalp][i], inVector);
            se = (float) inBuffer[VECTORSIZE+i] - prediction[VECTORSIZE+i];
            ix[VECTORSIZE+i] = qsample(se, 1<<scale);
            cV = (short) clip((int) ix[i+VECTORSIZE], llevel, ulevel) - ix[i+VECTORSIZE];
            if (abs(cV) > maxClip)
                maxClip = abs(cV);
            ix[i+VECTORSIZE] += cV;
            inVector[i+order] = ix[VECTORSIZE+i]*(1<<scale);
            state[VECTORSIZE+i] = prediction[i+VECTORSIZE] + inVector[i+order];
        }
    }
    while ((maxClip > MAXCLIP) && (nIter < MAXITER));
    
    /*
     * Write frame header and bitstream
     */
    header = (scale<<4) | ((optimalp) & 0xf);
    fwrite(&header, 1, 1, ofile);
    for (i=0; i<FRAMESIZE; i+=2){
        c = (ix[i]<<4) | (ix[i+1] & 0xf);
        fwrite(&c, 1, 1, ofile);
    }
}