SXMicrocontrollerDSPMathMethod

ulaw to 16bit linear

From Scott Dattalo

shows:

```> >            linear                            compressed
> > 12 11 10 9  8  7  6  5  4  3  2  1  0 | 6 5 4  3  2  1  0
> > ----------------------------------------------------------
> > 0   0 0  0  0  0  0  1  Q3 Q2 Q1 Q0 x   0 0 0 Q3 Q2 Q1 Q0
> > 0   0 0  0  0  0  1  Q3 Q2 Q1 Q0  x x   0 0 1 Q3 Q2 Q1 Q0
> > 0   0 0  0  0  1  Q3 Q2 Q1 Q0  x  x x   0 1 0 Q3 Q2 Q1 Q0
> > 0   0 0  0  1  Q3 Q2 Q1 Q0  x  x  x x   0 1 1 Q3 Q2 Q1 Q0
> > 0   0 0  1  Q3 Q2 Q1 Q0  x  x  x  x x   1 0 0 Q3 Q2 Q1 Q0
> > 0   0 1  Q3 Q2 Q1 Q0  x  x  x  x  x x   1 0 1 Q3 Q2 Q1 Q0
> > 0   1 Q3 Q2 Q1 Q0  x  x  x  x  x  x x   1 1 0 Q3 Q2 Q1 Q0
> > 1  Q3 Q2 Q1 Q0  x  x  x  x  x  x  x x   1 1 1 Q3 Q2 Q1 Q0
```

Now, A law has alternate bit inversion, and this only seems to have 7 bits compressed. Just remember that in the compressed for each bit is equal to 3dB up to 0dBmO.

Another search yielded a C solution:

The portion of interest:

```/*
** This routine converts from ulaw to 16 bit linear.
**
** Craig Reese: IDA/Supercomputing Research Center
** 29 September 1989
**
** References:
** 1) CCITT Recommendation G.711  (very difficult to follow)
** 2) MIL-STD-188-113,"Interoperability and Performance Standards
**     for Analog-to_Digital Conversion Techniques,"
**     17 February 1987
**
** Input: 8 bit ulaw sample
** Output: signed 16 bit linear sample
*/

int
ulaw2linear(ulawbyte)
unsigned char ulawbyte;
{
static int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764};
int sign, exponent, mantissa, sample;

ulawbyte = ~ulawbyte;
sign = (ulawbyte & 0x80);
exponent = (ulawbyte >> 4) & 0x07;
mantissa = ulawbyte & 0x0F;
sample = exp_lut[exponent] + (mantissa << (exponent + 3));
if (sign != 0) sample = -sample;

return(sample);
}
```

This is ulaw and not A-law.

...

The array exp_lut[8] can be expressed:

```exp_lut[i] = 132 *( (2^i) - 1)
```

You could use a look up table (like in the C code) or you could calculate it. But since there are only 8 cases, I think a table approach is fastest

```; ulawbyte contains the u-law encoded byte we wish to convert to it's
; linear form.
;

ulaw2linear:

mov	W, <>ulawbyte
and	W, #\$07	; Get the exponent

jmp	ulaw_exp0
jmp	ulaw_exp1
jmp	ulaw_exp2
jmp	ulaw_exp3
jmp	ulaw_exp4
jmp	ulaw_exp5
jmp	ulaw_exp6

ulaw_exp7

mov	W, <<ulawbyte
and	W, #\$1e
mov	ulaw_linhi, W

mov	W, #LOW(127*132)
mov	ulaw_linlo, W
mov	W, #HIGH(127*132)

jmp	ulaw_sign

ulaw_exp6

mov	W, <<ulawbyte
and	W, #\$1e
mov	ulaw_linhi, W

mov	W, #LOW(63*132)
mov	ulaw_linlo, W
mov	W, #HIGH(63*132)

jmp	ulaw_sign

ulaw_exp5

mov	W, ulawbyte
and	W, #\$0f
mov	ulaw_linhi, W

mov	W, #LOW(31*132)
mov	ulaw_linlo, W
mov	W, #HIGH(31*132)

jmp	ulaw_sign

ulaw_exp4

mov	W, >>ulawbyte
and	W, #\$07
mov	ulaw_linhi, W

mov	W, >>known_zero
mov	ulaw_linlo, W

mov	W, #LOW(15*132)
mov	W, #HIGH(15*132)
snb	C
inc	ulaw_linhi

jmp	ulaw_sign

ulaw_exp3

mov	W, >>ulawbyte
and	W, #\$07
mov	ulaw_linhi, W

mov	W, >>known_zero
mov	ulaw_linlo, W

rr	ulaw_linhi
rr	ulaw_linlo

mov	W, #LOW(7*132)
mov	W, #HIGH(7*132)
snb	C
inc	ulaw_linhi

jmp	ulaw_sign

ulaw_exp2
mov	W, <>ulawbyte
and	W, #\$f0
mov	ulaw_linlo, W
mov	W, <<known_zero
mov	ulaw_linhi, W

mov	W, #LOW(3*132)
mov	W, #HIGH(3*132)
snb	C
inc	ulaw_linhi

jmp	ulaw_sign

ulaw_exp0
mov	W, <>ulawbyte
mov	ulaw_linlo, W
mov	W, >>ulaw_linlo
and	W, #\$78

clr	ulaw_linhi

jmp	ulaw_sign

ulaw_exp1
mov	W, <>ulawbyte
and	W, #\$f0
mov	ulaw_linlo, W
clr	ulaw_linhi

mov	W, #LOW(1*132)
mov	W, #HIGH(1*132)
snb	C
inc	ulaw_linhi

ulaw_sign
sb	ulawbyte.7
ret

not	ulaw_linhi
not	ulaw_linlo
inc	ulaw_linhi
incsz	ulaw_linlo
dec	ulaw_linhi

ret
```

Now, this is untested and unoptimized, but it's close to being right and as fast as possible. If you want a shorter routine that's somewhat slower, then a slight modification of my last post will work. It takes advantage of the fact that:

```  132 = 4 * 33
```

and

```  (2^n - 1) * X = (X << n) - X
```

If ulawbyte is formatted:

```sxyzabcd
s - sign
xyz  - exponent
abcd - mantissa
```

Then this routine will convert it to the linear form

```	mov	W, <<ulawbyte	;w = xyzabcd?  carry = s
and	W, #\$1e	;w = 000abcd0
addlw 0x21          ;w = 001abcd1  carry=0
mov	Hack, W
mov	W, #\$21	;w = 001abcd1  carry=0

mov	ulaw_linlo, W
clr	ulaw_linhi

snb	ulawbyte.4
rl	ulaw_linlo	;01abcd10

sb	ulawbyte.5
jmp	L1

;If bit 4 and bit 5 are set then
rl	ulaw_linlo	; 1abcd100
rl	ulaw_linlo	; abcd1000
rl	ulaw_linhi	; 00000001

sb	ulawbyte.6
jmp	L2

swap	ulaw_linhi
swap	ulaw_linlo	;shift left four positions
mov	W, ulaw_linlo
and	W, #\$0f
or	ulaw_linhi, W
;;;	xor	ulaw_linlo, W	;probably unnecessary to clear lsbs
;since they are "don't cares"...

L2:
;; If the sign bit is set, then we need to compute
;;   33 - ulaw_linhi:ulaw_linhi
;; otherwise we need
;;   ulaw_linhi:ulaw_linhi - 33

mov	W, #-33
sb	C
dec	ulaw_linhi

sb	ulawbyte.7
jmp	L4

not	ulaw_linhi
not	ulaw_linlo
inc	ulaw_linhi
incsz	ulaw_linlo
dec	ulaw_linhi

L4
rl	lin_lo	;Final shift
rl	lin_hi

ret
```

 file: /Techref/scenix/lib/math/dsp/ulaw-16b-sd_sx.htm, 6KB, , updated: 2004/6/10 14:40, local time: 2024/6/19 03:17, TOP NEW HELP FIND:  100.28.132.102:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?Please DO link to this page! Digg it! / MAKE! SX Microcontroller Math Method ulaw to 16bit linear

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.

Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
 Did you find what you needed? "No. I'm looking for: " "No. Take me to the search page." "No. Take me to the top so I can drill down by catagory" "No. I'm willing to pay for help, please refer me to a qualified consultant"

 PICList 2024 contributors: o List host: MIT, Site host massmind.org, Top posters @none found - Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr.

.