-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmp3.cpp
283 lines (276 loc) · 8.27 KB
/
mp3.cpp
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*-----------------------------------------------
* Mp3 ID3v1 Tag Editor (Version 1.0)
* Programmed by Mike Rosenberg
* Group: Mike Rosenberg, James Chau, Ryan Wegner
* Final Project for Professor Sengupta's CS240
* Completed 4/15/2013
* http://mikerosenberger.com
*---------------------------------------------*/
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//Create a Structure to store MP3s tagged info
struct MP3Tag
{
string Artist;
string Title;
string Album;
string Year;
string Comment;
};
//Add Functions to be used
int getsize(FILE *file);
bool checkmp3(string filename);
string ReadThirty(FILE *file, int readloc);
string Header(FILE *file, int readloc);
string Year(FILE *file, int readloc);
void ReadMP3(FILE *file, MP3Tag tag);
void WriteArtist(FILE *file, int filesize, char Artist[]);
void WriteTitle(FILE *file, int filesize, char Title[]);
void WriteAlbum(FILE *file, int filesize, char Album[]);
void WriteYear(FILE *file, int filesize, char Year[]);
void WriteComment(FILE *file, int filesize, char Comment[]);
//Begin the program
int main(int argc, char *argv[])
{
string fileloc = "";
if(argc<2)
{
cout<<"Drag and drop MP3 files to the Application!"<<endl;
//If not file dragged to exe warn user
cin.get();
return 0;
}
else
{
FILE *ifile;
for(short i=1;i<argc;i++)
{
//If file dragged attempt to open file for Reading
cout<<"Opening File: "<<argv[i]<<endl;
fileloc = argv[i];
ifile = fopen(argv[i], "r+");
}
//Assuming Opening has initiated:
if (ifile)
{
if (!checkmp3(fileloc))
{
cout << "ERROR! File Is Not An MP3 and Can Not Be Read. Please Only Use MP3 Files"<<endl;
//If File Extension is not .mp3 file clearly cannot be read/edited. Warn user and close
cin.get();
fclose(ifile);
return 0;
}
else
{
cout << "File " <<fileloc<<" Opened Successfully"<<endl; //If .mp3 opened successfully
int readloc = getsize(ifile)-128; //Go to byte location of information
int filesize = getsize(ifile);//stores the full file size needed for writing data later
string tag = Header(ifile, readloc); //read The Tag to make sure the audio file is tagged
if (tag == "TAG")
{
cout<<"File Has A Valid MP3 Tag And Will Be Read Now"<<endl<<endl;
readloc+=3; //move past Tag location to next information
MP3Tag tag; //create an MP3 Structure
//Calls Function to read all data from the MP3 file
ReadMP3(ifile, tag);
//At this point the user will be prompted with options to continue
cout << "You May Now Edit the File's Tags" <<endl;
cout << "0: Exit Program"<<endl;
cout << "1. Edit Artist"<<endl;
cout << "2. Edit Title"<<endl;
cout << "3. Edit Album"<<endl;
cout << "4. Edit Year"<<endl;
cout << "5. Edit Comment"<<endl;
cout << "6. ReRead Info"<<endl<<endl;
short r, reboot=0; //reboot to keep options in a loop, r to accept input
while (reboot<1)
{
cout << "Please Enter Your Choice And Then Press Enter: " ;
cin>>r;
switch (r) //switch-case to set what happens on user input
{
case 0:
fclose(ifile);
return (0); //if close option end the program after closing the file
break;
case 1:
char artist [31];
cout << "Enter Desired Artist Name"<<endl;
cin.ignore(); //sets break time for user to enter input
cin.getline(artist, 31); //1 byte larger then needed to make up for enter key press
WriteArtist(ifile, filesize, artist); //calls write function
break;
case 2:
char title[31];
cout << "Enter Desired Title"<<endl;
cin.ignore();
cin.getline(title, 31);
WriteTitle(ifile, filesize, title); //same info as case 1
break;
case 3:
char album[31];
cout << "Enter Desired Album Title"<<endl;
cin.ignore();
cin.getline(album, 31);
WriteAlbum(ifile, filesize, album);//same info as case 1
break;
case 4:
char year[5];
cout << "Enter Desired Release Year"<<endl;
cin.ignore();
cin.getline(year, 5);
WriteYear(ifile, filesize, year); //same info as case 1
break;
case 5:
char comment[31];
cout << "Enter Desired Comments"<<endl;
cin.ignore();
cin.getline(comment, 31);
WriteComment(ifile, filesize, comment); //same info as case 1
break;
case 6:
cout <<endl;
ReadMP3(ifile, tag); //If user enters 6 rereads mp3 info
break;
default:
cout << "The Number You Entered Is Not A Valid Option. Please Try Again" <<endl;
break; //if not option gives error message
}
}
cin.get();
fclose(ifile);//closes file and ends program
return (0);
}
else
{
cout << "File Is Not Tagged With Information. Please Try A Different MP3"<<endl;
cin.get();
fclose(ifile);// If file is not tagged gives error message, closes file and ends program
return 0;
}
}
}
else
{
cout << "Error Opening File. Press The Enter Key To Exit" <<endl;
cin.get(); //If opening error end program
return 0;
}
cin.get();
}
return(0);
}
// Functions used by the program begin here:
// *****************************************
int getsize(FILE *file)
{
//returns the size of the file as an int
int loc = ftell(file);
fseek(file,0,SEEK_END);
int size = ftell(file);
fseek(file, loc, SEEK_SET);
return size;
}
bool checkmp3(string filename)
{
//Checks if the file extension is mp3
int filetype = filename.length() - 4;
string filetipe = filename.substr(filetype, 4);
if (filetipe == ".mp3")
{
return true;
}
else
{
return false;
}
}
string Header(FILE *file, int readloc)
{
//Checks for ID3v1 Tag Header 4bytes long...
//currently only supports v1
//v1+ coming later
char magic[4];
fseek(file , readloc, SEEK_SET);
fread(magic, 1, 4, file);
string str(magic);
string mag = str.substr(0,3);
return mag;
}
string Year(FILE *file, int readloc)
{
//Reads Year Of Track...4bytes long
char magic[4];
fseek(file , readloc, SEEK_SET);
fread(magic, 1, 4, file);
string str(magic);
return str;
}
string ReadThirty(FILE *file, int readloc)
{
//Used to read Title, Artist, Album, Comment
//Each is 30 bytes long
char magic[30];
fseek(file , readloc, SEEK_SET);
fread(magic, 1, 30, file);
string str(magic);
return str;
}
void ReadMP3(FILE *file, MP3Tag tag)
{
//The following code reads the information for x bytes and then increases the readlocation x spaces
//so the next information can be read
int readloc = getsize(file)-125;
tag.Title = ReadThirty(file, readloc);
readloc+=30;
tag.Artist = ReadThirty(file, readloc);
readloc+=30;
tag.Album = ReadThirty(file, readloc);
readloc+=30;
tag.Year = Year(file, readloc);
readloc+=4;
tag.Comment = ReadThirty(file, readloc);
cout << "Artist: " <<tag.Artist<<endl;
cout << "Title: " <<tag.Title<<endl;
cout << "Album: "<<tag.Album<<endl;
cout << "Year: "<<tag.Year<<endl;
cout << "Comment: "<<tag.Comment<<endl<<endl;
}
void WriteArtist(FILE *file, int filesize, char Artist[])
{
int writeloc = filesize-95;
fseek(file, writeloc, SEEK_SET);
fwrite(Artist, 1, 30, file); //goes to the storage of Artist data and writes new data
cout << Artist << " set as The Artist"<<endl;
}
void WriteTitle(FILE *file, int filesize, char Title[])
{
int writeloc = filesize-125;
fseek(file, writeloc, SEEK_SET);
fwrite(Title, 1, 30, file); //goes to the storage of Title data and writes new data
cout << Title << " set as The Title"<<endl;
}
void WriteAlbum(FILE *file, int filesize, char Album[])
{
int writeloc = filesize-65;
fseek(file, writeloc, SEEK_SET);
fwrite(Album, 1, 30, file); //goes to the storage of Album data and writes new data
cout << Album << " set as The Album"<<endl;
}
void WriteYear(FILE *file, int filesize, char Year[])
{
int writeloc = filesize-35;
fseek(file, writeloc, SEEK_SET);
fwrite(Year, 1, 4, file); //goes to the storage of Year data and writes new data
cout << Year << " set as The Release Year"<<endl;
}
void WriteComment(FILE *file, int filesize, char Comment[])
{
int writeloc = filesize-31;
fseek(file, writeloc, SEEK_SET);
fwrite(Comment, 1, 30, file); //goes to the storage of Comment data and writes new data
cout << Comment << " set as The Comment"<<endl;
}