CS 202 - Computer Science II - Fall 2005
Lab 5 - Binary Files
Loyola College >
Department of Computer Science >
Dr. James Glenn >
CS 202 >
Labs >
Lab 5
Due
Monday, November 7th at 11:59pm.
Labs submitted one day late will be assessed a
20% penalty. Labs will not be accepted more than one day late.
Objectives
- to read and write binary files
Reading
Koffman & Wolz, Chapter 8
Introduction
Sound is created by air (or whatever) pressure changing over time.
If you graph pressure versus time for a given sound, you may come up
with a graph that looks something like this:
To represent a continuous curve digitally, we can sample it at
regular intervals. At each sample point, we measure the pressure
to the desired resolution and record the result as an integer.
As we increase the sample frequency and resolution, we will digitize the
sound more accurately. In picture above, the blue curve represents the
original sound. The tick marks along the bottom show the times at which
we take samples. The tick marks along the side reflect the resolution
of our samples; the value recorded will be that represented by the closest
tick to the actual curve. The red dots represent the samples and the white
curve represents the approximation of the original curve that our
samples give us.
If we want to create an audio file without an original sound source,
we can synthesize sounds by coming up with what the pressure vs. time
graph would be if the sound were actually played.
For example, a pure tone has a sine curve for a graph. The shorter the
period of the sine curve, the higher the tone.
Higher amplitudes represent louder pure tones. For example, if the
range of our samples is -128 to 127, then
0 61 108 127 115 76 18 -45 -96 -124 -122 -90 -35 27 83 119 126
could be the series of samples for our hypothetical sine curve.
The .au file format
An audio file must contain information about the sample range and
frequency in order to be played back correctly. Different formats
specify different ways of recording this information. For this lab,
we will create .au files. .au files begin with 6 pieces of information,
each written as a 32-bit integer. Common values are given below.
| Magic number |
0x2e736e64 (".snd" in ASCII) |
| Data offset |
24 (bigger if there is optional data between the header and samples) |
| Data size |
-1 (most players will be able to figure it out on their own) |
| Encoding format |
2 |
| Sample rate, in Hz |
44100 |
| Number of channels |
1 |
By setting up the header this way, the rest of the file can contain
samples in the range -128 to 127.
Assignment
You must complete the part of the AudioClip class that
reads and writes the files. Your code to read .au files will go
in the AudioClip constructor and the code to write .au files
will go in the write method. Both methods will make use of the
RandomAccessFile class. In particular, you will need to use
the following methods and constructor.
- RandomAccessFile(String name, String mode), which opens
a file for reading or writing depending on the mode string.
mode should be "r" for an input file and "rw"
for an output file.
- int readByte() and int readInt(), which read
8-bit and 32-bit integers. 8-bit integers are used when the data
to be stored is in the range -128 to 127 (as will be the case with
the audio sample data). 32-bit integers are
used when the data is in the range -2147483648 to 2147483647
(as for the data in the .au header).
- void writeByte(int v) and void writeInt(int v), which
write 8- and 32-bit integers.
- long length(), which returns the size, in bytes, of the
file. Note that each 8-bit sample takes up 1 byte, so the size
of the file will be approximately the same as the number of samples
(the size of the file will be a little larger because length
counts the header too).
- void seek(long pos), which sets the current position in the
file to the given position, so that the next value read (or written)
will be read from that position. This is what makes
RandomAccessFiles random access -- you don't have to read or
write data in sequential order. If you want to read data later in the
file, or reread data you have already passed, you can seek
to it and then read it.
More information can be found, of course, in the
Java documentation.
In the constructor, you should
- open the file for reading by creating an instance of RandomAccessFile,
- read and save the 6 32-bit (4-byte) values in the .au header with the
readInt method (there is a field for the sample rate; all the
others can be read into local variables),
- use seek to skip ahead to the beginning of the sample data,
- use length to figure out how many samples there are in the
file (remember to subtract anything that comes before the sample data),
- create an array to hold the samples, and
- use a loop that invokes readByte to read the samples into the
array.
To debug this code, you should see what you've read from the header. The
values should be the same as in the table given above, except for the offset
field. You may also want to display the first few samples you read, which
should be 7 7 7 7 6 7.
In write, you should
- open the output file by creating an instance of RandomAccessFile,
- write the 6 values in the header with writeInt (the
only one that needs to be different for each file is the 5th entry
for the sample rate; all the other values can be as in the table above),
- use a loop that invoked writeByte to write the data in the
sample array to the file, and
- close the file.
To test your output files, you can play them in Windows Media Player.
Extra credit
Modify write to put a message in the file after the header. To do
this, you will have to add code after you write the header but before you
write the sample data that
- writes a message using writeBytes,
- saves the current position in the file as reported by getFilePointer,
- seeks to the 4th byte in the file to position the file pointer just
before the data offset field,
- write the saved file pointer using writeInt, and
- seek back to that position using seek.
Files
The files are contained in a Java archive.
You should edit AudioClip and run AudioFun. The
archive contains
an audio sample called posse_clip.au to test your code on.
Exercises
To be done individually.
- Coming later?
Submissions
Submit the source code (.java file) for AudioClip.