1 00:00:00,000 --> 00:00:00,320 2 00:00:00,320 --> 00:00:02,070 SPEAKER 1: In this lab, your task is going 3 00:00:02,070 --> 00:00:07,230 to be to write a program in C that changes the volume of an audio file. 4 00:00:07,230 --> 00:00:09,090 Specifically, in this lab, we're going to be 5 00:00:09,090 --> 00:00:12,870 working with WAV files, a standard file format for representing 6 00:00:12,870 --> 00:00:14,580 audio information. 7 00:00:14,580 --> 00:00:16,950 What is the structure of a WAV file? 8 00:00:16,950 --> 00:00:19,890 Well, like any file, these files consist of bytes. 9 00:00:19,890 --> 00:00:24,600 And in particular, in a WAV file, the first 44 bytes of that file 10 00:00:24,600 --> 00:00:29,160 are the header for that WAV file that contain information about that file 11 00:00:29,160 --> 00:00:31,530 that your computer, or programs on your computer, 12 00:00:31,530 --> 00:00:36,480 might need to know in order to read and understand and interpret that file. 13 00:00:36,480 --> 00:00:40,860 After the 44-byte header, are two byte samples of audio. 14 00:00:40,860 --> 00:00:42,810 Many, many of these 2-byte samples of audio 15 00:00:42,810 --> 00:00:46,530 are repeated back to back to back, where each of these 2-byte samples 16 00:00:46,530 --> 00:00:51,800 represents the value of some audio waveform at a particular point in time. 17 00:00:51,800 --> 00:00:56,110 So ultimately, your WAV file is going to consist of one 44-byte header followed 18 00:00:56,110 --> 00:00:58,990 by many of those 2-byte samples. 19 00:00:58,990 --> 00:01:01,930 And the interesting thing about those 2-byte samples 20 00:01:01,930 --> 00:01:04,760 is that each one is really just a number. 21 00:01:04,760 --> 00:01:07,670 And if you want to change the volume of a sample, 22 00:01:07,670 --> 00:01:11,030 you're going to multiply that sample by a number. 23 00:01:11,030 --> 00:01:13,510 If I have an audio sample, and I want to double the volume, 24 00:01:13,510 --> 00:01:17,350 for example, I would take each of the samples of audio in the audio file 25 00:01:17,350 --> 00:01:21,160 that I'm trying to modify and just multiply each of those sample values 26 00:01:21,160 --> 00:01:22,540 by 2. 27 00:01:22,540 --> 00:01:25,000 Likewise, if I'm trying to cut the volume in half 28 00:01:25,000 --> 00:01:28,930 for a particular audio file, then I'll take each of the 2-byte samples, 29 00:01:28,930 --> 00:01:34,570 and I'll multiply each by 0.5, or 1/2, in order to cut the volume in half 30 00:01:34,570 --> 00:01:36,070 as well. 31 00:01:36,070 --> 00:01:39,150 Ultimately, the way your program is going to work is we're going to run 32 00:01:39,150 --> 00:01:44,740 our program as ./volume followed by three command line arguments. 33 00:01:44,740 --> 00:01:47,580 The first command line argument is an input WAV file, 34 00:01:47,580 --> 00:01:51,540 some file that already exists representing the audio file that we're 35 00:01:51,540 --> 00:01:53,550 here going to try to modify. 36 00:01:53,550 --> 00:01:57,180 The next command line argument is the name of some output file, 37 00:01:57,180 --> 00:01:59,520 some new audio file that our program is going 38 00:01:59,520 --> 00:02:03,250 to generate that is going to have the modified volume. 39 00:02:03,250 --> 00:02:06,060 And finally, the last command line argument to this program 40 00:02:06,060 --> 00:02:08,759 is going to be a floating point number representing 41 00:02:08,759 --> 00:02:13,140 the factor by which to change the volume of the original audio file. 42 00:02:13,140 --> 00:02:16,830 In this case, for example, we're using a factor of 2.0 43 00:02:16,830 --> 00:02:20,170 to mean we want to double the volume of the audio file. 44 00:02:20,170 --> 00:02:24,420 But if instead we had tried to use 0.5, for example, as the factor, 45 00:02:24,420 --> 00:02:28,920 then we would be cutting the volume of the audio file in half. 46 00:02:28,920 --> 00:02:32,550 So here's what you're going to need to do in this lab. 47 00:02:32,550 --> 00:02:35,220 In order to take the input file and then generate 48 00:02:35,220 --> 00:02:38,940 a new output file that's the same audio but just with the volume 49 00:02:38,940 --> 00:02:42,870 changed, you're going to want to start with the header of that WAV file, 50 00:02:42,870 --> 00:02:45,720 since the header, those first 44 bytes of the file 51 00:02:45,720 --> 00:02:49,480 are the first thing you'll find inside the input WAV file. 52 00:02:49,480 --> 00:02:53,790 So you'll initially want to read the header from the input file. 53 00:02:53,790 --> 00:02:58,580 And then you'll want to write that exact same header to the output file. 54 00:02:58,580 --> 00:03:02,180 After the header, recall, comes each of those 2-byte samples, 55 00:03:02,180 --> 00:03:04,850 many 2 byte samples, back-to-back in the file, 56 00:03:04,850 --> 00:03:08,760 representing the audio waveform of the file itself. 57 00:03:08,760 --> 00:03:12,080 So you'll want to repeat, for each of those 2-byte samples, 58 00:03:12,080 --> 00:03:15,260 you'll want to first read the sample from the input file, 59 00:03:15,260 --> 00:03:17,630 likely into some sort of variable. 60 00:03:17,630 --> 00:03:22,580 And then, you'll want to multiply that sample value by the volume factor. 61 00:03:22,580 --> 00:03:25,010 If you're trying to double the volume of the sample, 62 00:03:25,010 --> 00:03:26,510 then you'll double that volume. 63 00:03:26,510 --> 00:03:28,820 If you're trying to triple it, you'll multiply it by 3. 64 00:03:28,820 --> 00:03:30,630 If you're trying to cut the volume in half, 65 00:03:30,630 --> 00:03:33,540 you'll multiply by 0.5, for example. 66 00:03:33,540 --> 00:03:35,510 And after you've done that multiplication, 67 00:03:35,510 --> 00:03:39,240 you'll then write that new sample to the output file. 68 00:03:39,240 --> 00:03:42,200 So that the updated sample, with the modified volume, 69 00:03:42,200 --> 00:03:46,460 ends up being written to the output file for each of the samples of audio 70 00:03:46,460 --> 00:03:48,760 in that entire file. 71 00:03:48,760 --> 00:03:52,700 As you go about working on this lab, a couple of techniques will be helpful. 72 00:03:52,700 --> 00:03:55,420 One is taking advantage of the various different types 73 00:03:55,420 --> 00:03:59,800 that C gives you for dealing with data of different sizes. 74 00:03:59,800 --> 00:04:05,380 uint8_t, for example, is a type that stores unsigned integers that 75 00:04:05,380 --> 00:04:08,350 are 8 bits, or 1-byte large. 76 00:04:08,350 --> 00:04:12,740 And this is useful anytime you want to represent just a generic byte of data. 77 00:04:12,740 --> 00:04:17,589 For example, if you're trying to read in a header that has 44 bytes of data, 78 00:04:17,589 --> 00:04:23,440 you might use an array of 44 of these unsigned integers of 8-bit size 79 00:04:23,440 --> 00:04:28,190 as uint8_ts, inside of an array, to store your header. 80 00:04:28,190 --> 00:04:32,930 Meanwhile, int16_t is a type that stores signed integers, 81 00:04:32,930 --> 00:04:39,020 meaning they could be positive or 0 or negative, of 16-bits, or 2-bytes, each. 82 00:04:39,020 --> 00:04:43,550 And ultimately, this is a great choice of type for representing your samples. 83 00:04:43,550 --> 00:04:46,910 Because we know that each sample is 2 bytes large. 84 00:04:46,910 --> 00:04:53,670 And int16_t is the perfect size for representing this kind of information. 85 00:04:53,670 --> 00:04:57,830 Next you're also going to want to deal with reading and writing files. 86 00:04:57,830 --> 00:05:03,470 And for that, these two functions will likely prove helpful, fread and fwrite. 87 00:05:03,470 --> 00:05:07,520 fread will read a certain number of bytes from some file 88 00:05:07,520 --> 00:05:09,870 into memory inside of your computer. 89 00:05:09,870 --> 00:05:13,340 And likewise, fwrite can write data from your computer's memory 90 00:05:13,340 --> 00:05:14,960 to a particular file. 91 00:05:14,960 --> 00:05:17,720 And you'll likely want to look to the documentation for each 92 00:05:17,720 --> 00:05:21,830 of these functions, fread and fwrite to get an understanding for what arguments 93 00:05:21,830 --> 00:05:25,940 they take in what order and how you might use these functions to read 94 00:05:25,940 --> 00:05:31,180 from the input file and then write your updated data to your output file. 95 00:05:31,180 --> 00:05:33,280 Now let's take a look at the distribution code 96 00:05:33,280 --> 00:05:35,335 that we give to you as part of this lab. 97 00:05:35,335 --> 00:05:37,210 You'll notice that one of the first things we 98 00:05:37,210 --> 00:05:42,100 give you is a constant integer called HEADER_SIZE, equal to 44. 99 00:05:42,100 --> 00:05:44,380 You can use this variable anytime you need 100 00:05:44,380 --> 00:05:48,280 to reference the number of bytes inside of the header of a WAV file 101 00:05:48,280 --> 00:05:51,810 as this constant integer called HEADER_SIZE. 102 00:05:51,810 --> 00:05:55,090 Inside of the main function, we've already done some work for you. 103 00:05:55,090 --> 00:05:57,480 First, checking the number of command line arguments 104 00:05:57,480 --> 00:06:00,390 to ensure that when the user is running this program, 105 00:06:00,390 --> 00:06:03,210 they're providing an input file, an output file, 106 00:06:03,210 --> 00:06:08,720 as well as some factor by which to change the volume of the input file. 107 00:06:08,720 --> 00:06:11,860 We then open the input file, checking to make sure that the input 108 00:06:11,860 --> 00:06:14,050 file was able to be opened correctly. 109 00:06:14,050 --> 00:06:18,563 We then open the output file using the W mode, W for writing that file, 110 00:06:18,563 --> 00:06:20,980 in order to make sure that we can open the file that we're 111 00:06:20,980 --> 00:06:22,900 going to be writing to correctly. 112 00:06:22,900 --> 00:06:25,480 And then we compute the factor, converting that factor 113 00:06:25,480 --> 00:06:30,670 to a floating point number like 2.0 for doubling the volume or 0.5 114 00:06:30,670 --> 00:06:33,260 for cutting the volume in half. 115 00:06:33,260 --> 00:06:35,210 Here, then, are your to dos. 116 00:06:35,210 --> 00:06:39,200 The first thing you want to do is to copy the header from the input file 117 00:06:39,200 --> 00:06:40,700 to the output file. 118 00:06:40,700 --> 00:06:44,300 Recall that you know that header is always going to be 44 bytes. 119 00:06:44,300 --> 00:06:48,500 So you'll likely want to use fread to read 44 bytes from your file 120 00:06:48,500 --> 00:06:52,850 and then fwrite to write 44 new bytes to the output file. 121 00:06:52,850 --> 00:06:55,490 Then you'll want to go through each of the samples, 122 00:06:55,490 --> 00:06:58,520 likely using some kind of loop to loop through the input 123 00:06:58,520 --> 00:07:01,230 file until you get to the end of the file. 124 00:07:01,230 --> 00:07:06,170 And for each of those 2-byte samples, to read it into memory, update the volume, 125 00:07:06,170 --> 00:07:10,700 and then write that updated sample to the output file as well. 126 00:07:10,700 --> 00:07:14,500 You'll notice that we provide you with a sample input file, input.wav, 127 00:07:14,500 --> 00:07:17,290 which you can listen to as just a sample of audio. 128 00:07:17,290 --> 00:07:21,850 And you can run your volume program on this file, passing in a factor of 2.0 129 00:07:21,850 --> 00:07:23,830 to double the volume, or some other factor 130 00:07:23,830 --> 00:07:26,110 to change the volume by a different amount. 131 00:07:26,110 --> 00:07:29,110 And then you should be able to listen to that new output file 132 00:07:29,110 --> 00:07:32,830 and detect that it does, in fact, have the same audio, just 133 00:07:32,830 --> 00:07:34,610 with a different volume. 134 00:07:34,610 --> 00:07:36,440 After you've done all of those steps, you 135 00:07:36,440 --> 00:07:39,500 should then have a program that you can take any WAV file 136 00:07:39,500 --> 00:07:42,590 and change the volume by a particular factor. 137 00:07:42,590 --> 00:07:43,700 My name is Brian. 138 00:07:43,700 --> 00:07:45,500 And this was volume. 139 00:07:45,500 --> 00:07:46,000