Skip to content

Commit 66ae813

Browse files
authored
Merge pull request drowe67#245 from drowe67/ms-optimization-mbest
Slight optimizations for mbest_search() and mbest_insert().
2 parents c7370de + 9c07707 commit 66ae813

File tree

9 files changed

+117
-84
lines changed

9 files changed

+117
-84
lines changed

CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ endif()
841841
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/unittest; ./reliable_text_fade.sh 700D -19 8 1 '${CMAKE_CURRENT_BINARY_DIR}/src'")
842842

843843
add_test(NAME test_freedv_reliable_text_fade_700E
844-
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/unittest; ./reliable_text_fade.sh 700E -22 9 1 '${CMAKE_CURRENT_BINARY_DIR}/src'")
844+
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/unittest; ./reliable_text_fade.sh 700E -22 8 1 '${CMAKE_CURRENT_BINARY_DIR}/src'")
845845

846846
if(LPCNET)
847847
add_test(NAME test_freedv_reliable_text_ideal_2020
@@ -991,10 +991,11 @@ endif(NOT APPLE)
991991

992992
add_test(NAME test_vq_mbest
993993
COMMAND sh -c "./tvq_mbest; \
994-
cat target.f32 | ../misc/vq_mbest -k 2 -q vq1.f32,vq2.f32 --mbest 2 -v > out.f32; \
995-
diff target.f32 out.f32"
994+
cat target.f32 | \
995+
../misc/vq_mbest -k 4 -q vq1.f32,vq2.f32 --st 1 --en 2 --mbest 2 -v > /dev/null;"
996996
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unittest
997997
)
998+
set_tests_properties(test_vq_mbest PROPERTIES PASS_REGULAR_EXPRESSION "MSE: 0.00")
998999

9991000
add_test(NAME test_700c_eq
10001001
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/unittest;

misc/vq_mbest.c

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@
1919
#define MAX_ENTRIES 4096
2020
#define MAX_STAGES 5
2121

22-
void quant_pred_mbest(float vec_out[],
23-
int indexes[],
24-
float vec_in[],
25-
int num_stages,
26-
float vq[],
27-
int m[], int k,
28-
int mbest_survivors, int st, int en);
22+
void quant_mbest(float vec_out[],
23+
int indexes[],
24+
float vec_in[],
25+
int num_stages,
26+
float vqw[], float vq[],
27+
int m[], int k,
28+
int mbest_survivors);
2929

3030
int verbose = 0;
3131

3232
int main(int argc, char *argv[]) {
3333
float vq[MAX_STAGES*MAX_K*MAX_ENTRIES];
34+
float vqw[MAX_STAGES*MAX_K*MAX_ENTRIES];
3435
int m[MAX_STAGES];
3536
int k=0, mbest_survivors=1, num_stages=0;
3637
char fnames[256], fn[256], *comma, *p;
@@ -143,11 +144,27 @@ int main(int argc, char *argv[]) {
143144
if (st == -1) st = 0;
144145
if (en == -1) en = k-1;
145146

146-
int indexes[num_stages], nvecs = 0; int vec_usage[m[0]];
147+
float w[k];
148+
for(int i=0; i<st; i++)
149+
w[i] = 0.0;
150+
for(int i=st; i<=en; i++)
151+
w[i] = 1.0;
152+
for(int i=en+1; i<k; i++)
153+
w[i] = 0.0;
154+
155+
/* apply weighting to codebook (rather than in search) */
156+
memcpy(vqw, vq, sizeof(vq));
157+
for(int s=0; s<num_stages; s++) {
158+
mbest_precompute_weight(&vqw[s*k*MAX_ENTRIES], w, k, m[s]);
159+
}
160+
161+
int indexes[num_stages], nvecs = 0; int vec_usage[m[0]];
147162
for(int i=0; i<m[0]; i++) vec_usage[i] = 0;
148163
float target[k], quantised[k];
149164
float sqe = 0.0;
150165
while(fread(&target, sizeof(float), k, stdin) && (nvecs < num)) {
166+
for(int i=0; i<k; i++)
167+
target[i] *= w[i];
151168
int dont_count = 0;
152169
/* optional clamping to lower limit or mean */
153170
float mean = 0.0;
@@ -161,7 +178,7 @@ int main(int argc, char *argv[]) {
161178
target[i] += -difference;
162179
dont_count = 1;
163180
}
164-
quant_pred_mbest(quantised, indexes, target, num_stages, vq, m, k, mbest_survivors, st, en);
181+
quant_mbest(quantised, indexes, target, num_stages, vqw, vq, m, k, mbest_survivors);
165182
if (dont_count == 0) {
166183
for(int i=st; i<=en; i++)
167184
sqe += pow(target[i]-quantised[i], 2.0);
@@ -172,7 +189,7 @@ int main(int argc, char *argv[]) {
172189
vec_usage[indexes[0]]++;
173190
}
174191

175-
fprintf(stderr, "%4.2f\n", sqe/(nvecs*(en-st+1)));
192+
fprintf(stderr, "MSE: %4.2f\n", sqe/(nvecs*(en-st+1)));
176193

177194
if (output_vec_usage) {
178195
for(int i=0; i<m[0]; i++)
@@ -196,15 +213,15 @@ void pv(char s[], float v[], int k) {
196213

197214
// mbest algorithm version, backported from LPCNet/src
198215

199-
void quant_pred_mbest(float vec_out[],
200-
int indexes[],
201-
float vec_in[],
202-
int num_stages,
203-
float vq[],
204-
int m[], int k,
205-
int mbest_survivors, int st, int en)
216+
void quant_mbest(float vec_out[],
217+
int indexes[],
218+
float vec_in[],
219+
int num_stages,
220+
float vqw[], float vq[],
221+
int m[], int k,
222+
int mbest_survivors)
206223
{
207-
float err[k], w[k], se1;
224+
float err[k], se1;
208225
int i,j,s,s1,ind;
209226

210227
struct MBEST *mbest_stage[num_stages];
@@ -216,24 +233,17 @@ void quant_pred_mbest(float vec_out[],
216233
index[i] = 0;
217234
}
218235

219-
for(i=0; i<st; i++)
220-
w[i] = 0.0;
221-
for(i=st; i<=en; i++)
222-
w[i] = 1.0;
223-
for(i=en+1; i<k; i++)
224-
w[i] = 0.0;
225-
226236
se1 = 0.0;
227237
for(i=0; i<k; i++) {
228238
err[i] = vec_in[i];
229-
se1 += err[i]*err[i]*w[i]*w[i];
239+
se1 += err[i]*err[i];
230240
}
231241
se1 /= k;
232242

233243
/* now quantise err[] using multi-stage mbest search, preserving
234244
mbest_survivors at each stage */
235245

236-
mbest_search(vq, err, w, k, m[0], mbest_stage[0], index);
246+
mbest_search(vqw, err, k, m[0], mbest_stage[0], index);
237247
if (verbose) mbest_print("Stage 1:", mbest_stage[0]);
238248

239249
for(s=1; s<num_stages; s++) {
@@ -251,11 +261,11 @@ void quant_pred_mbest(float vec_out[],
251261
ind = index[s-s1];
252262
if (verbose) fprintf(stderr, " s: %d s1: %d s-s1: %d ind: %d\n", s,s1,s-s1,ind);
253263
for(i=0; i<k; i++) {
254-
target[i] -= vq[s1*k*MAX_ENTRIES+ind*k+i];
264+
target[i] -= vqw[s1*k*MAX_ENTRIES+ind*k+i];
255265
}
256266
}
257267
pv(" target: ", target, k);
258-
mbest_search(&vq[s*k*MAX_ENTRIES], target, w, k, m[s], mbest_stage[s], index);
268+
mbest_search(&vqw[s*k*MAX_ENTRIES], target, k, m[s], mbest_stage[s], index);
259269
}
260270
char str[80]; sprintf(str,"Stage %d:", s+1);
261271
if (verbose) mbest_print(str, mbest_stage[s]);
@@ -272,9 +282,9 @@ void quant_pred_mbest(float vec_out[],
272282
int ind = indexes[s];
273283
float se2 = 0.0;
274284
for(i=0; i<k; i++) {
275-
err[i] -= vq[s*k*MAX_ENTRIES+ind*k+i];
285+
err[i] -= vqw[s*k*MAX_ENTRIES+ind*k+i];
276286
vec_out[i] += vq[s*k*MAX_ENTRIES+ind*k+i];
277-
se2 += err[i]*err[i]*w[i]*w[i];
287+
se2 += err[i]*err[i];
278288
}
279289
se2 /= k;
280290
pv(" err: ", err, k);

src/defines.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,8 @@ struct lsp_codebook {
103103

104104
extern const struct lsp_codebook lsp_cb[];
105105
extern const struct lsp_codebook lsp_cbd[];
106-
extern const struct lsp_codebook lsp_cbvq[];
107-
extern const struct lsp_codebook lsp_cbjnd[];
108-
extern const struct lsp_codebook lsp_cbdt[];
109106
extern const struct lsp_codebook lsp_cbjvm[];
110-
extern const struct lsp_codebook lsp_cbvqanssi[];
111-
extern const struct lsp_codebook mel_cb[];
112107
extern const struct lsp_codebook ge_cb[];
113-
extern const struct lsp_codebook lspmelvq_cb[];
114108
extern const struct lsp_codebook newamp1vq_cb[];
115109
extern const struct lsp_codebook newamp1_energy_cb[];
116110
extern const struct lsp_codebook newamp2vq_cb[];

src/generate_codebook.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
AUTHOR......: Bruce Perens
55
DATE CREATED: 29 Sep 2010
66
7-
Generate header files containing LSP quantisers, runs at compile time.
7+
Generate header files containing quantisers, runs at compile time.
88
99
\*---------------------------------------------------------------------------*/
1010

src/mbest.c

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ void mbest_destroy(struct MBEST *mbest) {
6464
}
6565

6666

67+
/* apply weighting to VQ for efficient VQ search */
68+
69+
void mbest_precompute_weight(float cb[], float w[], int k, int m) {
70+
for (int j=0; j<m; j++) {
71+
for(int i=0; i<k; i++)
72+
cb[k*j+i] *= w[i];
73+
}
74+
}
75+
6776
/*---------------------------------------------------------------------------*\
6877
6978
mbest_insert
@@ -75,18 +84,16 @@ void mbest_destroy(struct MBEST *mbest) {
7584
\*---------------------------------------------------------------------------*/
7685

7786
void mbest_insert(struct MBEST *mbest, int index[], float error) {
78-
int i, j, found;
87+
int i, found;
7988
struct MBEST_LIST *list = mbest->list;
8089
int entries = mbest->entries;
8190

8291
found = 0;
8392
for(i=0; i<entries && !found; i++)
8493
if (error < list[i].error) {
8594
found = 1;
86-
for(j=entries-1; j>i; j--)
87-
list[j] = list[j-1];
88-
for(j=0; j<MBEST_STAGES; j++)
89-
list[i].index[j] = index[j];
95+
memmove(&list[i+1], &list[i], sizeof(struct MBEST_LIST) * (entries - i - 1));
96+
memcpy(&list[i].index[0], &index[0], sizeof(int) * MBEST_STAGES);
9097
list[i].error = error;
9198
}
9299
}
@@ -114,30 +121,49 @@ void mbest_print(char title[], struct MBEST *mbest) {
114121
\*---------------------------------------------------------------------------*/
115122

116123
void mbest_search(
117-
const float *cb, /* VQ codebook to search */
118-
float vec[], /* target vector */
119-
float w[], /* weighting vector */
120-
int k, /* dimension of vector */
121-
int m, /* number on entries in codebook */
122-
struct MBEST *mbest, /* list of closest matches */
123-
int index[] /* indexes that lead us here */
124+
const float *cb, /* VQ codebook to search */
125+
float vec[], /* target vector */
126+
int k, /* dimension of vector */
127+
int m, /* number on entries in codebook */
128+
struct MBEST *mbest, /* list of closest matches */
129+
int index[] /* indexes that lead us here */
124130
)
125131
{
126-
float e;
127-
int i,j;
128-
float diff;
132+
int j;
129133

130-
for(j=0; j<m; j++) {
131-
e = 0.0;
132-
for(i=0; i<k; i++) {
133-
diff = cb[j*k+i]-vec[i];
134-
e += diff*w[i]*diff*w[i];
135-
}
136-
index[0] = j;
137-
mbest_insert(mbest, index, e);
138-
}
139-
}
134+
/* note weighting can be applied externally by modifiying cb[] and vec:
140135
136+
float e = 0.0;
137+
for(i=0; i<k; i++)
138+
e += pow(w[i]*(cb[j*k+i] - vec[i]),2.0)
139+
140+
|
141+
\|/
142+
143+
for(i=0; i<k; i++)
144+
e += pow(w[i]*cb[j*k+i] - w[i]*vec[i]),2.0)
145+
146+
|
147+
\|/
148+
149+
for(i=0; i<k; i++)
150+
e += pow(cb1[j*k+i] - vec1[i]),2.0)
151+
152+
where cb1[j*k+i] = w[i]*cb[j*k+i], and vec1[i] = w[i]*vec[i]
153+
*/
154+
155+
for(j=0; j<m; j++) {
156+
float e = 0.0;
157+
for(int i=0; i<k; i++) {
158+
float diff = *cb++ - vec[i];
159+
e += diff*diff;
160+
}
161+
162+
index[0] = j;
163+
if (e < mbest->list[mbest->entries - 1].error)
164+
mbest_insert(mbest, index, e);
165+
}
166+
}
141167

142168
/*---------------------------------------------------------------------------*\
143169
@@ -146,7 +172,7 @@ void mbest_search(
146172
Searches vec[] to a codebbook of vectors, and maintains a list of the mbest
147173
closest matches. Only searches the first NewAmp2_K Vectors
148174
149-
\*---------------------------------------------------------------------------*/
175+
\*---------------------------------------------------------------------------*/
150176

151177
void mbest_search450(const float *cb, float vec[], float w[], int k,int shorterK, int m, struct MBEST *mbest, int index[])
152178

src/mbest.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ struct MBEST {
4444

4545
struct MBEST *mbest_create(int entries);
4646
void mbest_destroy(struct MBEST *mbest);
47+
void mbest_precompute_weight(float cb[], float w[], int k, int m);
4748
void mbest_insert(struct MBEST *mbest, int index[], float error);
48-
void mbest_search(const float *cb, float vec[], float w[], int k, int m, struct MBEST *mbest, int index[]);
49+
void mbest_search(const float *cb, float vec[], int k, int m, struct MBEST *mbest, int index[]);
4950
void mbest_search450(const float *cb, float vec[], float w[], int k,int shorterK, int m, struct MBEST *mbest, int index[]);
5051

5152
void mbest_print(char title[], struct MBEST *mbest);

src/newamp1.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,35 +166,29 @@ float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest
166166
const float *codebook2 = newamp1vq_cb[1].cb;
167167
struct MBEST *mbest_stage1, *mbest_stage2;
168168
float target[ndim];
169-
float w[ndim];
170169
int index[MBEST_STAGES];
171170
float mse, tmp;
172171

173172
/* codebook is compiled for a fixed K */
174173

175174
assert(ndim == newamp1vq_cb[0].k);
176175

177-
/* equal weights, could be argued mel freq axis gives freq dep weighting */
178-
179-
for(i=0; i<ndim; i++)
180-
w[i] = 1.0;
181-
182176
mbest_stage1 = mbest_create(mbest_entries);
183177
mbest_stage2 = mbest_create(mbest_entries);
184178
for(i=0; i<MBEST_STAGES; i++)
185179
index[i] = 0;
186180

187181
/* Stage 1 */
188182

189-
mbest_search(codebook1, x, w, ndim, newamp1vq_cb[0].m, mbest_stage1, index);
183+
mbest_search(codebook1, x, ndim, newamp1vq_cb[0].m, mbest_stage1, index);
190184

191185
/* Stage 2 */
192186

193187
for (j=0; j<mbest_entries; j++) {
194188
index[1] = n1 = mbest_stage1->list[j].index[0];
195189
for(i=0; i<ndim; i++)
196190
target[i] = x[i] - codebook1[ndim*n1+i];
197-
mbest_search(codebook2, target, w, ndim, newamp1vq_cb[1].m, mbest_stage2, index);
191+
mbest_search(codebook2, target, ndim, newamp1vq_cb[1].m, mbest_stage2, index);
198192
}
199193

200194
n1 = mbest_stage2->list[0].index[1];

src/sine.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,11 +372,15 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float
372372
for(p=pmin; p<=pmax; p+=pstep) {
373373
E = 0.0;
374374
Wo = TWO_PI/p;
375+
376+
float bFloat = Wo * one_on_r;
377+
float currentBFloat = bFloat;
375378

376379
/* Sum harmonic magnitudes */
377380
for(m=1; m<=model->L; m++) {
378-
b = (int)(m*Wo*one_on_r + 0.5);
381+
b = (int)(currentBFloat + 0.5);
379382
E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag;
383+
currentBFloat += bFloat;
380384
}
381385
/* Compare to see if this is a maximum */
382386

0 commit comments

Comments
 (0)