SPEAKER 1: In this lab, your task is going
to be to write a program in C that changes the volume of an audio file.
Specifically, in this lab, we're going to be
working with WAV files, a standard file format for representing
audio information.
What is the structure of a WAV file?
Well, like any file, these files consist of bytes.
And in particular, in a WAV file, the first 44 bytes of that file
are the header for that WAV file that contain information about that file
that your computer, or programs on your computer,
might need to know in order to read and understand and interpret that file.
After the 44-byte header, are two byte samples of audio.
Many, many of these 2-byte samples of audio
are repeated back to back to back, where each of these 2-byte samples
represents the value of some audio waveform at a particular point in time.
So ultimately, your WAV file is going to consist of one 44-byte header followed
by many of those 2-byte samples.
And the interesting thing about those 2-byte samples
is that each one is really just a number.
And if you want to change the volume of a sample,
you're going to multiply that sample by a number.
If I have an audio sample, and I want to double the volume,
for example, I would take each of the samples of audio in the audio file
that I'm trying to modify and just multiply each of those sample values
by 2.
Likewise, if I'm trying to cut the volume in half
for a particular audio file, then I'll take each of the 2-byte samples,
and I'll multiply each by 0.5, or 1/2, in order to cut the volume in half
as well.
Ultimately, the way your program is going to work is we're going to run
our program as ./volume followed by three command line arguments.
The first command line argument is an input WAV file,
some file that already exists representing the audio file that we're
here going to try to modify.
The next command line argument is the name of some output file,
some new audio file that our program is going
to generate that is going to have the modified volume.
And finally, the last command line argument to this program
is going to be a floating point number representing
the factor by which to change the volume of the original audio file.
In this case, for example, we're using a factor of 2.0
to mean we want to double the volume of the audio file.
But if instead we had tried to use 0.5, for example, as the factor,
then we would be cutting the volume of the audio file in half.
So here's what you're going to need to do in this lab.
In order to take the input file and then generate
a new output file that's the same audio but just with the volume
changed, you're going to want to start with the header of that WAV file,
since the header, those first 44 bytes of the file
are the first thing you'll find inside the input WAV file.
So you'll initially want to read the header from the input file.
And then you'll want to write that exact same header to the output file.
After the header, recall, comes each of those 2-byte samples,
many 2 byte samples, back-to-back in the file,
representing the audio waveform of the file itself.
So you'll want to repeat, for each of those 2-byte samples,
you'll want to first read the sample from the input file,
likely into some sort of variable.
And then, you'll want to multiply that sample value by the volume factor.
If you're trying to double the volume of the sample,
then you'll double that volume.
If you're trying to triple it, you'll multiply it by 3.
If you're trying to cut the volume in half,
you'll multiply by 0.5, for example.
And after you've done that multiplication,
you'll then write that new sample to the output file.
So that the updated sample, with the modified volume,
ends up being written to the output file for each of the samples of audio
in that entire file.
As you go about working on this lab, a couple of techniques will be helpful.
One is taking advantage of the various different types
that C gives you for dealing with data of different sizes.
uint8_t, for example, is a type that stores unsigned integers that
are 8 bits, or 1-byte large.
And this is useful anytime you want to represent just a generic byte of data.
For example, if you're trying to read in a header that has 44 bytes of data,
you might use an array of 44 of these unsigned integers of 8-bit size
as uint8_ts, inside of an array, to store your header.
Meanwhile, int16_t is a type that stores signed integers,
meaning they could be positive or 0 or negative, of 16-bits, or 2-bytes, each.
And ultimately, this is a great choice of type for representing your samples.
Because we know that each sample is 2 bytes large.
And int16_t is the perfect size for representing this kind of information.
Next you're also going to want to deal with reading and writing files.
And for that, these two functions will likely prove helpful, fread and fwrite.
fread will read a certain number of bytes from some file
into memory inside of your computer.
And likewise, fwrite can write data from your computer's memory
to a particular file.
And you'll likely want to look to the documentation for each
of these functions, fread and fwrite to get an understanding for what arguments
they take in what order and how you might use these functions to read
from the input file and then write your updated data to your output file.
Now let's take a look at the distribution code
that we give to you as part of this lab.
You'll notice that one of the first things we
give you is a constant integer called HEADER_SIZE, equal to 44.
You can use this variable anytime you need
to reference the number of bytes inside of the header of a WAV file
as this constant integer called HEADER_SIZE.
Inside of the main function, we've already done some work for you.
First, checking the number of command line arguments
to ensure that when the user is running this program,
they're providing an input file, an output file,
as well as some factor by which to change the volume of the input file.
We then open the input file, checking to make sure that the input
file was able to be opened correctly.
We then open the output file using the W mode, W for writing that file,
in order to make sure that we can open the file that we're
going to be writing to correctly.
And then we compute the factor, converting that factor
to a floating point number like 2.0 for doubling the volume or 0.5
for cutting the volume in half.
Here, then, are your to dos.
The first thing you want to do is to copy the header from the input file
to the output file.
Recall that you know that header is always going to be 44 bytes.
So you'll likely want to use fread to read 44 bytes from your file
and then fwrite to write 44 new bytes to the output file.
Then you'll want to go through each of the samples,
likely using some kind of loop to loop through the input
file until you get to the end of the file.
And for each of those 2-byte samples, to read it into memory, update the volume,
and then write that updated sample to the output file as well.
You'll notice that we provide you with a sample input file, input.wav,
which you can listen to as just a sample of audio.
And you can run your volume program on this file, passing in a factor of 2.0
to double the volume, or some other factor
to change the volume by a different amount.
And then you should be able to listen to that new output file
and detect that it does, in fact, have the same audio, just
with a different volume.
After you've done all of those steps, you
should then have a program that you can take any WAV file
and change the volume by a particular factor.
My name is Brian.
And this was volume.