mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
opus: hold cwrsi's row pair, and test it with one comparison
53% of the dimensions a decode walks hold no pulses, and that arm leaves _k alone, so the two CELT_PVQ_U_ROW pointers stay valid. U is non-decreasing in _k, so p <= _i < q is the single unsigned test (_i-p) < (q-p). Bit-exact over 8.2M samples. Modelled: -0.40% ARMv4, -0.78% ARMv5E; the function -4.8% and -7.1%. Measured: e200v1 39.19 -> 38.96 MHz, Clip+ 28.13 -> 28.08 MHz. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Change-Id: Id50be222e101aeabd9a1f4cf5380d3244da610ff
This commit is contained in:
parent
93d564426b
commit
5a6935047e
1 changed files with 34 additions and 6 deletions
|
|
@ -461,13 +461,21 @@ void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
|
|||
}
|
||||
|
||||
static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
|
||||
const opus_uint32 *rk;
|
||||
const opus_uint32 *rk1;
|
||||
opus_uint32 p;
|
||||
opus_uint32 d;
|
||||
int s;
|
||||
int k0;
|
||||
int kc;
|
||||
opus_int16 val;
|
||||
opus_val32 yy=0;
|
||||
celt_assert(_k>0);
|
||||
celt_assert(_n>1);
|
||||
/*_k never goes negative, so this cannot match before the pair has been
|
||||
loaded once.*/
|
||||
kc=-1;
|
||||
rk=rk1=NULL;
|
||||
while(_n>2){
|
||||
opus_uint32 q;
|
||||
/*Lots of pulses case:*/
|
||||
|
|
@ -495,12 +503,32 @@ static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
|
|||
}
|
||||
/*Lots of dimensions case:*/
|
||||
else{
|
||||
/*Are there any pulses in this dimension at all?*/
|
||||
p=CELT_PVQ_U_ROW[_k][_n];
|
||||
q=CELT_PVQ_U_ROW[_k+1][_n];
|
||||
if(p<=_i&&_i<q){
|
||||
_i-=p;
|
||||
*_y++=0;
|
||||
if(_k!=kc){
|
||||
rk=CELT_PVQ_U_ROW[_k];
|
||||
rk1=CELT_PVQ_U_ROW[_k+1];
|
||||
kc=_k;
|
||||
}
|
||||
p=rk[_n];
|
||||
q=rk1[_n];
|
||||
celt_sig_assert(p<=q);
|
||||
d=_i-p;
|
||||
if(d<q-p){
|
||||
/*None, and more than half of all dimensions end here. The next
|
||||
dimension reads the same two rows one element lower, so test it
|
||||
from inside this loop instead of going back through the dispatch
|
||||
above, which would reload both row pointers to reach it.*/
|
||||
for(;;){
|
||||
_i=d;
|
||||
*_y++=0;
|
||||
_n--;
|
||||
if(_n<=2||_k>=_n)break;
|
||||
p=rk[_n];
|
||||
q=rk1[_n];
|
||||
d=_i-p;
|
||||
if(d>=q-p)break;
|
||||
}
|
||||
/*_n is already decremented for every dimension handled above.*/
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
/*Are the pulses in this dimension negative?*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue