U255Impl.mesa
u-255 law conversion
takes 12 bit linear pcm and converts to u-255 8 bit and back
L. Stewart, last updated: December 22, 1983 3:04 pm
DIRECTORY
Basics,
FS,
IO,
Rope,
U255;
U255Impl: PROGRAM IMPORTS Basics, FS, IO EXPORTS U255 = BEGIN
OPEN U255;
And: PUBLIC BitOp = { RETURN[Basics.BITAND[a,b]]; };
Shift: PUBLIC BitOp = { RETURN[Basics.BITSHIFT[a,b]]; };
Or: PUBLIC BitOp = { RETURN[Basics.BITOR[a,b]]; };
Swab:
PUBLIC
PROC [a:
UNSPECIFIED]
RETURNS [
UNSPECIFIED] = {
RETURN [Shift[a, 8] + Shift [a, -8]];
};
OffToInt:
PUBLIC
PROC [i:
CARDINAL]
RETURNS [
INTEGER] = {
RETURN[Shift[i-Offset, 4]];
};
Right justified, but not offset
IntToRJInt:
PUBLIC
PROC [i:
INTEGER]
RETURNS [
INTEGER] = {
i ← Shift[i, -4];
IF And[i, 4000B] THEN i ← Basics.BITOR[i, 170000B];
RETURN[LOOPHOLE[i, INTEGER]];
};
Encode:
PUBLIC
PROC [v:
INTEGER]
RETURNS [
INTEGER] = {
exp: INTEGER ← 7;
sign: BOOLEAN ← v < 0;
{
IF sign THEN v ← -v;
v ← v + 204B;
IF v < 0 THEN GOTO Overflow;
v ← Shift[v, -2]; -- align correctly for exp=7
This loop will definitely terminate before exp goes negative.
WHILE And[v, 10000B] = 0 DO exp ← exp - 1; v ← Shift[v, 1]; ENDLOOP;
v ← Shift[v, -8];
v ← And[v, 17B];
v ← v + Shift[exp, 4];
IF sign THEN v ← v + 200B;
RETURN[v];
EXITS Overflow => IF sign THEN RETURN[377B] ELSE RETURN[177B];
};
};
Decode:
PUBLIC
PROC [v:
INTEGER]
RETURNS [
INTEGER] = {
exp: INTEGER ← And[7B, Shift[v, -4]];
sign: BOOLEAN ← And[200B, v] # 0;
v ← And[v, 17B];
v ← Shift[v, 3];
v ← v + 204B;
v ← Shift[v, exp];
v ← v - 204B;
IF sign THEN v ← -v;
RETURN[v];
};
WriteBitsFile:
PUBLIC
PROC [name: Rope.
ROPE, data:
REF
ANY, byteSwap:
BOOL ←
FALSE]
RETURNS [
BOOL] = {
f: IO.STREAM ← FS.StreamOpen[fileName: name, accessOptions: $create ! FS.Error => TRUSTED {GOTO Fail}];
IF
ISTYPE[data,
REF WTab]
THEN {
wdata: REF WTab ← NARROW[data];
p: LONG POINTER = BASE[DESCRIPTOR[wdata^]];
IF byteSwap
THEN
FOR i:
INT
IN [0..wdata.length)
DO
wdata[i] ← Swab[wdata[i]];
ENDLOOP;
f.UnsafePutBlock[[base: p, startIndex: 0, count: wdata.length*2]];
IF byteSwap
THEN
FOR i:
INT
IN [0..wdata.length)
DO
wdata[i] ← Swab[wdata[i]];
ENDLOOP;
}
ELSE {
bdata: REF BTab ← NARROW[data];
p: LONG POINTER = BASE[DESCRIPTOR[bdata^]];
f.UnsafePutBlock[[base: p, startIndex: 0, count: bdata.length]];
};
f.Close[];
RETURN [TRUE];
EXITS
Fail => RETURN [FALSE];
};
WriteTableFile:
PUBLIC
PROC [name: Rope.
ROPE, data:
REF
ANY, byteSwap:
BOOL ←
FALSE]
RETURNS [
BOOL] = {
f: IO.STREAM ← FS.StreamOpen[fileName: name, accessOptions: $create ! FS.Error => TRUSTED {GOTO Fail}];
IF
ISTYPE[data,
REF WTab]
THEN {
wdata: REF WTab ← NARROW[data];
v: INTEGER;
f.PutF["// %d by 16 table %g\n", IO.card[wdata.length], IO.rope[name]];
f.PutF[" let v = table ["];
FOR i:
CARDINAL
IN [0..wdata.length)
DO
IF i MOD 8 = 0 THEN f.PutF["\n "];
v ← wdata[i];
IF byteSwap THEN v ← Swab[v];
f.PutF[" #%06b;", IO.card[LOOPHOLE[v, CARDINAL]]];
ENDLOOP;
}
ELSE {
bdata: REF BTab ← NARROW[data];
i: CARDINAL ← 0;
v: CARDINAL;
IF bdata.length MOD 2 = 1 THEN GOTO Fail;
f.PutF["// %d by 8 table %g\n", IO.card[bdata.length], IO.rope[name]];
f.PutF["// Table is packed 2 bytes per word left to right.\n"];
f.PutF[" let v = table ["];
DO
v ← bdata[i]*256;
v ← v + bdata[i+1];
IF byteSwap THEN v ← Swab[v];
i ← i+2;
f.PutF[" #%06b;",
IO.card[v]];
IF i = bdata.length THEN EXIT;
ENDLOOP;
};
f.PutF["\n ];\n"];
f.Close[];
RETURN [TRUE];
EXITS
Fail => RETURN [FALSE];
};
END.
September 20, 1979 3:47 PM, Stewart, created
12-Jan-82 11:38:54, Stewart, Cedar
May 5, 1982 9:15 pm, added File IO stuff
L. Stewart, last updated: October 8, 1982 9:35 pm
L. Stewart, last updated: December 6, 1982 4:13 pm, Cedar 3.5
L. Stewart, last updated: December 22, 1983 3:04 pm, Cedar 5