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: BOOLFALSE] RETURNS [BOOL] = {
f: IO.STREAMFS.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: BOOLFALSE] RETURNS [BOOL] = {
f: IO.STREAMFS.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