Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/tools/sdk-tools/adpcm/vencode.c
7861 views
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
}
237
238