dont rely on >> working on signed ints

This commit is contained in:
Alexandre Ratchov 2014-10-12 23:17:27 +02:00
parent d372b3a580
commit c5606fd3f3
2 changed files with 31 additions and 17 deletions

View File

@ -328,9 +328,9 @@ enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
{ {
unsigned int f; unsigned int f;
adata_t *idata; adata_t *idata;
int s; unsigned int s;
unsigned int oshift; unsigned int oshift;
int osigbit; int obias;
unsigned int obps; unsigned int obps;
unsigned int i; unsigned int i;
unsigned char *odata; unsigned char *odata;
@ -352,7 +352,7 @@ enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
idata = (adata_t *)in; idata = (adata_t *)in;
odata = out; odata = out;
oshift = p->shift; oshift = p->shift;
osigbit = p->sigbit; obias = p->bias;
obps = p->bps; obps = p->bps;
obnext = p->bnext; obnext = p->bnext;
osnext = p->snext; osnext = p->snext;
@ -362,10 +362,14 @@ enc_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
*/ */
odata += p->bfirst; odata += p->bfirst;
for (f = todo * p->nch; f > 0; f--) { for (f = todo * p->nch; f > 0; f--) {
s = *idata++; /* convert adata to u32 */
s = (int)*idata++ + ADATA_UNIT;
s <<= 32 - ADATA_BITS; s <<= 32 - ADATA_BITS;
/* convert u32 to uN */
s >>= oshift; s >>= oshift;
s ^= osigbit; /* convert uN to sN */
s -= obias;
/* packetize sN */
for (i = obps; i > 0; i--) { for (i = obps; i > 0; i--) {
*odata = (unsigned char)s; *odata = (unsigned char)s;
s >>= 8; s >>= 8;
@ -382,8 +386,9 @@ void
enc_sil_do(struct conv *p, unsigned char *out, int todo) enc_sil_do(struct conv *p, unsigned char *out, int todo)
{ {
unsigned int f; unsigned int f;
int s; unsigned int s;
int osigbit; unsigned int oshift;
int obias;
unsigned int obps; unsigned int obps;
unsigned int i; unsigned int i;
unsigned char *odata; unsigned char *odata;
@ -403,7 +408,8 @@ enc_sil_do(struct conv *p, unsigned char *out, int todo)
* order local variables more "cache-friendly". * order local variables more "cache-friendly".
*/ */
odata = out; odata = out;
osigbit = p->sigbit; oshift = p->shift;
obias = p->bias;
obps = p->bps; obps = p->bps;
obnext = p->bnext; obnext = p->bnext;
osnext = p->snext; osnext = p->snext;
@ -413,7 +419,7 @@ enc_sil_do(struct conv *p, unsigned char *out, int todo)
*/ */
odata += p->bfirst; odata += p->bfirst;
for (f = todo * p->nch; f > 0; f--) { for (f = todo * p->nch; f > 0; f--) {
s = osigbit; s = ((1 << 31) >> oshift) - obias;
for (i = obps; i > 0; i--) { for (i = obps; i > 0; i--) {
*odata = (unsigned char)s; *odata = (unsigned char)s;
s >>= 8; s >>= 8;
@ -431,12 +437,16 @@ enc_init(struct conv *p, struct aparams *par, int nch)
{ {
p->nch = nch; p->nch = nch;
p->bps = par->bps; p->bps = par->bps;
p->sigbit = par->sig ? 0 : 1 << (par->bits - 1);
if (par->msb) { if (par->msb) {
p->shift = 32 - par->bps * 8; p->shift = 32 - par->bps * 8;
} else { } else {
p->shift = 32 - par->bits; p->shift = 32 - par->bits;
} }
if (par->sig) {
p->bias = 1 << (p->shift - 1);
} else {
p->bias = 0;
}
if (!par->le) { if (!par->le) {
p->bfirst = par->bps - 1; p->bfirst = par->bps - 1;
p->bnext = -1; p->bnext = -1;
@ -466,11 +476,11 @@ dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
unsigned int f; unsigned int f;
unsigned int ibps; unsigned int ibps;
unsigned int i; unsigned int i;
int s = 0xdeadbeef; unsigned int s = 0xdeadbeef;
unsigned char *idata; unsigned char *idata;
int ibnext; int ibnext;
int isnext; int isnext;
int isigbit; int ibias;
unsigned int ishift; unsigned int ishift;
adata_t *odata; adata_t *odata;
@ -490,7 +500,7 @@ dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
odata = (adata_t *)out; odata = (adata_t *)out;
ibps = p->bps; ibps = p->bps;
ibnext = p->bnext; ibnext = p->bnext;
isigbit = p->sigbit; ibias = p->bias;
ishift = p->shift; ishift = p->shift;
isnext = p->snext; isnext = p->snext;
@ -505,10 +515,10 @@ dec_do(struct conv *p, unsigned char *in, unsigned char *out, int todo)
idata += ibnext; idata += ibnext;
} }
idata += isnext; idata += isnext;
s ^= isigbit; s += ibias;
s <<= ishift; s <<= ishift;
s >>= 32 - ADATA_BITS; s >>= 32 - ADATA_BITS;
*odata++ = s; *odata++ = s - ADATA_UNIT;
} }
} }
@ -519,13 +529,17 @@ void
dec_init(struct conv *p, struct aparams *par, int nch) dec_init(struct conv *p, struct aparams *par, int nch)
{ {
p->bps = par->bps; p->bps = par->bps;
p->sigbit = par->sig ? 0 : 1 << (par->bits - 1);
p->nch = nch; p->nch = nch;
if (par->msb) { if (par->msb) {
p->shift = 32 - par->bps * 8; p->shift = 32 - par->bps * 8;
} else { } else {
p->shift = 32 - par->bits; p->shift = 32 - par->bits;
} }
if (par->sig) {
p->bias = 1 << (p->shift - 1);
} else {
p->bias = 0;
}
if (par->le) { if (par->le) {
p->bfirst = par->bps - 1; p->bfirst = par->bps - 1;
p->bnext = -1; p->bnext = -1;

View File

@ -124,7 +124,7 @@ struct conv {
int bfirst; /* bytes to skip at startup */ int bfirst; /* bytes to skip at startup */
unsigned int bps; /* bytes per sample */ unsigned int bps; /* bytes per sample */
unsigned int shift; /* shift to get 32bit MSB */ unsigned int shift; /* shift to get 32bit MSB */
int sigbit; /* sign bits to XOR */ int bias; /* bias of unsigned samples */
int bnext; /* to reach the next byte */ int bnext; /* to reach the next byte */
int snext; /* to reach the next sample */ int snext; /* to reach the next sample */
int nch; int nch;