COS 461 Final Project Report - Philip Nikolov
Data Compression
(implemented by Philip Nikolov)
Data compression is an important
factor in handling network latency and bandwith constraints.
The scheme we employed was U-LAW.
This is a standard encoding format
in the U.S. This lossy algorithm
converts a single data sample from 16 bits
to 8 bits by making use of the fact
that the human ear is more sensitive
to sound fluctuations at low volumes.
The basic compression calls were
made through the SGI Data Compression
Library . Convenient wrappers around
those calls were provided by the
Compressor and Decompressor classes.
For more information on the
facilities we used, do "man
clIntro". (Compressor.H , Decompressor.H ,
Compressor.C , Decompressor.C )
Even if the
compression/decompression code does not look like a lot
of lines, it took quite some
programming time to get right. There were
at least three undocumented
"features" of the library, with which we
had to deal (one example). The appeal of the
library was that it was going to provide
us with an accepted industry
standard - thus opening the door to
porting and interoperability. The
disadvantage was that during the time we
fought with the library we could
have implemented our own compression.
In fact, Boris Kerbikov implemented a simple compression scheme based
on averaging of neighboring values
in the array of data samples.
The idea was given by Tim Milliron
and tests showed that we could
achieve a comression ratio of 2
without losing much in sound quality.
We decided not to use that idea
because by that time we had figured
out the peculiarities of the SGI
compression library.
Data Interpolation
(idea Tim Milliron, implemented by
Philip Nikolov)
The UDP data connection does not
guarantee arrival of every packet.
If a relatively small amount of
sound data gets lost we should be able
to do something intelligent to fill
in the gap. This is the job of the
Interpolate class. Linear
interpolation is very simple and worked well
for us. Assume that we received
packet A1, missed the next packet A2,
then received A3. Fist we
decompress the data. All packets have the
same size of N bytes, so after
decompression we get two arrays of N
shorts (sample width is 16). We want
to make up N "reasonable" samples
of sound data. (We are in MONO
mode). Let S1 be the average of the
last several shorts in the data from
A1 and S3 be the average of the
first few shorts from A3. We fill in
the gap of N shorts by
linearly interpolating between S1
and S3.
( Interpolate.H , Interpolate.C )
One of the Problems with the SGI Compression
Library
None of the manual pages inform you that the call clCompress()
can only
be invoked with a desired number of frames smaller than 50. Compressor
objects
often need to compress more than this amount of data. So a generic
class
was created to split up the compression of N frames into
manageable-size pieces.
( FrameCounter.H , FrameCounter.C )