sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

vencode.c (7224B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <math.h>
      4 #include "vadpcm.h"
      5 
      6 void vencodeframe(FILE *ofile, s16 *inBuffer, s32 *state, s32 ***coefTable, s32 order, s32 npredictors, s32 nsam)
      7 {
      8     s16 ix[16];
      9     s32 prediction[16];
     10     s32 inVector[16];
     11     s32 saveState[16];
     12     s32 optimalp;
     13     s32 scale;
     14     s32 llevel;
     15     s32 ulevel;
     16     s32 i;
     17     s32 j;
     18     s32 k;
     19     s32 ie[16];
     20     s32 nIter;
     21     s32 max;
     22     s32 cV;
     23     s32 maxClip;
     24     u8 header;
     25     u8 c;
     26     f32 e[16];
     27     f32 se;
     28     f32 min;
     29 
     30     // We are only given 'nsam' samples; pad with zeroes to 16.
     31     for (i = nsam; i < 16; i++)
     32     {
     33         inBuffer[i] = 0;
     34     }
     35 
     36     llevel = -8;
     37     ulevel = -llevel - 1;
     38 
     39     // Determine the best-fitting predictor.
     40     min = 1e30;
     41     optimalp = 0;
     42     for (k = 0; k < npredictors; k++)
     43     {
     44         // Copy over the last 'order' samples from the previous output.
     45         for (i = 0; i < order; i++)
     46         {
     47             inVector[i] = state[16 - order + i];
     48         }
     49 
     50         // For 8 samples...
     51         for (i = 0; i < 8; i++)
     52         {
     53             // Compute a prediction based on 'order' values from the old state,
     54             // plus previous errors in this chunk, as an inner product with the
     55             // coefficient table.
     56             prediction[i] = inner_product(order + i, coefTable[k][i], inVector);
     57             // Record the error in inVector (thus, its first 'order' samples
     58             // will contain actual values, the rest will be error terms), and
     59             // in floating point form in e (for no particularly good reason).
     60             inVector[i + order] = inBuffer[i] - prediction[i];
     61             e[i] = (f32) inVector[i + order];
     62         }
     63 
     64         // For the next 8 samples, start with 'order' values from the end of
     65         // the previous 8-sample chunk of inBuffer. (The code is equivalent to
     66         // inVector[i] = inBuffer[8 - order + i].)
     67         for (i = 0; i < order; i++)
     68         {
     69             inVector[i] = prediction[8 - order + i] + inVector[8 + i];
     70         }
     71 
     72         // ... and do the same thing as before to get predictions.
     73         for (i = 0; i < 8; i++)
     74         {
     75             prediction[8 + i] = inner_product(order + i, coefTable[k][i], inVector);
     76             inVector[i + order] = inBuffer[8 + i] - prediction[8 + i];
     77             e[8 + i] = (f32) inVector[i + order];
     78         }
     79 
     80         // Compute the L2 norm of the errors; the lowest norm decides which
     81         // predictor to use.
     82         se = 0.0f;
     83         for (j = 0; j < 16; j++)
     84         {
     85             se += e[j] * e[j];
     86         }
     87 
     88         if (se < min)
     89         {
     90             min = se;
     91             optimalp = k;
     92         }
     93     }
     94 
     95     // Do exactly the same thing again, for real.
     96     for (i = 0; i < order; i++)
     97     {
     98         inVector[i] = state[16 - order + i];
     99     }
    100 
    101     for (i = 0; i < 8; i++)
    102     {
    103         prediction[i] = inner_product(order + i, coefTable[optimalp][i], inVector);
    104         inVector[i + order] = inBuffer[i] - prediction[i];
    105         e[i] = (f32) inVector[i + order];
    106     }
    107 
    108     for (i = 0; i < order; i++)
    109     {
    110         inVector[i] = prediction[8 - order + i] + inVector[8 + i];
    111     }
    112 
    113     for (i = 0; i < 8; i++)
    114     {
    115         prediction[8 + i] = inner_product(order + i, coefTable[optimalp][i], inVector);
    116         inVector[i + order] = inBuffer[8 + i] - prediction[8 + i];
    117         e[8 + i] = (f32) inVector[i + order];
    118     }
    119 
    120     // Clamp the errors to 16-bit signed ints, and put them in ie.
    121     clamp(16, e, ie, 16);
    122 
    123     // Find a value with highest absolute value.
    124     // @bug If this first finds -2^n and later 2^n, it should set 'max' to the
    125     // latter, which needs a higher value for 'scale'.
    126     max = 0;
    127     for (i = 0; i < 16; i++)
    128     {
    129         if (fabs(ie[i]) > fabs(max))
    130         {
    131             max = ie[i];
    132         }
    133     }
    134 
    135     // Compute which power of two we need to scale down by in order to make
    136     // all values representable as 4-bit signed integers (i.e. be in [-8, 7]).
    137     // The worst-case 'max' is -2^15, so this will be at most 12.
    138     for (scale = 0; scale <= 12; scale++)
    139     {
    140         if (max <= ulevel && max >= llevel)
    141         {
    142             goto out;
    143         }
    144         max /= 2;
    145     }
    146 out:;
    147 
    148     for (i = 0; i < 16; i++)
    149     {
    150         saveState[i] = state[i];
    151     }
    152 
    153     // Try with the computed scale, but if it turns out we don't fit in 4 bits
    154     // (if some |cV| >= 2), use scale + 1 instead (i.e. downscaling by another
    155     // factor of 2).
    156     scale--;
    157     nIter = 0;
    158     do
    159     {
    160         nIter++;
    161         maxClip = 0;
    162         scale++;
    163         if (scale > 12)
    164         {
    165             scale = 12;
    166         }
    167 
    168         // Copy over the last 'order' samples from the previous output.
    169         for (i = 0; i < order; i++)
    170         {
    171             inVector[i] = saveState[16 - order + i];
    172         }
    173 
    174         // For 8 samples...
    175         for (i = 0; i < 8; i++)
    176         {
    177             // Compute a prediction based on 'order' values from the old state,
    178             // plus previous *quantized* errors in this chunk (because that's
    179             // all the decoder will have available).
    180             prediction[i] = inner_product(order + i, coefTable[optimalp][i], inVector);
    181 
    182             // Compute the error, and divide it by 2^scale, rounding to the
    183             // nearest integer. This should ideally result in a 4-bit integer.
    184             se = (f32) inBuffer[i] - (f32) prediction[i];
    185             ix[i] = qsample(se, 1 << scale);
    186 
    187             // Clamp the error to a 4-bit signed integer, and record what delta
    188             // was needed for that.
    189             cV = (s16) clip(ix[i], llevel, ulevel) - ix[i];
    190             if (maxClip < abs(cV))
    191             {
    192                 maxClip = abs(cV);
    193             }
    194             ix[i] += cV;
    195 
    196             // Record the quantized error in inVector for later predictions,
    197             // and the quantized (decoded) output in state (for use in the next
    198             // batch of 8 samples).
    199             inVector[i + order] = ix[i] * (1 << scale);
    200             state[i] = prediction[i] + inVector[i + order];
    201         }
    202 
    203         // Copy over the last 'order' decoded samples from the above chunk.
    204         for (i = 0; i < order; i++)
    205         {
    206             inVector[i] = state[8 - order + i];
    207         }
    208 
    209         // ... and do the same thing as before.
    210         for (i = 0; i < 8; i++)
    211         {
    212             prediction[8 + i] = inner_product(order + i, coefTable[optimalp][i], inVector);
    213             se = (f32) inBuffer[8 + i] - (f32) prediction[8 + i];
    214             ix[8 + i] = qsample(se, 1 << scale);
    215             cV = (s16) clip(ix[8 + i], llevel, ulevel) - ix[8 + i];
    216             if (maxClip < abs(cV))
    217             {
    218                 maxClip = abs(cV);
    219             }
    220             ix[8 + i] += cV;
    221             inVector[i + order] = ix[8 + i] * (1 << scale);
    222             state[8 + i] = prediction[8 + i] + inVector[i + order];
    223         }
    224     }
    225     while (maxClip >= 2 && nIter < 2);
    226 
    227     // The scale, the predictor index, and the 16 computed outputs are now all
    228     // 4-bit numbers. Write them out as 1 + 8 bytes.
    229     header = (scale << 4) | (optimalp & 0xf);
    230     fwrite(&header, 1, 1, ofile);
    231     for (i = 0; i < 16; i += 2)
    232     {
    233         c = (ix[i] << 4) | (ix[i + 1] & 0xf);
    234         fwrite(&c, 1, 1, ofile);
    235     }
    236 }