Skip to content
Snippets Groups Projects
Commit 405e6a99 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by Jean-Marc Valin
Browse files

Change strategies for allocation hole prevention.

In commit ffe10574 JM added a "done" flag to the allocation
 interpolation loop: whenver a band did not have enough bits to
 pass its threshold for receiving PVQ pulses, all of the rest of
 band were given just enough bits for fine energy only.
This patch implements JM's "backwards done" idea: instead work
 backwards, dropping bands until the first band that is over the
 threshold is encountered, and don't artificially reduce the
 allocation any more after that.
This is much more stable: we can continue to signal manual skips if
 we want to, but we aren't forced to skip a large number of bands
 because of an isolated hole in he allocation.

This makes low-bitrate 120-sample frames much less rough.
It also reduces the force skip threshold from
 alloc_floor+(1<<BITRES)+1 to just alloc_floor+(1<<BITRES), because
 the former can now cascade to cause many bands to be skipped.
The difference here is subtle, and increases signaling overhead by
 0.11% of the total bitrate, but Monty confirmed that removing the
 +1 reduces noise in the bass (i.e., in N=1 bands where such a skip
 could cascade).

Finally the 64*C<<BITRES<<LM ceiling is moved into the bisection
 search, instead of just being imposed afterwards, again because I
 wouldn't want to try to explain in a spec why they're different.
parent 7627b9f6
No related branches found
No related tags found
No related merge requests found
......@@ -165,15 +165,15 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end,
int mid = (lo+hi)>>1;
psum = 0;
done = 0;
for (j=start;j<end;j++)
for (j=end;j-->start;)
{
int tmp = bits1[j] + (mid*bits2[j]>>ALLOC_STEPS);
/* Don't allocate more than we can actually use */
if (tmp >= thresh[j] && !done)
if (tmp >= thresh[j] || done)
{
psum += tmp;
} else {
done = 1;
/* Don't allocate more than we can actually use */
psum += IMIN(tmp, 64*C<<BITRES<<LM);
} else {
if (tmp >= alloc_floor)
psum += alloc_floor;
}
......@@ -186,17 +186,17 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end,
psum = 0;
/*printf ("interp bisection gave %d\n", lo);*/
done = 0;
for (j=start;j<end;j++)
for (j=end;j-->start;)
{
int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);
if (tmp < thresh[j] || done)
if (tmp < thresh[j] && !done)
{
done = 1;
if (tmp >= alloc_floor)
tmp = alloc_floor;
else
tmp = 0;
}
} else
done = 1;
/* Don't allocate more than we can actually use */
tmp = IMIN(tmp, 64*C<<BITRES<<LM);
bits[j] = tmp;
......@@ -227,9 +227,8 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end,
band_bits = bits[j] + percoeff*band_width + rem;
/*Only code a skip decision if we're above the threshold for this band.
Otherwise it is force-skipped.
This ensures that a) we have enough bits to code the skip flag and b)
there are actually some bits to redistribute.*/
if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)+1))
This ensures that we have enough bits to code the skip flag.*/
if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)))
{
if (encode)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment