Thread: Reading MP3 information breaks...

  1. #1
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310

    Reading MP3 information breaks...

    This is my hole code:
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using std::cout;
    using std::cin;
    using std::endl;
    using std::string;
    using std::ifstream;
    using std::ios;
    using std::filebuf;
    
    class CID3 {
    public:
    	CID3() : _strFile("") {};
    	CID3(const string& strMP3File) : _strFile(strMP3File) {}
    	~CID3() {
    		_iFile.close();
    	}
    	bool bOK() {
    		_iFile.open(_strFile.c_str(), ios::binary);
    		_bOk = _iFile.good();
    		return _bOk;
    	}
    	int GetBytes() {
    		pbuf = _iFile.rdbuf();
    		_bytes = pbuf->pubseekoff(0, ios::end); // FileSize
    		return _bytes;
    	}
    	int Parse() {
    		pbuf->pubseekpos(_bytes-128);
    		string strTag;
    		char szTag[3], szTrackName[30], szTrackArtist[30], szTrackAlbum[30], szTrackYear[4], szTrackComment[30], szTrackGenre[1];
    		pbuf->sgetn(szTag, 3);
    		strTag = szTag;
    		if (strTag == "TAG") { // ID3v1.0
    			// Title
    			pbuf->sgetn(szTrackName, 30);
    			_strTitle = szTrackName;
    			// Artist
    			pbuf->sgetn(szTrackArtist, 30);
    			_strArtist = szTrackArtist;
    			// Album
    			pbuf->sgetn(szTrackAlbum, 30);
    			_strAlbum = szTrackAlbum;
    			// Year
    			pbuf->sgetn(szTrackYear, 4);
    			_strYear = szTrackYear;
    			// Comment
    			pbuf->sgetn(szTrackComment, 30);
    			_strComment = szTrackComment;
    			// Genere
    			pbuf->sgetn(szTrackGenre, 1);
    			_strGenre = szTrackGenre;
    			return 1;
    		}
    		return 0;
    	}
    	string GetTitle() const {
    		return _strTitle;
    	}
    	string GetArtist() const {
    		return _strArtist;
    	}
    	string GetAlbum() const {
    		return _strAlbum;
    	}
    	string GetYear() const {
    		return _strYear.substr(0, 4);
    	}
    	string GetComment() const {
    		return _strComment;
    	}
    	string GetGenre() const {
    		return _strGenre;
    	}
    private:
    	string _strGenre; // Genre
    	int _Genre; // # Genre
    	string _strComment; // Comment
    	string _strYear; // Year
    	string _strAlbum; // Album
    	string _strArtist; // Artist
    	string _strTitle; // Title
    	string _strFile;
    	ifstream _iFile;
    	filebuf *pbuf;
    	int _bytes;
    	bool _bOk;
    };
    
    int main() {
    	CID3 pMP3("X:\\mp3s\\chris isaak - chris issac - wicked game.mp3");
    	if (pMP3.bOK()) {
    		cout << "OK" << endl;
    		cout << pMP3.GetBytes() << endl;
    		cout << pMP3.Parse() << endl;
    		cout << "[" << pMP3.GetTitle() << "]" << endl; // Works!
    		cout << "[" << pMP3.GetArtist() << "]" << endl; // Works!
    		cout << "[" << pMP3.GetAlbum() << "]" << endl; // Works!
    		cout << "[" << pMP3.GetYear() << "]" << endl; // Works, but with a extra "+" sign
    		cout << "[" << pMP3.GetComment() << "]" << endl; // "Works"
    		cout << "[" << pMP3.GetGenre() << "]" << endl; // No integer value returns
    	}
    	else {
    		cout << "Error!" << endl;
    	}
    	return 0;
    }
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

  2. #2
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    It could potentially be 1.1? Edit: that integer thing. It's a byte value that you're printing as a string. Edit: you're assigning a non-null terminated string to a std::string. It doesn't know where to stop. That data you're reading isn't guaranteed to be null-terminated, it just so happens that non-filled in data is zero filled.
    Last edited by Tonto; 11-24-2006 at 08:48 PM.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Just to be specific on what Tonto said

    char szTag[3],
    Can only store two characters and a \0

    pbuf->sgetn(szTag, 3);
    Does this write 3 characters without a \0 ?

    strTag = szTag;
    This can only work if there is a \0

    if (strTag == "TAG")
    This can never succeed if there was a \0
    It doesn't stand much chance if there wasn't, since that would result in buffer overruns in the original char arrays.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310
    ah, ok..I understand...thanks
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 06-01-2009, 07:54 PM
  2. Reading a MP3 header
    By xErath in forum C Programming
    Replies: 6
    Last Post: 06-22-2004, 08:09 PM
  3. more help needed with mp3
    By duck-billed platypus in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 12-30-2001, 06:23 PM
  4. Using the MP3 format with C++
    By floridaclint in forum C++ Programming
    Replies: 1
    Last Post: 11-28-2001, 07:04 AM