MAT 201B -- Media Networks and Services
Homework Assignment #3a


Dealing with audio across a network is an interesting problem. One of the specific problems one must deal with is jitter. W. Montgomery has a paper in the December 1983 issue of the IEEE Journal on Selected Areas in Communications entitled, ``Techniques for Packet Voice Synchronization'' that deals with some of these issues.

In this assignment, you will implement a simulation to evaluate different strategies for controlling jitter in order to improve the quality of real-time audio transmitted over a packet network.

Problem Overview

Figure 1 shows a typical architecture over which real-time audio packets might flow. Handling real-time audio traffic in such an environment is non-trivial for two reasons. First, the data being transmitted is assumed to be real-time; therefore, minimizing delay is crucial. Second, the network can introduce a certain amount of jitter which must be compensated for at the receiver. If a packet is delayed long enough, it does not reach the receiver by the time it needs to be played out. If this happens, the packet is useless to the receiver, and will be discarded.

For this type of real-time operation, and for this assignment, you can assume that if the jitter causes a packet to arrive after its playback time, then the packet is lost. Since the probability of losing a packet is non-zero, the receiver must have some policy for handling playout when some packets arrive after their playback time. You will experiment with some of these different policies.

Packets can also be lost because they arrive too quickly from the transmitter; the receiver's buffer fills up; and packets must be dropped. One way to solve this problem is to create additional space in the buffer by further compressing the audio data already in the buffer. You will experiment with different mechanisms for compressing mu-law encoded data.

Simulation Model

In your simulation, you will not have to transmit packets over a network (though it really shouldn't be too difficult). One way to simulate the network is to create one procedure to transmit packets, and one procedure to receive packets. You can pass the packets between the transmitting procedure and the receiving procedure any way you want. One way might be to pass a C pointer to a data structure. You must also find a way to introduce jitter into the flow of packets from the receiver to the transmitter. One way to simulate jitter, i.e. packets arriving after their playback point, is to not deliver the packet. In your simulation, this means the packet will not be passed to the receive procedure. The receiver assumes it was lost; or arrived after the playback point, and discards the packet. The main procedure in your code should be simple. It only has to open the devices, and then start a loop to send and receive packets until there is no more sample data. The main procedure in your code might look like the following:

   while not EOF {
      read_sample();   /* Read audio sample from a file */
      play_sample();   /* Play out the received sample */


We suggest that you write this simulation in C, and run it on a Sun Sparcstation (only because this hypothetical assignment has been tested and verified there. An interesting problem would be to try this in Java or on an x86 Solaris machine.).

All the Sun Sparcstations have the same audio device interface. See the man pages for ``audio'' to get information about this interface. The man pages provide some extremely useful information about the interface, and audio data in general.

Device/File Processing

You may or may not know how to write the code to open the audio socket, and the audio data file. Since this is an implementation issue, we are providing help on the commands and syntax for opening the audio device and sample files.

To open the audio socket, use the following statement:

audio_device_ID = open("/dev/audio",O_WRONLY | O_NDELAY);

To open a file containing sample data, use the following statement:

source_file_ID = open("",O_RDONLY | O_NDELAY);

The return value of the ``open'' function is an integer that serves as the identifier for the opened device. For more information, do a ``man open''. Once the device or file is open, you can read or write using the ``read'' and ``write'' commands. Both statements have the same format, and look like the following:

return_code = read(device_identifier,buffer_variable,length);

The ``device_identifier'' is what is returned from an open command. The ``buffer_variable'' is the array used to store read data, or as a source for write data. The length specifies how long the data to be read or written is. For more information on the read or write statement, do a ``man 2v read'' or ``man 2v write''.

Sample Files

The audio data that we will be using is mu-law encoded. Part of your assignment will be to understand this encoding technique. Basically, each sample is an 8 bit non-linear value which is obtained by sampling the audio source 8000 times a second.

To help you get started, we have provided some sample audio files that you can use. These are located in the directory ``/fs/jackson/almeroth/tools/samples/*.au'' (if you cannot access these files because you do not have NMSL access, please let me know). You can also play out any sample file, or record your own samples using the programs ``audiotool'', or ``soundtool''. In order to create your own sample files, you'll need a microphone.


Your objective is to experiment with several of the parameters that affect audio quality. Using the network model discussed earlier, you will simulate a network which delivers audio packets with any level of reliability. For each parameter, you must first decide the range of values to be tested. This range should include enough points to demonstrate the affect of a parameter on audio quality. Furthermore, you should test the affects of changing these parameters on different types of audio sources, i.e. voice, music, etc. The parameters you should experiment with include the following:


For this project, you must turn in a writeup describing how your code works, what tests your performed, what results you obtained, an analysis of the results, and conclusions. Results should be shown in tables or graphs and any factors should be tested over a sufficiently wide range of values as to allow a comprehensive analysis.