-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLab3.c
241 lines (183 loc) · 5.41 KB
/
Lab3.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
* Christian Bazoian
* CS315 Lab 3: C data types
* compile with gcc -Wall Lab3.cabs in CygWin terminal
* run with ./a song.mp3
*/
#include <stdio.h>
#include <stdlib.h>
#include "Lab3.h"
int main( int argc, char ** argv )
{
const long int range = 10485760;
const long int num = 1048576;
FILE * fp = fopen(argv[1], "rb"); // open file specified in command line.
int success = initialize(argc, argv);
if(success == EXIT_FAILURE)
{
return(EXIT_FAILURE);
}
if( fp == NULL )
{
printf( "Can't open file %s\n", argv[1] );
return(EXIT_FAILURE);
}
// We now have a pointer to the first byte of data in a copy of the file, have fun
// unsigned char * data <--- this is the pointer
unsigned char* data = readFile(fp, range, num);
//find sync bits and return the pointer position after them to continue
//checking file for rest of information.
int pos = findSyncBits(fp, data);
//pointer is now at start of bit rate and frequency byte, so check bit rate
pos = findBitRate(data, pos);
//pointer is still at start of bit rate and frequency, so check second half of byte for frequency bits
pos = findFrequency(data, pos);
//pointer is now incremented to the start of the fourth and last byte of MP3 frame
pos = findCopyrightInfo(data, pos);
// Clean up
free(data);
fclose(fp); // close and free the file
exit(EXIT_SUCCESS); // or return 0;
} // end main()
// ************* Function Implementations *********************************************
int initialize(int argc, char** argv)
{
// Open the file given on the command line
if( argc != 2 )
{
printf( "Usage: %s filename.mp3\n", argv[0] );
return(EXIT_FAILURE);
}
return(EXIT_SUCCESS);
}
unsigned char* readFile(FILE * fp, long int range, long int num)
{
// Loads file into memory and returns a pointer to the beginning of it.
long size = findFileSize(fp); // go back to the beginning
if( size < 1 || size > range )
{
printf("File size is not within the allowed range\n");
// Clean up
fclose(fp); // close and free the file
exit(EXIT_SUCCESS); // or return 0;
}
printf( "File size: %ld MB\n", size/num );
// Allocate memory on the heap for a copy of the file
unsigned char * data = (unsigned char *)malloc(size);
// Read it into our block of memory
size_t bytesRead = fread( data, sizeof(unsigned char), size, fp );
if( bytesRead != size )
{
printf( "Error reading file. Unexpected number of bytes read: %zd\n",bytesRead );
// Clean up
fclose(fp); // close and free the file
free(data);
exit(EXIT_SUCCESS); // or return 0;
}
return(data);
}
int findSyncBits(FILE * fp, unsigned char * data)
{
long size = findFileSize(fp);
int i = 0;
//search for sync bits 0xFFF
while(i < size)
{
//printf("%x \n",data[i]);
//found first 8 bits
if(data[i] == 0xff)
{
//printf("Found 0xff! \n");
//check next four bits to confirm these are indeed sync bits
if(data[i++] & 00001111) // masks out the last four bits and checks half of the byte stored at this location
{
//printf("Sync bits found. \n");
//if next bit is 1, then the file is MPEG, otherwise exit program
//if(data[i++] & 00011111) //mask out all but first five bits alternate way of doing it
if(data[i++] >> 4 & 00000001) //shift bits right 4 spots
{
printf("File is MPEG. \n");
}
else
{
printf("File is not MPEG. Exiting program.");
exit(EXIT_SUCCESS);
}
//find if file is MPEG Layer 3
//shift bits right five spaces and account for whether error checking third bit is set or not
if( (data[i++] >> 5 & 00000110) || (data[i++] >> 5 & 00000010) )
{
printf("File is Layer 3.");
}
else
{
printf("File is not Layer 3. \n");
//exit(EXIT_SUCCESS);
}
break; //break out of while loop and leave pointer where it is to access rest of mp3 file
}
}
i++; //i increments in bytes, not bits
}
//shift to next byte
i++;
return(i); //returns position of pointer after the first two bytes
}
int findBitRate(unsigned char* data, int pos)
{
if(((5 << data[pos] >> 7) && (7 << data[pos] >> 7)) & 00000001)
{
printf("Bit rate: 160 \n");
}
else
{
printf("Bit rate not standard 160. \n");
}
return(pos);
}
int findFrequency(unsigned char* data, int pos)
{
//shift bits to clear out everything but the two frequency bits
if(!((2 << data[pos] >> 6) & 00000011))
{
printf("Frequency is 44.1 \n");
}
else
{
printf("Frequency not 44.1 \n");
}
pos++;
return(pos);
}
int findCopyrightInfo(unsigned char* data, int pos)
{
//shift bits right four spaces to isolate the bit telling whether file is copyrighted or not
if(!( 3 << data[pos] >> 7 & 00000001)) //if copyright bit is set to zero, file is not copyrighted
{
printf("MP3 File is not copyrighted. \n");
}
else
{
printf("File is copyrighted. \n");
}
if(!( 2 << data[pos] >> 7 ) & 00000001) //if original media bit set to 0, it is a copy and not original file
{
printf("File is a copy of original media. \n");
}
else
{
printf("File is original media. \n");
}
return(pos);
}
long findFileSize(FILE * fp)
{
// How many bytes are there in the file? If you know the OS you're
// on you can use a system API call to find out. Here we use ANSI standard
// function calls.
long size = 0;
fseek( fp, 0, SEEK_END ); // go to 0 bytes from the end
size = ftell(fp); // how far from the beginning?
rewind(fp);
return(size);
}