Windows Azure Cloud Storage ermöglicht es Ihnen bereits ab 0,10€ pro GB/Monat die Vorteile der Cloud zu nutzen.
Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Advanced Developers Conference     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Projekte ::  id3tag Klasse mit id3v1 id3v2  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Der_Knob
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.05.2001
Beiträge: 580
Beitrag Der_Knob Mitglied 17:27:24 03.02.2010   Titel:   id3tag Klasse mit id3v1 id3v2            Zitieren

Hi,

ich hab mal vor ein paar Wochen mir eine id3tag Klasse zum auslesen der Tags gebaut v1 und v2.
Der Sourcecode ist zwar nicht der beste, aber besser als nix.

Zwei Sachen gefallen mir noch nicht:
1. Wenn ein Attribute gezipped ist, wird es nicht richtig angezeigt (da hab ich dann aufgehört) - sprich der ausgelesen Text ist nicht lesbar
2. Um die Bitrate zu lesen, habe ich mir den Code von einem anderen Thread hier im Forum geholt. Hier wird die Datei dann noch mal geöffnet und diesmal mit C-Funktionen ausgelesen. Das müsste noch auf C++ umgestellt werden um sauber zu sein...

Wenn jemand lust hat, kann er ja noch die angesprochenen Punkte verbessern und hier wieder posten :D

Ist vielleicht was fürs FAQ, da ja schon öfters nach id3tag Klassen gefragt wurde.

Generell: Wenn man mehr braucht würde ich eine schon fertige Lib (z.b. http://id3lib.sourceforge.net/) benutzen. Die id3lib benutze ich selbst auch in meinen Touchscreen Projekt ( http://www.sally-project.de/ ).

C/C++ Code:
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
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
#pragma once
#include
<fstream>
#include
<string>

enum MP3TAG_VERSION {MP3TAG_VERSION_NONE, MP3TAG_VERSION_V1, MP3TAG_VERSION_V2};

class CMp3TagInfo
{
private:
    MP3TAG_VERSION    m_eMp3TagVersion;
    std::string        m_strFilename;
    bool            m_bInit;

    // Headerinfo
    std::string m_strBitRate;
    std::string m_strMpegLayer;
    std::string m_strMpegVersion;     

    // V1
    std::string m_strTagVersionNumber;
    std::string m_strArtist;
    std::string m_strTitle;
    std::string m_strAlbum;
    std::string m_strComment;
    std::string m_strTrack;
    std::string m_strYear;
    std::string m_strGenre;

    // V2 ext
    std::string m_strComposer;
    std::string m_strCopyright;
    std::string m_strOriginalArtist;
    std::string m_strURL;

    std::string    GetMp3Genre(std::string number);
    std::string    GetMp3Genre(int number);
    bool        ReadV1(const std::string& filename);
    bool        ReadV2(const std::string& filename);
    bool        FillHeaderInfos(std::string filename);
    void        CleanUp();
public:
    CMp3TagInfo();
    CMp3TagInfo(const std::string& filename);
   
    ~CMp3TagInfo();

    bool Init(const std::string& filename);

    bool            IsInit();
    MP3TAG_VERSION    GetMp3TagVersion();
    std::string        GetFilename();

    std::string GetBitRate();
    std::string GetMpegLayer();
    std::string GetMpegVersion();

    std::string GetTagVersionNumber();
    std::string GetArtist();
    std::string GetTitle();
    std::string GetAlbum();
    std::string GetComment();
    std::string GetTrack();
    std::string GetYear();
    std::string GetGenre();

    std::string GetComposer();
    std::string GetCopyright();
    std::string GetOriginalArtist();
    std::string GetURL();
};
C/C++ Code:
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
#pragma once
#include
<fstream>
#include
<string>

enum MP3TAG_VERSION {MP3TAG_VERSION_NONE, MP3TAG_VERSION_V1, MP3TAG_VERSION_V2};

class CMp3TagInfo
{
private:
MP3TAG_VERSION m_eMp3TagVersion;
std::string m_strFilename;
bool m_bInit;

// Headerinfo
std::string m_strBitRate;
std::string m_strMpegLayer;
std::string m_strMpegVersion;

// V1
std::string m_strTagVersionNumber;
std::string m_strArtist;
std::string m_strTitle;
std::string m_strAlbum;
std::string m_strComment;
std::string m_strTrack;
std::string m_strYear;
std::string m_strGenre;

// V2 ext
std::string m_strComposer;
std::string m_strCopyright;
std::string m_strOriginalArtist;
std::string m_strURL;

std::string GetMp3Genre(std::string number);
std::string GetMp3Genre(int number);
bool ReadV1(const std::string& filename);
bool ReadV2(const std::string& filename);
bool FillHeaderInfos(std::string filename);
void CleanUp();
public:
CMp3TagInfo();
CMp3TagInfo(const std::string& filename);

~CMp3TagInfo();

bool Init(const std::string& filename);

bool IsInit();
MP3TAG_VERSION GetMp3TagVersion();
std::string GetFilename();

std::string GetBitRate();
std::string GetMpegLayer();
std::string GetMpegVersion();

std::string GetTagVersionNumber();
std::string GetArtist();
std::string GetTitle();
std::string GetAlbum();
std::string GetComment();
std::string GetTrack();
std::string GetYear();
std::string GetGenre();

std::string GetComposer();
std::string GetCopyright();
std::string GetOriginalArtist();
std::string GetURL();
};
C/C++ Code:
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
#pragma once
#include
<fstream>
#include
<string>

enum MP3TAG_VERSION {MP3TAG_VERSION_NONE, MP3TAG_VERSION_V1, MP3TAG_VERSION_V2};

class CMp3TagInfo
{
private:
    MP3TAG_VERSION    m_eMp3TagVersion;
    std::string        m_strFilename;
    bool            m_bInit;

    // Headerinfo
    std::string m_strBitRate;
    std::string m_strMpegLayer;
    std::string m_strMpegVersion;     

    // V1
    std::string m_strTagVersionNumber;
    std::string m_strArtist;
    std::string m_strTitle;
    std::string m_strAlbum;
    std::string m_strComment;
    std::string m_strTrack;
    std::string m_strYear;
    std::string m_strGenre;

    // V2 ext
    std::string m_strComposer;
    std::string m_strCopyright;
    std::string m_strOriginalArtist;
    std::string m_strURL;

    std::string    GetMp3Genre(std::string number);
    std::string    GetMp3Genre(int number);
    bool        ReadV1(const std::string& filename);
    bool        ReadV2(const std::string& filename);
    bool        FillHeaderInfos(std::string filename);
    void        CleanUp();
public:
    CMp3TagInfo();
    CMp3TagInfo(const std::string& filename);
   
    ~CMp3TagInfo();

    bool Init(const std::string& filename);

    bool            IsInit();
    MP3TAG_VERSION    GetMp3TagVersion();
    std::string        GetFilename();

    std::string GetBitRate();
    std::string GetMpegLayer();
    std::string GetMpegVersion();

    std::string GetTagVersionNumber();
    std::string GetArtist();
    std::string GetTitle();
    std::string GetAlbum();
    std::string GetComment();
    std::string GetTrack();
    std::string GetYear();
    std::string GetGenre();

    std::string GetComposer();
    std::string GetCopyright();
    std::string GetOriginalArtist();
    std::string GetURL();
};

C/C++ Code:
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
#include "Mp3TagInfo.h"

// bitrate info
int bitratetable[2][16]={0,8,16,24,32,64,80,56,64,128,160,112,128,256,320,0,0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0};

// todo: put into the string utils
std::string RemoveUnnecessarySpaces(std::string inString)
{
    // Remove spaces at start
    while ((inString.length() > 0) && (inString[0] == ' '))
        inString.erase(0,1);


    // Remove spaces from end
    while ((inString.length() > 0) && (inString[inString.length() -1] == ' '))
        inString.erase(inString.length() -1,1);

    return inString;
}

CMp3TagInfo::CMp3TagInfo()
    :m_eMp3TagVersion(MP3TAG_VERSION_NONE), m_bInit(false), m_strBitRate("0")
{
}

CMp3TagInfo::CMp3TagInfo(const std::string& filename)
    :m_eMp3TagVersion(MP3TAG_VERSION_NONE), m_bInit(false), m_strBitRate("0")
{
    Init(filename);
}


CMp3TagInfo::~CMp3TagInfo()
{
}

void CMp3TagInfo::CleanUp()
{
    m_eMp3TagVersion = MP3TAG_VERSION_NONE;
    m_bInit = false;

    m_strBitRate = "0";
    m_strMpegLayer = "";
    m_strMpegVersion = "";     

    m_strArtist = "";
    m_strTitle = "";
    m_strAlbum = "";
    m_strComment = "";
    m_strTrack = "";
    m_strYear = "";
    m_strGenre = "";

    m_strComposer = "";
    m_strCopyright = "";
    m_strOriginalArtist = "";
    m_strURL = "";

    m_strFilename = "";
}

bool CMp3TagInfo::Init(const std::string& filename)
{
    // have we already loaded a file?
    // than reset all

    if (m_bInit)
        CleanUp();

    m_strFilename = filename;

    // try to read v2
    if (ReadV2(filename) == false)
    {
        // try to read v1
        if (ReadV1(filename) == false)
        {
            return false;
        }
    }

    FillHeaderInfos(filename);

    m_bInit = true;
    return true;
}

bool CMp3TagInfo::ReadV1(const std::string& filename)
{
    std::fstream file;
    file.open(filename.c_str(), std::ios::in | std::ios::binary);

    if (!file)
        return false;

    try
    {
        // go to then end
        file.seekg(-128, std::ios::end);

        // check if we have here a MP3 Tag
        char id[3];
        file.read(id, 3);
        if (strncmp(id, "TAG", 3) != 0)
            return false;

        // now read all values from the file
        char buffer[31];

        file.read(buffer, 30);
        buffer[30] = '\0';
        m_strTitle = buffer;

        file.read(buffer, 30);
        buffer[30] = '\0';
        m_strArtist = buffer;

        file.read(buffer, 30);
        buffer[30] = '\0';
        m_strAlbum = buffer;

        file.read(buffer, 4);
        buffer[4] = '\0';
        m_strYear = buffer;

        file.read(buffer, 28);
        buffer[28] = '\0';
        m_strComment = buffer;

        file.read(buffer, 2);
        buffer[2] = '\0';
        m_strTrack = buffer;

        file.read(buffer, 1);
        buffer[1] = '\0';

        m_strGenre = GetMp3Genre(buffer[0]);
    }
    catch (std::exception)
    {
        file.close();
        return false;
    }

    m_strTagVersionNumber = "1";

    // close the file
    file.close();

    // cleanup the strings
    RemoveUnnecessarySpaces(m_strTitle);
    RemoveUnnecessarySpaces(m_strArtist);
    RemoveUnnecessarySpaces(m_strAlbum);
    RemoveUnnecessarySpaces(m_strYear);
    RemoveUnnecessarySpaces(m_strComment);
    RemoveUnnecessarySpaces(m_strTrack);
    RemoveUnnecessarySpaces(m_strGenre);

    m_eMp3TagVersion = MP3TAG_VERSION_V1;
    return true;
}

bool CMp3TagInfo::ReadV2(const std::string& filename)
{
    std::fstream file;
    std::ifstream::pos_type fileSize;

    // open file
    file.open(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate);

    if (!file)
        return false;

    try
    {
        // get file length
        fileSize = file.tellg();
        file.seekg(0, std::ios::beg);

        // do we have a id3v2 tag
        char version[3];
        file.read(version, 3);

        if (strncmp(version, "ID3", 3))
        {
            // no id3v2 tag - exit
            file.close();
            return false;
        }

        // the max we read with this buffer
        char temp[10];
        int tagLength = 0;
        int headerSize = 0;
        int frameSize = 0;

        //     ID3v2/file identifier   ID3
        //     ID3v2 version           $03 00
        //     ID3v2 flags             %abc00000
        //     ID3v2 size              4 * %0xxxxxxx

        // get the version

        m_strTagVersionNumber = "2.";
        char versionTemp[11];

        file.read(temp, 1);
        int versionNumber = temp[0];
        _itoa_s(versionNumber, versionTemp, 10);
        m_strTagVersionNumber.append(versionTemp);
        m_strTagVersionNumber.append(".");

        file.read(temp, 1);
        int versionRevison = temp[0];
        _itoa_s(versionRevison, versionTemp, 10);
        m_strTagVersionNumber.append(versionTemp);

        // go to the flags
        file.read(temp, 1); // jump over the flags

        // read the length

        file.read(temp, 4);

        headerSize = ((temp[3]&0x7F) + ((temp[2]&0x7F)<<7) + ((temp[1]&0x7F)<<14)+ ((temp[0]&0x7F)<<21))-1 ;

        // now read the frames
        char frameName[5];

        file.read(frameName, 4);
        frameName[4] = '\0';

        while(((frameName[0] + frameName[1] + frameName[2] + frameName[3]) != 0)
            && (headerSize > 7) // Still more info in the file?
            )
        {
            file.read(temp, 4);

            frameSize = ( (((unsigned int)temp[3])&0x000000FF) +
                ((((unsigned int)temp[2])&0x000000FF)<<8 )+
                ((((unsigned int)temp[1])&0x000000FF)<<16)+
                ((((unsigned int)temp[0])&0x000000FF)<<24)
                );

            file.read(temp, 3);

            //if ((unsigned int) temp[0])
            bool f = ((((unsigned int)temp[0])&0x0000000F)<<4);


            // subtract bytes read from total header size
            headerSize -= (7 + frameSize);

             // is there data in this block?
            if(frameSize > 0)
            {
                char* tempFrameBuffer = new char[frameSize];
                frameSize -= 1;

                // read the frame data
                file.read(tempFrameBuffer, frameSize);
                tempFrameBuffer[frameSize] = '\0';

                if (strncmp(frameName, "TIT2", 4) == 0)
                {
                    m_strTitle = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TALB", 4) == 0)
                {
                    m_strAlbum = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TCON", 4) == 0)
                {
                    m_strGenre = GetMp3Genre(tempFrameBuffer);
                }
                else if (strncmp(frameName, "TPE1", 4) == 0)
                {
                    m_strArtist = tempFrameBuffer;
                }
                else if (strncmp(frameName, "COMM", 4) == 0)
                {
                    m_strComment = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TYER", 4) == 0)
                {
                    m_strYear = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TRCK", 4) == 0)
                {
                    m_strTrack = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TCOM", 4) == 0)
                {
                    m_strComposer = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TOPE", 4) == 0)
                {
                    m_strOriginalArtist = tempFrameBuffer;
                }
                else if (strncmp(frameName, "WCOP", 4) == 0)
                {
                    m_strCopyright = tempFrameBuffer;
                }
                else if (strncmp(frameName, "WXXX", 4) == 0)
                {
                    m_strURL = tempFrameBuffer;
                }

                delete[] tempFrameBuffer;
            }

            //////////////////////////////////////////////////////////////////////////
            // read now the next frame

            // reset the memory

            memset(frameName, 5, 0);

            // read from file, if we are not at the end
            if (file.tellg() < ((int) fileSize) - 4) {
                file.read(frameName, 4) ;
            }
        }
    }
    catch (std::exception)
    {
        file.close();
        return false;
    }

    RemoveUnnecessarySpaces(m_strTitle);
    RemoveUnnecessarySpaces(m_strArtist);
    RemoveUnnecessarySpaces(m_strAlbum);
    RemoveUnnecessarySpaces(m_strYear);
    RemoveUnnecessarySpaces(m_strComment);
    RemoveUnnecessarySpaces(m_strTrack);
    RemoveUnnecessarySpaces(m_strGenre);

    RemoveUnnecessarySpaces(m_strComposer);
    RemoveUnnecessarySpaces(m_strCopyright);
    RemoveUnnecessarySpaces(m_strOriginalArtist);
    RemoveUnnecessarySpaces(m_strURL);

    m_eMp3TagVersion = MP3TAG_VERSION_V2;

    file.close();
    return true;
}

bool CMp3TagInfo::FillHeaderInfos(std::string filename)
{
    FILE* file = NULL;
    fopen_s(&file, filename.c_str(), "rb");

    if(!file)
        return false;
   
    int curch;

    // finding first frame for MPEG 1 LAYER III
    bool flag = false;
    do {
        if ((curch = fgetc(file)) == EOF)
            return false;
        if (curch == 255)
        {
            if ((curch = fgetc(file)) == EOF)
                return false;
            if (tolower(curch/16) == 15)
                flag = true;
        }
    } while(!flag);

    // version check MPEG 1/2...
    int impegversion=tolower(((curch%16)/4)/2);
    if(impegversion==1)
        m_strMpegVersion = "MPEG 1";
    else if (impegversion==0)
        m_strMpegVersion = "MPEG 2";


    // layer check....
    int layer = tolower((((curch%16)/4)%2)*2+(((curch%16)%4)/2));
   
    switch (layer)
    {
    case 0:
        m_strMpegLayer = "Reserved";
        break;
    case 1:
        m_strMpegLayer = "Layer III";
        break;
    case 2:
        m_strMpegLayer = "Layer II";
        break;
    case 3:
        m_strMpegLayer = "Layer I";
        break;
    }

    //get next byte to read 3rd byte of header.
    if ((curch = fgetc(file)) == EOF)
        return false;

    int mp3bitrate = bitratetable[impegversion][tolower(curch/16)];
    char temp[11];
    _itoa_s(mp3bitrate, temp, 10);
    m_strBitRate = temp;

    fclose(file);

    return true;
}

std::string CMp3TagInfo::GetMp3Genre(std::string number)
{
    // is the genre for example (09) than we have to resolve the number
    if (number.length() != 4)
        return number;

    if ((number[0] != '(') || (number[3] != ')'))
        return number;

    number = number.substr(1, number.length() - 2);

    int i = atoi(number.c_str());

    return GetMp3Genre(i);
}

std::string CMp3TagInfo::GetMp3Genre(int number)
{
    switch(number)
    {
    case 0: return "Blues";
    case 1: return "Classic Rock";
    case 2: return "Country";
    case 3: return "Dance";
    case 4: return "Disco";
    case 5: return "Funk";
    case 6: return "Grunge";
    case 7: return "Hip-Hop";
    case 8: return "Jazz";
    case 9: return "Metal";
    case 10: return "New Age";
    case 11: return "Oldies";
    case 12: return "Other";
    case 13: return "Pop";
    case 14: return "R&B";
    case 15: return "Rap";
    case 16: return "Reggae";
    case 17: return "Rock";
    case 18: return "Techno";
    case 19: return "Industrial";
    case 20: return "Alternative";
    case 21: return "Ska";
    case 22: return "Death Metal";
    case 23: return "Pranks";
    case 24: return "Soundtrack";
    case 25: return "Euro-Techno";
    case 26: return "Ambient";
    case 27: return "Trip-Hop";
    case 28: return "Vocal";
    case 29: return "Jazz&Funk";
    case 30: return "Fusion";
    case 31: return "Trance";
    case 32: return "Classical";
    case 33: return "Instrumental";
    case 34: return "Acid";
    case 35: return "House";
    case 36: return "Game";
    case 37: return "Sound Clip";
    case 38: return "Gospel";
    case 39: return "Noise";
    case 40: return "Alternative Rock";
    case 41: return "Bass";
    case 42: return "Soul";
    case 43: return "Punk";
    case 44: return "Space";
    case 45: return "Meditative";
    case 46: return "Instrumental Pop";
    case 47: return "Instrumental Rock";
    case 48: return "Ethnic";
    case 49: return "Gothic";
    case 50: return "Darkwave";
    case 51: return "Techno-Industrial";
    case 52: return "Electronic";
    case 53: return "Pop-Folk";
    case 54: return "Eurodance";
    case 55: return "Dream";
    case 56: return "Southern Rock";
    case 57: return "Comedy";
    case 58: return "Cult";
    case 59: return "Gangsta";
    case 60: return "Top 40";
    case 61: return "Christian Rap";
    case 62: return "Pop/Funk";
    case 63: return "Jungle";
    case 64: return "Native US";
    case 65: return "Cabaret";
    case 66: return "New Wave";
    case 67: return "Psychedelic";
    case 68: return "Rave";
    case 69: return "Showtunes";
    case 70: return "Trailer";
    case 71: return "Lo-Fi";
    case 72: return "Tribal";
    case 73: return "Acid Punk";
    case 74: return "Acid Jazz";
    case 75: return "Polka";
    case 76: return "Retro";
    case 77: return "Musical";
    case 78: return "Rock & Roll";
    case 79: return "Hard Rock";
    case 80: return "Folk";
    case 81: return "Folk-Rock";
    case 82: return "National Folk";
    case 83: return "Swing";
    case 84: return "Fast Fusion";
    case 85: return "Bebop";
    case 86: return "Latin";
    case 87: return "Revival";
    case 88: return "Celtic";
    case 89: return "Bluegrass";
    case 90: return "Avantgarde";
    case 91: return "Gothic Rock";
    case 92: return "Progressive Rock";
    case 93: return "Psychedelic Rock";
    case 94: return "Symphonic Rock";
    case 95: return "Slow Rock";
    case 96: return "Big Band";
    case 97: return "Chorus";
    case 98: return "Easy Listening";
    case 99: return "Acoustic";
    case 100: return "Humour";
    case 101: return "Speech";
    case 102: return "Chanson";
    case 103: return "Opera";
    case 104: return "Chamber Music";
    case 105: return "Sonata";
    case 106: return "Symphony";
    case 107: return "Booty Bass";
    case 108: return "Primus";
    case 109: return "Porn Groove";
    case 110: return "Satire";
    case 111: return "Slow Jam";
    case 112: return "Club";
    case 113: return "Tango";
    case 114: return "Samba (Musik)";
    case 115: return "Folklore";
    case 116: return "Ballad";
    case 117: return "Power Ballad";
    case 118: return "Rhytmic Soul";
    case 119: return "Freestyle";
    case 120: return "Duet";
    case 121: return "Punk Rock";
    case 122: return "Drum Solo";
    case 123: return "Acapella";
    case 124: return "Euro-House";
    case 125: return "Dance Hall";
    case 126: return "Goa";
    case 127: return "Drum’n’Bass";
    case 128: return "Club-House";
    case 129: return "Hardcore";
    case 130: return "Terror";
    case 131: return "Indie";
    case 132: return "BritPop";
    case 133: return "Negerpunk";
    case 134: return "Polsk Punk";
    case 135: return "Beat";
    case 136: return "Christian Gangsta";
    case 137: return "Heavy Metal";
    case 138: return "Black Metal";
    case 139: return "Crossover";
    case 140: return "Contemporary Christian";
    case 141: return "Christian Rock";
    case 142: return "Merengue";
    case 143: return "Salsa";
    case 144: return "Thrash Metal";
    case 145: return "Anime";
    case 146: return "JPop";
    case 147: return "SynthPop";
    default: return "";
    }
}

bool CMp3TagInfo::IsInit()
{
    return m_bInit;
}

//////////////////////////////////////////////////////////////////////////
// all the getter
//////////////////////////////////////////////////////////////////////////


MP3TAG_VERSION CMp3TagInfo::GetMp3TagVersion()
{
    return m_eMp3TagVersion;
}

std::string CMp3TagInfo::GetFilename()
{
    return m_strFilename;
}

std::string CMp3TagInfo::GetBitRate()
{
    return m_strBitRate;
}

std::string CMp3TagInfo::GetMpegLayer()
{
    return m_strMpegLayer;
}

std::string CMp3TagInfo::GetMpegVersion()
{
    return m_strMpegVersion;
}

std::string CMp3TagInfo::GetTagVersionNumber()
{
    return m_strTagVersionNumber;
}

std::string CMp3TagInfo::GetArtist()
{
    return m_strArtist;
}

std::string CMp3TagInfo::GetTitle()
{
    return m_strTitle;
}

std::string CMp3TagInfo::GetAlbum()
{
    return m_strAlbum;
}

std::string CMp3TagInfo::GetComment()
{
    return m_strComment;
}

std::string CMp3TagInfo::GetTrack()
{
    return m_strTrack;
}

std::string CMp3TagInfo::GetYear()
{
    return m_strYear;
}

std::string CMp3TagInfo::GetGenre()
{
    return m_strGenre;
}

std::string CMp3TagInfo::GetComposer()
{
    return m_strComposer;
}

std::string CMp3TagInfo::GetCopyright()
{
    return m_strCopyright;
}

std::string CMp3TagInfo::GetOriginalArtist()
{
    return m_strOriginalArtist;
}

std::string CMp3TagInfo::GetURL()
{
    return m_strURL;
}
C/C++ Code:
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
#include "Mp3TagInfo.h"

// bitrate info
int bitratetable[2][16]={0,8,16,24,32,64,80,56,64,128,160,112,128,256,320,0,0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0};

// todo: put into the string utils
std::string RemoveUnnecessarySpaces(std::string inString)
{
// Remove spaces at start
while ((inString.length() > 0) && (inString[0] == ' '))
inString.erase(0,1);


// Remove spaces from end
while ((inString.length() > 0) && (inString[inString.length() -1] == ' '))
inString.erase(inString.length() -1,1);

return inString;
}

CMp3TagInfo::CMp3TagInfo()
:m_eMp3TagVersion(MP3TAG_VERSION_NONE), m_bInit(false), m_strBitRate("0")
{
}

CMp3TagInfo::CMp3TagInfo(const std::string& filename)
:m_eMp3TagVersion(MP3TAG_VERSION_NONE), m_bInit(false), m_strBitRate("0")
{
Init(filename);
}


CMp3TagInfo::~CMp3TagInfo()
{
}

void CMp3TagInfo::CleanUp()
{
m_eMp3TagVersion = MP3TAG_VERSION_NONE;
m_bInit = false;

m_strBitRate = "0";
m_strMpegLayer = "";
m_strMpegVersion = "";

m_strArtist = "";
m_strTitle = "";
m_strAlbum = "";
m_strComment = "";
m_strTrack = "";
m_strYear = "";
m_strGenre = "";

m_strComposer = "";
m_strCopyright = "";
m_strOriginalArtist = "";
m_strURL = "";

m_strFilename = "";
}

bool CMp3TagInfo::Init(const std::string& filename)
{
// have we already loaded a file?
// than reset all

if (m_bInit)
CleanUp();

m_strFilename = filename;

// try to read v2
if (ReadV2(filename) == false)
{
// try to read v1
if (ReadV1(filename) == false)
{
return false;
}
}

FillHeaderInfos(filename);

m_bInit = true;
return true;
}

bool CMp3TagInfo::ReadV1(const std::string& filename)
{
std::fstream file;
file.open(filename.c_str(), std::ios::in | std::ios::binary);

if (!file)
return false;

try
{
// go to then end
file.seekg(-128, std::ios::end);

// check if we have here a MP3 Tag
char id[3];
file.read(id, 3);
if (strncmp(id, "TAG", 3) != 0)
return false;

// now read all values from the file
char buffer[31];

file.read(buffer, 30);
buffer[30] = '\0';
m_strTitle = buffer;

file.read(buffer, 30);
buffer[30] = '\0';
m_strArtist = buffer;

file.read(buffer, 30);
buffer[30] = '\0';
m_strAlbum = buffer;

file.read(buffer, 4);
buffer[4] = '\0';
m_strYear = buffer;

file.read(buffer, 28);
buffer[28] = '\0';
m_strComment = buffer;

file.read(buffer, 2);
buffer[2] = '\0';
m_strTrack = buffer;

file.read(buffer, 1);
buffer[1] = '\0';

m_strGenre = GetMp3Genre(buffer[0]);
}
catch (std::exception)
{
file.close();
return false;
}

m_strTagVersionNumber = "1";

// close the file
file.close();

// cleanup the strings
RemoveUnnecessarySpaces(m_strTitle);
RemoveUnnecessarySpaces(m_strArtist);
RemoveUnnecessarySpaces(m_strAlbum);
RemoveUnnecessarySpaces(m_strYear);
RemoveUnnecessarySpaces(m_strComment);
RemoveUnnecessarySpaces(m_strTrack);
RemoveUnnecessarySpaces(m_strGenre);

m_eMp3TagVersion = MP3TAG_VERSION_V1;
return true;
}

bool CMp3TagInfo::ReadV2(const std::string& filename)
{
std::fstream file;
std::ifstream::pos_type fileSize;

// open file
file.open(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate);

if (!file)
return false;

try
{
// get file length
fileSize = file.tellg();
file.seekg(0, std::ios::beg);

// do we have a id3v2 tag
char version[3];
file.read(version, 3);

if (strncmp(version, "ID3", 3))
{
// no id3v2 tag - exit
file.close();
return false;
}

// the max we read with this buffer
char temp[10];
int tagLength = 0;
int headerSize = 0;
int frameSize = 0;

// ID3v2/file identifier ID3
// ID3v2 version $03 00
// ID3v2 flags %abc00000
// ID3v2 size 4 * %0xxxxxxx

// get the version

m_strTagVersionNumber = "2.";
char versionTemp[11];

file.read(temp, 1);
int versionNumber = temp[0];
_itoa_s(versionNumber, versionTemp, 10);
m_strTagVersionNumber.append(versionTemp);
m_strTagVersionNumber.append(".");

file.read(temp, 1);
int versionRevison = temp[0];
_itoa_s(versionRevison, versionTemp, 10);
m_strTagVersionNumber.append(versionTemp);

// go to the flags
file.read(temp, 1); // jump over the flags

// read the length

file.read(temp, 4);

headerSize = ((temp[3]&0x7F) + ((temp[2]&0x7F)<<7) + ((temp[1]&0x7F)<<14)+ ((temp[0]&0x7F)<<21))-1 ;

// now read the frames
char frameName[5];

file.read(frameName, 4);
frameName[4] = '\0';

while(((frameName[0] + frameName[1] + frameName[2] + frameName[3]) != 0)
&& (headerSize > 7) // Still more info in the file?
)
{
file.read(temp, 4);

frameSize = ( (((unsigned int)temp[3])&0x000000FF) +
((((unsigned int)temp[2])&0x000000FF)<<8 )+
((((unsigned int)temp[1])&0x000000FF)<<16)+
((((unsigned int)temp[0])&0x000000FF)<<24)
);

file.read(temp, 3);

//if ((unsigned int) temp[0])
bool f = ((((unsigned int)temp[0])&0x0000000F)<<4);


// subtract bytes read from total header size
headerSize -= (7 + frameSize);

// is there data in this block?
if(frameSize > 0)
{
char* tempFrameBuffer = new char[frameSize];
frameSize -= 1;

// read the frame data
file.read(tempFrameBuffer, frameSize);
tempFrameBuffer[frameSize] = '\0';

if (strncmp(frameName, "TIT2", 4) == 0)
{
m_strTitle = tempFrameBuffer;
}
else if (strncmp(frameName, "TALB", 4) == 0)
{
m_strAlbum = tempFrameBuffer;
}
else if (strncmp(frameName, "TCON", 4) == 0)
{
m_strGenre = GetMp3Genre(tempFrameBuffer);
}
else if (strncmp(frameName, "TPE1", 4) == 0)
{
m_strArtist = tempFrameBuffer;
}
else if (strncmp(frameName, "COMM", 4) == 0)
{
m_strComment = tempFrameBuffer;
}
else if (strncmp(frameName, "TYER", 4) == 0)
{
m_strYear = tempFrameBuffer;
}
else if (strncmp(frameName, "TRCK", 4) == 0)
{
m_strTrack = tempFrameBuffer;
}
else if (strncmp(frameName, "TCOM", 4) == 0)
{
m_strComposer = tempFrameBuffer;
}
else if (strncmp(frameName, "TOPE", 4) == 0)
{
m_strOriginalArtist = tempFrameBuffer;
}
else if (strncmp(frameName, "WCOP", 4) == 0)
{
m_strCopyright = tempFrameBuffer;
}
else if (strncmp(frameName, "WXXX", 4) == 0)
{
m_strURL = tempFrameBuffer;
}

delete[] tempFrameBuffer;
}

//////////////////////////////////////////////////////////////////////////
// read now the next frame

// reset the memory

memset(frameName, 5, 0);

// read from file, if we are not at the end
if (file.tellg() < ((int) fileSize) - 4) {
file.read(frameName, 4) ;
}
}
}
catch (std::exception)
{
file.close();
return false;
}

RemoveUnnecessarySpaces(m_strTitle);
RemoveUnnecessarySpaces(m_strArtist);
RemoveUnnecessarySpaces(m_strAlbum);
RemoveUnnecessarySpaces(m_strYear);
RemoveUnnecessarySpaces(m_strComment);
RemoveUnnecessarySpaces(m_strTrack);
RemoveUnnecessarySpaces(m_strGenre);

RemoveUnnecessarySpaces(m_strComposer);
RemoveUnnecessarySpaces(m_strCopyright);
RemoveUnnecessarySpaces(m_strOriginalArtist);
RemoveUnnecessarySpaces(m_strURL);

m_eMp3TagVersion = MP3TAG_VERSION_V2;

file.close();
return true;
}

bool CMp3TagInfo::FillHeaderInfos(std::string filename)
{
FILE* file = NULL;
fopen_s(&file, filename.c_str(), "rb");

if(!file)
return false;

int curch;

// finding first frame for MPEG 1 LAYER III
bool flag = false;
do {
if ((curch = fgetc(file)) == EOF)
return false;
if (curch == 255)
{
if ((curch = fgetc(file)) == EOF)
return false;
if (tolower(curch/16) == 15)
flag = true;
}
} while(!flag);

// version check MPEG 1/2...
int impegversion=tolower(((curch%16)/4)/2);
if(impegversion==1)
m_strMpegVersion = "MPEG 1";
else if (impegversion==0)
m_strMpegVersion = "MPEG 2";


// layer check....
int layer = tolower((((curch%16)/4)%2)*2+(((curch%16)%4)/2));

switch (layer)
{
case 0:
m_strMpegLayer = "Reserved";
break;
case 1:
m_strMpegLayer = "Layer III";
break;
case 2:
m_strMpegLayer = "Layer II";
break;
case 3:
m_strMpegLayer = "Layer I";
break;
}

//get next byte to read 3rd byte of header.
if ((curch = fgetc(file)) == EOF)
return false;

int mp3bitrate = bitratetable[impegversion][tolower(curch/16)];
char temp[11];
_itoa_s(mp3bitrate, temp, 10);
m_strBitRate = temp;

fclose(file);

return true;
}

std::string CMp3TagInfo::GetMp3Genre(std::string number)
{
// is the genre for example (09) than we have to resolve the number
if (number.length() != 4)
return number;

if ((number[0] != '(') || (number[3] != ')'))
return number;

number = number.substr(1, number.length() - 2);

int i = atoi(number.c_str());

return GetMp3Genre(i);
}

std::string CMp3TagInfo::GetMp3Genre(int number)
{
switch(number)
{
case 0: return "Blues";
case 1: return "Classic Rock";
case 2: return "Country";
case 3: return "Dance";
case 4: return "Disco";
case 5: return "Funk";
case 6: return "Grunge";
case 7: return "Hip-Hop";
case 8: return "Jazz";
case 9: return "Metal";
case 10: return "New Age";
case 11: return "Oldies";
case 12: return "Other";
case 13: return "Pop";
case 14: return "R&B";
case 15: return "Rap";
case 16: return "Reggae";
case 17: return "Rock";
case 18: return "Techno";
case 19: return "Industrial";
case 20: return "Alternative";
case 21: return "Ska";
case 22: return "Death Metal";
case 23: return "Pranks";
case 24: return "Soundtrack";
case 25: return "Euro-Techno";
case 26: return "Ambient";
case 27: return "Trip-Hop";
case 28: return "Vocal";
case 29: return "Jazz&Funk";
case 30: return "Fusion";
case 31: return "Trance";
case 32: return "Classical";
case 33: return "Instrumental";
case 34: return "Acid";
case 35: return "House";
case 36: return "Game";
case 37: return "Sound Clip";
case 38: return "Gospel";
case 39: return "Noise";
case 40: return "Alternative Rock";
case 41: return "Bass";
case 42: return "Soul";
case 43: return "Punk";
case 44: return "Space";
case 45: return "Meditative";
case 46: return "Instrumental Pop";
case 47: return "Instrumental Rock";
case 48: return "Ethnic";
case 49: return "Gothic";
case 50: return "Darkwave";
case 51: return "Techno-Industrial";
case 52: return "Electronic";
case 53: return "Pop-Folk";
case 54: return "Eurodance";
case 55: return "Dream";
case 56: return "Southern Rock";
case 57: return "Comedy";
case 58: return "Cult";
case 59: return "Gangsta";
case 60: return "Top 40";
case 61: return "Christian Rap";
case 62: return "Pop/Funk";
case 63: return "Jungle";
case 64: return "Native US";
case 65: return "Cabaret";
case 66: return "New Wave";
case 67: return "Psychedelic";
case 68: return "Rave";
case 69: return "Showtunes";
case 70: return "Trailer";
case 71: return "Lo-Fi";
case 72: return "Tribal";
case 73: return "Acid Punk";
case 74: return "Acid Jazz";
case 75: return "Polka";
case 76: return "Retro";
case 77: return "Musical";
case 78: return "Rock & Roll";
case 79: return "Hard Rock";
case 80: return "Folk";
case 81: return "Folk-Rock";
case 82: return "National Folk";
case 83: return "Swing";
case 84: return "Fast Fusion";
case 85: return "Bebop";
case 86: return "Latin";
case 87: return "Revival";
case 88: return "Celtic";
case 89: return "Bluegrass";
case 90: return "Avantgarde";
case 91: return "Gothic Rock";
case 92: return "Progressive Rock";
case 93: return "Psychedelic Rock";
case 94: return "Symphonic Rock";
case 95: return "Slow Rock";
case 96: return "Big Band";
case 97: return "Chorus";
case 98: return "Easy Listening";
case 99: return "Acoustic";
case 100: return "Humour";
case 101: return "Speech";
case 102: return "Chanson";
case 103: return "Opera";
case 104: return "Chamber Music";
case 105: return "Sonata";
case 106: return "Symphony";
case 107: return "Booty Bass";
case 108: return "Primus";
case 109: return "Porn Groove";
case 110: return "Satire";
case 111: return "Slow Jam";
case 112: return "Club";
case 113: return "Tango";
case 114: return "Samba (Musik)";
case 115: return "Folklore";
case 116: return "Ballad";
case 117: return "Power Ballad";
case 118: return "Rhytmic Soul";
case 119: return "Freestyle";
case 120: return "Duet";
case 121: return "Punk Rock";
case 122: return "Drum Solo";
case 123: return "Acapella";
case 124: return "Euro-House";
case 125: return "Dance Hall";
case 126: return "Goa";
case 127: return "Drum’n’Bass";
case 128: return "Club-House";
case 129: return "Hardcore";
case 130: return "Terror";
case 131: return "Indie";
case 132: return "BritPop";
case 133: return "Negerpunk";
case 134: return "Polsk Punk";
case 135: return "Beat";
case 136: return "Christian Gangsta";
case 137: return "Heavy Metal";
case 138: return "Black Metal";
case 139: return "Crossover";
case 140: return "Contemporary Christian";
case 141: return "Christian Rock";
case 142: return "Merengue";
case 143: return "Salsa";
case 144: return "Thrash Metal";
case 145: return "Anime";
case 146: return "JPop";
case 147: return "SynthPop";
default: return "";
}
}

bool CMp3TagInfo::IsInit()
{
return m_bInit;
}

//////////////////////////////////////////////////////////////////////////
// all the getter
//////////////////////////////////////////////////////////////////////////


MP3TAG_VERSION CMp3TagInfo::GetMp3TagVersion()
{
return m_eMp3TagVersion;
}

std::string CMp3TagInfo::GetFilename()
{
return m_strFilename;
}

std::string CMp3TagInfo::GetBitRate()
{
return m_strBitRate;
}

std::string CMp3TagInfo::GetMpegLayer()
{
return m_strMpegLayer;
}

std::string CMp3TagInfo::GetMpegVersion()
{
return m_strMpegVersion;
}

std::string CMp3TagInfo::GetTagVersionNumber()
{
return m_strTagVersionNumber;
}

std::string CMp3TagInfo::GetArtist()
{
return m_strArtist;
}

std::string CMp3TagInfo::GetTitle()
{
return m_strTitle;
}

std::string CMp3TagInfo::GetAlbum()
{
return m_strAlbum;
}

std::string CMp3TagInfo::GetComment()
{
return m_strComment;
}

std::string CMp3TagInfo::GetTrack()
{
return m_strTrack;
}

std::string CMp3TagInfo::GetYear()
{
return m_strYear;
}

std::string CMp3TagInfo::GetGenre()
{
return m_strGenre;
}

std::string CMp3TagInfo::GetComposer()
{
return m_strComposer;
}

std::string CMp3TagInfo::GetCopyright()
{
return m_strCopyright;
}

std::string CMp3TagInfo::GetOriginalArtist()
{
return m_strOriginalArtist;
}

std::string CMp3TagInfo::GetURL()
{
return m_strURL;
}
C/C++ Code:
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
#include "Mp3TagInfo.h"

// bitrate info
int bitratetable[2][16]={0,8,16,24,32,64,80,56,64,128,160,112,128,256,320,0,0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0};

// todo: put into the string utils
std::string RemoveUnnecessarySpaces(std::string inString)
{
    // Remove spaces at start
    while ((inString.length() > 0) && (inString[0] == ' '))
        inString.erase(0,1);


    // Remove spaces from end
    while ((inString.length() > 0) && (inString[inString.length() -1] == ' '))
        inString.erase(inString.length() -1,1);

    return inString;
}

CMp3TagInfo::CMp3TagInfo()
    :m_eMp3TagVersion(MP3TAG_VERSION_NONE), m_bInit(false), m_strBitRate("0")
{
}

CMp3TagInfo::CMp3TagInfo(const std::string& filename)
    :m_eMp3TagVersion(MP3TAG_VERSION_NONE), m_bInit(false), m_strBitRate("0")
{
    Init(filename);
}


CMp3TagInfo::~CMp3TagInfo()
{
}

void CMp3TagInfo::CleanUp()
{
    m_eMp3TagVersion = MP3TAG_VERSION_NONE;
    m_bInit = false;

    m_strBitRate = "0";
    m_strMpegLayer = "";
    m_strMpegVersion = "";     

    m_strArtist = "";
    m_strTitle = "";
    m_strAlbum = "";
    m_strComment = "";
    m_strTrack = "";
    m_strYear = "";
    m_strGenre = "";

    m_strComposer = "";
    m_strCopyright = "";
    m_strOriginalArtist = "";
    m_strURL = "";

    m_strFilename = "";
}

bool CMp3TagInfo::Init(const std::string& filename)
{
    // have we already loaded a file?
    // than reset all

    if (m_bInit)
        CleanUp();

    m_strFilename = filename;

    // try to read v2
    if (ReadV2(filename) == false)
    {
        // try to read v1
        if (ReadV1(filename) == false)
        {
            return false;
        }
    }

    FillHeaderInfos(filename);

    m_bInit = true;
    return true;
}

bool CMp3TagInfo::ReadV1(const std::string& filename)
{
    std::fstream file;
    file.open(filename.c_str(), std::ios::in | std::ios::binary);

    if (!file)
        return false;

    try
    {
        // go to then end
        file.seekg(-128, std::ios::end);

        // check if we have here a MP3 Tag
        char id[3];
        file.read(id, 3);
        if (strncmp(id, "TAG", 3) != 0)
            return false;

        // now read all values from the file
        char buffer[31];

        file.read(buffer, 30);
        buffer[30] = '\0';
        m_strTitle = buffer;

        file.read(buffer, 30);
        buffer[30] = '\0';
        m_strArtist = buffer;

        file.read(buffer, 30);
        buffer[30] = '\0';
        m_strAlbum = buffer;

        file.read(buffer, 4);
        buffer[4] = '\0';
        m_strYear = buffer;

        file.read(buffer, 28);
        buffer[28] = '\0';
        m_strComment = buffer;

        file.read(buffer, 2);
        buffer[2] = '\0';
        m_strTrack = buffer;

        file.read(buffer, 1);
        buffer[1] = '\0';

        m_strGenre = GetMp3Genre(buffer[0]);
    }
    catch (std::exception)
    {
        file.close();
        return false;
    }

    m_strTagVersionNumber = "1";

    // close the file
    file.close();

    // cleanup the strings
    RemoveUnnecessarySpaces(m_strTitle);
    RemoveUnnecessarySpaces(m_strArtist);
    RemoveUnnecessarySpaces(m_strAlbum);
    RemoveUnnecessarySpaces(m_strYear);
    RemoveUnnecessarySpaces(m_strComment);
    RemoveUnnecessarySpaces(m_strTrack);
    RemoveUnnecessarySpaces(m_strGenre);

    m_eMp3TagVersion = MP3TAG_VERSION_V1;
    return true;
}

bool CMp3TagInfo::ReadV2(const std::string& filename)
{
    std::fstream file;
    std::ifstream::pos_type fileSize;

    // open file
    file.open(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate);

    if (!file)
        return false;

    try
    {
        // get file length
        fileSize = file.tellg();
        file.seekg(0, std::ios::beg);

        // do we have a id3v2 tag
        char version[3];
        file.read(version, 3);

        if (strncmp(version, "ID3", 3))
        {
            // no id3v2 tag - exit
            file.close();
            return false;
        }

        // the max we read with this buffer
        char temp[10];
        int tagLength = 0;
        int headerSize = 0;
        int frameSize = 0;

        //     ID3v2/file identifier   ID3
        //     ID3v2 version           $03 00
        //     ID3v2 flags             %abc00000
        //     ID3v2 size              4 * %0xxxxxxx

        // get the version

        m_strTagVersionNumber = "2.";
        char versionTemp[11];

        file.read(temp, 1);
        int versionNumber = temp[0];
        _itoa_s(versionNumber, versionTemp, 10);
        m_strTagVersionNumber.append(versionTemp);
        m_strTagVersionNumber.append(".");

        file.read(temp, 1);
        int versionRevison = temp[0];
        _itoa_s(versionRevison, versionTemp, 10);
        m_strTagVersionNumber.append(versionTemp);

        // go to the flags
        file.read(temp, 1); // jump over the flags

        // read the length

        file.read(temp, 4);

        headerSize = ((temp[3]&0x7F) + ((temp[2]&0x7F)<<7) + ((temp[1]&0x7F)<<14)+ ((temp[0]&0x7F)<<21))-1 ;

        // now read the frames
        char frameName[5];

        file.read(frameName, 4);
        frameName[4] = '\0';

        while(((frameName[0] + frameName[1] + frameName[2] + frameName[3]) != 0)
            && (headerSize > 7) // Still more info in the file?
            )
        {
            file.read(temp, 4);

            frameSize = ( (((unsigned int)temp[3])&0x000000FF) +
                ((((unsigned int)temp[2])&0x000000FF)<<8 )+
                ((((unsigned int)temp[1])&0x000000FF)<<16)+
                ((((unsigned int)temp[0])&0x000000FF)<<24)
                );

            file.read(temp, 3);

            //if ((unsigned int) temp[0])
            bool f = ((((unsigned int)temp[0])&0x0000000F)<<4);


            // subtract bytes read from total header size
            headerSize -= (7 + frameSize);

             // is there data in this block?
            if(frameSize > 0)
            {
                char* tempFrameBuffer = new char[frameSize];
                frameSize -= 1;

                // read the frame data
                file.read(tempFrameBuffer, frameSize);
                tempFrameBuffer[frameSize] = '\0';

                if (strncmp(frameName, "TIT2", 4) == 0)
                {
                    m_strTitle = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TALB", 4) == 0)
                {
                    m_strAlbum = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TCON", 4) == 0)
                {
                    m_strGenre = GetMp3Genre(tempFrameBuffer);
                }
                else if (strncmp(frameName, "TPE1", 4) == 0)
                {
                    m_strArtist = tempFrameBuffer;
                }
                else if (strncmp(frameName, "COMM", 4) == 0)
                {
                    m_strComment = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TYER", 4) == 0)
                {
                    m_strYear = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TRCK", 4) == 0)
                {
                    m_strTrack = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TCOM", 4) == 0)
                {
                    m_strComposer = tempFrameBuffer;
                }
                else if (strncmp(frameName, "TOPE", 4) == 0)
                {
                    m_strOriginalArtist = tempFrameBuffer;
                }
                else if (strncmp(frameName, "WCOP", 4) == 0)
                {
                    m_strCopyright = tempFrameBuffer;
                }
                else if (strncmp(frameName, "WXXX", 4) == 0)
                {
                    m_strURL = tempFrameBuffer;
                }

                delete[] tempFrameBuffer;
            }

            //////////////////////////////////////////////////////////////////////////
            // read now the next frame

            // reset the memory

            memset(frameName, 5, 0);

            // read from file, if we are not at the end
            if (file.tellg() < ((int) fileSize) - 4) {
                file.read(frameName, 4) ;
            }
        }
    }
    catch (std::exception)
    {
        file.close();
        return false;
    }

    RemoveUnnecessarySpaces(m_strTitle);
    RemoveUnnecessarySpaces(m_strArtist);
    RemoveUnnecessarySpaces(m_strAlbum);
    RemoveUnnecessarySpaces(m_strYear);
    RemoveUnnecessarySpaces(m_strComment);
    RemoveUnnecessarySpaces(m_strTrack);
    RemoveUnnecessarySpaces(m_strGenre);

    RemoveUnnecessarySpaces(m_strComposer);
    RemoveUnnecessarySpaces(m_strCopyright);
    RemoveUnnecessarySpaces(m_strOriginalArtist);
    RemoveUnnecessarySpaces(m_strURL);

    m_eMp3TagVersion = MP3TAG_VERSION_V2;

    file.close();
    return true;
}

bool CMp3TagInfo::FillHeaderInfos(std::string filename)
{
    FILE* file = NULL;
    fopen_s(&file, filename.c_str(), "rb");

    if(!file)
        return false;
   
    int curch;

    // finding first frame for MPEG 1 LAYER III
    bool flag = false;
    do {
        if ((curch = fgetc(file)) == EOF)
            return false;
        if (curch == 255)
        {
            if ((curch = fgetc(file)) == EOF)
                return false;
            if (tolower(curch/16) == 15)
                flag = true;
        }
    } while(!flag);

    // version check MPEG 1/2...
    int impegversion=tolower(((curch%16)/4)/2);
    if(impegversion==1)
        m_strMpegVersion = "MPEG 1";
    else if (impegversion==0)
        m_strMpegVersion = "MPEG 2";


    // layer check....
    int layer = tolower((((curch%16)/4)%2)*2+(((curch%16)%4)/2));
   
    switch (layer)
    {
    case 0:
        m_strMpegLayer = "Reserved";
        break;
    case 1:
        m_strMpegLayer = "Layer III";
        break;
    case 2:
        m_strMpegLayer = "Layer II";
        break;
    case 3:
        m_strMpegLayer = "Layer I";
        break;
    }

    //get next byte to read 3rd byte of header.
    if ((curch = fgetc(file)) == EOF)
        return false;

    int mp3bitrate = bitratetable[impegversion][tolower(curch/16)];
    char temp[11];
    _itoa_s(mp3bitrate, temp, 10);
    m_strBitRate = temp;

    fclose(file);

    return true;
}

std::string CMp3TagInfo::GetMp3Genre(std::string number)
{
    // is the genre for example (09) than we have to resolve the number
    if (number.length() != 4)
        return number;

    if ((number[0] != '(') || (number[3] != ')'))
        return number;

    number = number.substr(1, number.length() - 2);

    int i = atoi(number.c_str());

    return GetMp3Genre(i);
}

std::string CMp3TagInfo::GetMp3Genre(int number)
{
    switch(number)
    {
    case 0: return "Blues";
    case 1: return "Classic Rock";
    case 2: return "Country";
    case 3: return "Dance";
    case 4: return "Disco";
    case 5: return "Funk";
    case 6: return "Grunge";
    case 7: return "Hip-Hop";
    case 8: return "Jazz";
    case 9: return "Metal";
    case 10: return "New Age";
    case 11: return "Oldies";
    case 12: return "Other";
    case 13: return "Pop";
    case 14: return "R&B";
    case 15: return "Rap";
    case 16: return "Reggae";
    case 17: return "Rock";
    case 18: return "Techno";
    case 19: return "Industrial";
    case 20: return "Alternative";
    case 21: return "Ska";
    case 22: return "Death Metal";
    case 23: return "Pranks";
    case 24: return "Soundtrack";
    case 25: return "Euro-Techno";
    case 26: return "Ambient";
    case 27: return "Trip-Hop";
    case 28: return "Vocal";
    case 29: return "Jazz&Funk";
    case 30: return "Fusion";
    case 31: return "Trance";
    case 32: return "Classical";
    case 33: return "Instrumental";
    case 34: return "Acid";
    case 35: return "House";
    case 36: return "Game";
    case 37: return "Sound Clip";
    case 38: return "Gospel";
    case 39: return "Noise";
    case 40: return "Alternative Rock";
    case 41: return "Bass";
    case 42: return "Soul";
    case 43: return "Punk";
    case 44: return "Space";
    case 45: return "Meditative";
    case 46: return "Instrumental Pop";
    case 47: return "Instrumental Rock";
    case 48: return "Ethnic";
    case 49: return "Gothic";
    case 50: return "Darkwave";
    case 51: return "Techno-Industrial";
    case 52: return "Electronic";
    case 53: return "Pop-Folk";
    case 54: return "Eurodance";
    case 55: return "Dream";
    case 56: return "Southern Rock";
    case 57: return "Comedy";
    case 58: return "Cult";
    case 59: return "Gangsta";
    case 60: return "Top 40";
    case 61: return "Christian Rap";
    case 62: return "Pop/Funk";
    case 63: return "Jungle";
    case 64: return "Native US";
    case 65: return "Cabaret";
    case 66: return "New Wave";
    case 67: return "Psychedelic";
    case 68: return "Rave";
    case 69: return "Showtunes";
    case 70: return "Trailer";
    case 71: return "Lo-Fi";
    case 72: return "Tribal";
    case 73: return "Acid Punk";
    case 74: return "Acid Jazz";
    case 75: return "Polka";
    case 76: return "Retro";
    case 77: return "Musical";
    case 78: return "Rock & Roll";
    case 79: return "Hard Rock";
    case 80: return "Folk";
    case 81: return "Folk-Rock";
    case 82: return "National Folk";
    case 83: return "Swing";
    case 84: return "Fast Fusion";
    case 85: return "Bebop";
    case 86: return "Latin";
    case 87: return "Revival";
    case 88: return "Celtic";
    case 89: return "Bluegrass";
    case 90: return "Avantgarde";
    case 91: return "Gothic Rock";
    case 92: return "Progressive Rock";
    case 93: return "Psychedelic Rock";
    case 94: return "Symphonic Rock";
    case 95: return "Slow Rock";
    case 96: return "Big Band";
    case 97: return "Chorus";
    case 98: return "Easy Listening";
    case 99: return "Acoustic";
    case 100: return "Humour";
    case 101: return "Speech";
    case 102: return "Chanson";
    case 103: return "Opera";
    case 104: return "Chamber Music";
    case 105: return "Sonata";
    case 106: return "Symphony";
    case 107: return "Booty Bass";
    case 108: return "Primus";
    case 109: return "Porn Groove";
    case 110: return "Satire";
    case 111: return "Slow Jam";
    case 112: return "Club";
    case 113: return "Tango";
    case 114: return "Samba (Musik)";
    case 115: return "Folklore";
    case 116: return "Ballad";
    case 117: return "Power Ballad";
    case 118: return "Rhytmic Soul";
    case 119: return "Freestyle";
    case 120: return "Duet";
    case 121: return "Punk Rock";
    case 122: return "Drum Solo";
    case 123: return "Acapella";
    case 124: return "Euro-House";
    case 125: return "Dance Hall";
    case 126: return "Goa";
    case 127: return "Drum’n’Bass";
    case 128: return "Club-House";
    case 129: return "Hardcore";
    case 130: return "Terror";
    case 131: return "Indie";
    case 132: return "BritPop";
    case 133: return "Negerpunk";
    case 134: return "Polsk Punk";
    case 135: return "Beat";
    case 136: return "Christian Gangsta";
    case 137: return "Heavy Metal";
    case 138: return "Black Metal";
    case 139: return "Crossover";
    case 140: return "Contemporary Christian";
    case 141: return "Christian Rock";
    case 142: return "Merengue";
    case 143: return "Salsa";
    case 144: return "Thrash Metal";
    case 145: return "Anime";
    case 146: return "JPop";
    case 147: return "SynthPop";
    default: return "";
    }
}

bool CMp3TagInfo::IsInit()
{
    return m_bInit;
}

//////////////////////////////////////////////////////////////////////////
// all the getter
//////////////////////////////////////////////////////////////////////////


MP3TAG_VERSION CMp3TagInfo::GetMp3TagVersion()
{
    return m_eMp3TagVersion;
}

std::string CMp3TagInfo::GetFilename()
{
    return m_strFilename;
}

std::string CMp3TagInfo::GetBitRate()
{
    return m_strBitRate;
}

std::string CMp3TagInfo::GetMpegLayer()
{
    return m_strMpegLayer;
}

std::string CMp3TagInfo::GetMpegVersion()
{
    return m_strMpegVersion;
}

std::string CMp3TagInfo::GetTagVersionNumber()
{
    return m_strTagVersionNumber;
}

std::string CMp3TagInfo::GetArtist()
{
    return m_strArtist;
}

std::string CMp3TagInfo::GetTitle()
{
    return m_strTitle;
}

std::string CMp3TagInfo::GetAlbum()
{
    return m_strAlbum;
}

std::string CMp3TagInfo::GetComment()
{
    return m_strComment;
}

std::string CMp3TagInfo::GetTrack()
{
    return m_strTrack;
}

std::string CMp3TagInfo::GetYear()
{
    return m_strYear;
}

std::string CMp3TagInfo::GetGenre()
{
    return m_strGenre;
}

std::string CMp3TagInfo::GetComposer()
{
    return m_strComposer;
}

std::string CMp3TagInfo::GetCopyright()
{
    return m_strCopyright;
}

std::string CMp3TagInfo::GetOriginalArtist()
{
    return m_strOriginalArtist;
}

std::string CMp3TagInfo::GetURL()
{
    return m_strURL;
}

_________________
sally - because we love music
* www.sally-project.org *


Zuletzt bearbeitet von Der_Knob am 19:13:26 03.02.2010, insgesamt 1-mal bearbeitet
C++ Forumbot
Forumbot

Benutzerprofil
Anmeldungsdatum: 29.02.2004
Beiträge: 15805
Beitrag C++ Forumbot Forumbot 17:30:24 03.02.2010   Titel:              Zitieren

Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum Projekte verschoben.

Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?


Dieses Posting wurde automatisch erzeugt.

_________________
Besuchen Sie unsere Bücherecke.
http://www.c-plusplus.de/bucher.php
Mit jeder Bestellung unterstützen Sie das Forum.
Kóyaánasqatsi
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.10.2008
Beiträge: 3023
Beitrag Kóyaánasqatsi Mitglied 17:47:08 03.02.2010   Titel:              Zitieren

Oh man, wo soll man da anfangen?

_________________
xDelete('//tr[td/strong[text()="volkard"]]');, Hobby.
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 12748
Beitrag hustbaer Mitglied 18:02:39 03.02.2010   Titel:              Zitieren

Kóyaánasqatsi schrieb:
Oh man, wo soll man da anfangen?

Mir wäre nicht aufgefallen, dass der OP um Kommentare zur Code-Qualität oder ähnlichem gefragt hätte.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
Der_Knob
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.05.2001
Beiträge: 580
Beitrag Der_Knob Mitglied 18:27:24 03.02.2010   Titel:              Zitieren

Ich wollte keinen Code Review... ich dachte nur dass es jemand brauchen kann.

Aber wenn jemand was zum anmerken am Code hat freu ich mich natürlich auch.
Allerdings wurde das ganze auch nur schnell zusammen gebaut... weiß selber das es nicht das Beste ist – aber es funktioniert!

_________________
sally - because we love music
* www.sally-project.org *


Zuletzt bearbeitet von Der_Knob am 18:34:37 03.02.2010, insgesamt 2-mal bearbeitet
Der_Knob
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.05.2001
Beiträge: 580
Beitrag Der_Knob Mitglied 22:43:38 04.02.2010   Titel:              Zitieren

Kóyaánasqatsi schrieb:
Oh man, wo soll man da anfangen?

Was genau gefällt dir den an dem Code nicht?
Will ja auch was hinzu lernen...

_________________
sally - because we love music
* www.sally-project.org *
Kóyaánasqatsi
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.10.2008
Beiträge: 3023
Beitrag Kóyaánasqatsi Mitglied 23:17:19 04.02.2010   Titel:              Zitieren

Der_Knob schrieb:
Was genau gefällt dir den an dem Code nicht?
Will ja auch was hinzu lernen...

Header:
-Dateiheader in einer Struktur ablagern, damit die Datenstruktur "abgekapselt" ist und die Hauptklasse nicht so riesig wird
-Bei GetMp3Genre(std::string) und GetMp3Genre(int i) können die Datentypen ruhig const und die fnc's auch const sein

Cpp:
-CleanUp() sieht böse aus :eek:
-Zeile 109-134 schreien gerade zu automatisiert zu werden
-GetMp3Genre() hm, da fällt mir sicherlich auch noch was schöneres ein...

Ansonsten:
-Es sollte nicht Sinn einer Klasse sein, Getter für alle mem-vars bereitzustellen, das ist schlechtes Design
-Mit std::ifstream::exception() lassen sich flags zur Exception-Kontrolle setzen
-Eindeutige Namen für die mem-fncs erfinden (wtf ist V1 oder V2!?)

_________________
xDelete('//tr[td/strong[text()="volkard"]]');, Hobby.
volkard
Moderator

Benutzerprofil
Anmeldungsdatum: 06.04.2000
Beiträge: 24258
Beitrag volkard Moderator 23:55:30 04.02.2010   Titel:              Zitieren

Kóyaánasqatsi schrieb:
-GetMp3Genre() hm, da fällt mir sicherlich auch noch was schöneres ein...

Fängt es mit Tab an und hört mit elle auf?

Kóyaánasqatsi schrieb:
-Eindeutige Namen für die mem-fncs erfinden (wtf ist V1 oder V2!?)

Ich denke, das ist im Kontext der MP3-Tags klar. http://de.wikipedia.org/wiki/ID3-Tag#ID3v1

_________________
http://www.venganza.info/
plonk fürs Forum v1.02
Der_Knob
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.05.2001
Beiträge: 580
Beitrag Der_Knob Mitglied 23:47:19 05.02.2010   Titel:              Zitieren

Danke für das Feedback ;)

Eine paar Fragen habe ich noch:

Macht es Laufzeittechnisch einen Unterschied wenn ich bei einer Funktion den int Übergabewert const mache (GetMp3Genre(int i))?

Zitat:
-Es sollte nicht Sinn einer Klasse sein, Getter für alle mem-vars bereitzustellen, das ist schlechtes Design

Wäre eine Funktion in der man einen Identifier rein gibt und dann das entsprechende"Object" zurück bekommt besser? oder woran hast du gedacht?

Zitat:
-CleanUp() sieht böse aus

Ich ruf jedesmal cleanup auf wenn auf der Instance ein Init aufgerufen wird. Wie könnte / sollte ich das besser lösen?


Die anderen Sachen sind mir soweit klar und ich stimme dir zu :live:

@volkard
Ja genau, ich denke das mit v1 und v2 erklärt im MP3-Tag Kontext

_________________
sally - because we love music
* www.sally-project.org *
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 12748
Beitrag hustbaer Mitglied 00:47:19 06.02.2010   Titel:              Zitieren

Der_Knob schrieb:
Danke für das Feedback ;)

Eine paar Fragen habe ich noch:

Macht es Laufzeittechnisch einen Unterschied wenn ich bei einer Funktion den int Übergabewert const mache (GetMp3Genre(int i))?

Nein, macht keinen Unterschied.

Auch wird Laufzeittechnisch alles was du machst im Vergleich zum File-IO verblassen.
Solche Mikro-Optimierungen, in Funktionen, die aus Files lesen müssen (oder in Files schreiben), machen überhaupt garkeinen Sinn.

Zitat:

Zitat:
-Es sollte nicht Sinn einer Klasse sein, Getter für alle mem-vars bereitzustellen, das ist schlechtes Design

Wäre eine Funktion in der man einen Identifier rein gibt und dann das entsprechende"Object" zurück bekommt besser? oder woran hast du gedacht?

Ich weiss nicht woran er gedacht hat, aber ich würde es vermutlich eher so angehen, dass ich eine Klasse habe die den Tag-Inhalt beschreibt. Und dann habe ich eine Helper-Funktion, die die Infos aus einem File lädt, und so eine "TagContents" Klasse zurückgibt. Der "TagContents" Klasse dann Getter und Setter für alle möglichen Felder zu verpassen, halte ich dagegen eher für guten Stil.

Die Definition wie so ein Tag-Inhalt aussieht, und wie man ihn aus einem File laden kann, sind für mich zwei verschiedene Dinge. Und sollten daher auch getrennt werden.

Zitat:

Zitat:
-CleanUp() sieht böse aus

Ich ruf jedesmal cleanup auf wenn auf der Instance ein Init aufgerufen wird. Wie könnte / sollte ich das besser lösen?

Wenn du den ganzen IO/Parsing Code aus der Tag-Klasse raus nimmst, brauchst du auch keine CleanUp() Funktion mehr.

Stattdessen solltest du vermutlich sicher stellen dass der Assignment-Operator korrekt funktioniert, und dass ein default-konstruiertes Tag Objekt "leer" ist. Wenn du dann irgendwo die "Cleanup" Funktionalität brauchst, kannst du einfach schreiben:
C/C++ Code:
Tag tag = LoadTagFromFile(...);

// ...

tag = Tag(); // "cleanup"

// ...
C/C++ Code:
Tag tag = LoadTagFromFile(...);

// ...

tag = Tag(); // "cleanup"

// ...
C/C++ Code:
Tag tag = LoadTagFromFile(...);

// ...

tag = Tag(); // "cleanup"

// ...

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
C/C++ Forum :: Projekte ::  id3tag Klasse mit id3v1 id3v2  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum nicht antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.