Click here to Skip to main content
15,880,608 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Am presenting trying to convert a wave file to mp3 using LAME (which I have succeeded in doing). I also tried writing the id3tag to the mp3 which had been a success up to the point of id3tag_set_albumart.
Going through the parse.c in the frontend folder, I discovered that the second parameter of id3tag_set_albumart (image) will be the content of the image file while the third parameter will be the size of the image file.
But when I did this (code below), it return 0 which according to the lame.h is success but the encoding refuse to take place (i.e. The wave file converting to mp3).

C++
FILE* fpi = 0;
char *albumart = 0;
char *filename = "ty.jpg";
fpi = fopen(filename, "rb");
size_t size;
fseek(fpi, 0, SEEK_END);
size = ftell(fpi);
fseek(fpi, 0, SEEK_SET);
albumart = (char*)malloc(size);
fread(albumart, 1, size, fpi);
id3tag_set_albumart(lame, albumart, size);
free(albumart);
fclose(fpi);


EDIT:---
When ever I call id3tag_set_albumart, lame_encode_buffer_interleaved returns -1 which according to lame.h means mp3buf was too small. I don't think this as to do with the "size of the array" because I increased it to twice it present size but the function still returns -1
Posted
Updated 21-Aug-13 6:30am
v4
Comments
The_Inventor 17-Aug-13 6:30am    
As lame as this is, but where or how did you define and initialize, 'lame' in your id3tag_set_albumart(lame, albumart, size); statement? Which one is the file for the music, and which file is for the album art?
Oso Oluwafemi Ebenezer 21-Aug-13 12:12pm    
That was just a code snippet. I can't just dump the entire code here. The code works till I added the above code.
Jochen Arndt 21-Aug-13 13:08pm    
Did you tried to perform the PCM to MP3 conversion before adding the image?
Oso Oluwafemi Ebenezer 23-Aug-13 11:43am    
Am calling id3tag_set_albumart before lame_init_params which writes the id3Tag is also before lame_encode_buffer_interleaved with actually converts the PCM to MP3.
Sergey Alexandrovich Kryukov 21-Aug-13 14:10pm    
I'm not 100% sure, but I remember that LAME supported obsolete ID3, no Unicode, decided not to mess up with it. I found an ID3 library on CodeProject, but that was for NET...
—SA

Well let's take a closer look:

    FILE* fpi = 0;  //Initial file structure set to zero.
    char *albumart = 0; //Initial char pointer set to zero.
    char *filename = "ty.jpg";//Initial file name set to "ty.jpg".
    size_t size;//Initial size variable not initialized, of _W64 unsigned int type on 
                // my system, yours may be a _W32 unsigned int type.
  
//Here, I presume, you're opening the JPG in READ | BINARY mode. 
    fpi = fopen(filename, "rb");
    fopen(&fpi, filename, "rb, IMG= encoding "); //This is how it is done correctly.
/*
"r"   Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
"b"   Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed. 

Here you 'seek' the file, for what don't know as you didn't indicate it. 
How it is defined: int fseek(FILE *stream, long offset, int origin );

    Look at the file from end, if there is a return value it is unknown.
*/
    fseek(fpi, 0, SEEK_END);// not doing anything for you
// Here, I presume, that having possibly opened the file, you try to get the size of it.
    size = ftell(fpi);// However since you opened it in binary mode, it may not work with _W64 unsigned int type. ftell  and _ftelli64 return the current file position. The value returned by ftell and _ftelli64 may not reflect the physical byte offset for streams opened in text mode, because text mode causes carriage return–linefeed translation. Use ftell with fseek or _ftelli64 with _fseeki64 to return to file locations correctly. On error, ftell and _ftelli64 invoke the invalid parameter handler, as described in Parameter Validation.     

//Since you're at the end of the file and moved 0Bytes using fseek, ftell tells you are at EOF 
      // Move the pointer by reading data: 
      fread( list, sizeof( char ), 100, stream );
      // Get position after read: 
      position = ftell( stream );
      printf( "Position after trying to read 100 bytes: %ld\n",
              position );
// Your position is EOF, 
/*
SEEK_SET = Beginning of file.

You can use fseek and _fseeki64 to reposition the pointer anywhere in a file. The pointer can also be positioned beyond the end of the file. fseek and _fseeki64clears the end-of-file indicator and negates the effect of any prior ungetc calls against stream.

When a file is opened for appending data, the current file position is determined by the last I/O operation, not by where the next write would occur. If no I/O operation has yet occurred on a file opened for appending, the file position is the start of the file. 

For streams opened in text mode, fseek and _fseeki64have limited use, because carriage return–line feed translations can cause fseek and _fseeki64to produce unexpected results. 

The only fseek and _fseeki64 operations guaranteed to work on streams opened in text mode are: 
•Seeking with an offset of 0 relative to any of the origin values.
•Seeking from the beginning of the file with an offset value returned from a call to ftell when using fseek.

     This says to move to start the file and move 0 units of measure.
     fseek(fpi, 0, SEEK_SET); //    
     albumart = (char*)malloc(size);// doesn't work because size = 0
     size = fseek(fpi, SEEK_END, SEEK_SET); //This might have worked better.

However:
*/
//   albumart = (char*)malloc(size); fread(albumart, 1, size, fpi); This is better as:
//  size_t fread( void *buffer, size_t size, size_t count, FILE *stream ); // Read the file


    size = fread(albumart,(char),sizeof(fpi),fpi);// This reads the file and gives you the correct size and stores the data in albumart. 

    id3tag_set_albumart(lame, albumart, size); // So now if you did the above statement then this might work.
    free(albumart);
    fclose(fpi);

Or something like that ...
 
Share this answer
 
v3
Comments
Oso Oluwafemi Ebenezer 23-Aug-13 11:50am    
First of all, it is not the reading of the image file this is the challenge here. Secondly, size = fread(albumart,(char),sizeof(fpi),fpi); will never work because sizeof(fpi) will return size of an HANDLE which is 4 (on my system; HANDLE is almost same as int). And also albumart needs to be allocated to the size of the image file before calling fread on it. (char) should be sizeof(char). In short, your code for reading the file wont work...
    FILE* fpi = 0;
    char *albumart = 0;
    char *filename = "ty.jpg";//Initial file name set to "ty.jpg".
    size_t size;
    fopen(&fpi, filename, "rb, IMG= encoding ");     
    size = fseek(fpi, SEEK_END, SEEK_SET); // This gets you the size of fpi
    fread(albumart,(char), size, fpi); //This will put the data of the image into 'albumart' based upon the byte size of 'char' and whatever got read and counted into 'size'

//OR
//  size = fread(albumart,(char), sizeof(fpi), fpi); //Does the same thing in one statement.
    id3tag_set_albumart(lame, albumart, size);
    free(albumart);
    fclose(fpi);


Parameters
--------------------------------------------------------------------------------
buffer = Storage location for data.
size = Item size in bytes.
count = Maximum number of items to be read.
stream = Pointer to FILE structure.

size_t = Return Value
--------------------------------------------------------------------------------
fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged. If stream or buffer is a null pointer, fread invokes the invalid parameter handler, as described in Parameter Validation. If execution is allowed to continue, this function sets errno to EINVAL and returns 0.
------------------------------------------------------------------------------------
AND if your are only getting a value of 4, for sizeof(fpi), then you didn't open the file, or read it.
 
Share this answer
 
Comments
Oso Oluwafemi Ebenezer 24-Aug-13 11:16am    
Which OS are you using? And again like I said before, this question is not about how to read a file in cpp. It is about the id3tag_set_albumart of LAME (lame_enc.dll)
The_Inventor 25-Aug-13 3:03am    
Look in your code: fread(albumart, 1, size, fpi);, what is the 1 doing for you? It is supposed to be the 'item' size in bytes, so what, one byte? You're kidding me yes?

id3tag_set_albumart fails because YOUR code is not logically functional using the statements that you choose to use, to do what you think is correct, yet with out receiving the return information to do the things that you claim to be doing.

I am using Win7Ultimate SP1, on an Asus based system that I built for myself, using and i7(quad 4) 950 running @ 3.0Ghz, with 6GB RAM, and a 1GB video card, plus other stuff.

How about you?
Oso Oluwafemi Ebenezer 28-Aug-13 12:57pm    
1 in that code stands for sizeof(char). It is same as fread(albumart, sizeof(char), size, fpi);. I asked for your OS because fopen(&fpi, filename, "rb, IMG = encoding "); wont work on VS2012 on Windows 8. And besides writing the content of MY albumart after using MY method to fread into a file resulted in the same inputted file.
The_Inventor 29-Aug-13 1:02am    
OK, however, the place in the statement is for the size of the item, in bytes. For instance some item could be 64 bytes in size, that is a known, however what is unknown is the count of items of that size, thus the fseek gives total file size, and if you know the item width in bytes, say 32bit, is 4 bytes, then you can divide the size by the item width and get a count of items, which often goes by the name size, but is different than the size you get from the fseek command. You have presumed that in a bitmap the item size is 1 byte, yet image formats are 24 or 32 bits, so that also may be an issue.
Looked into id3lib and I think I will settle for that to read and edit the id3 tags inside the mp3. It even has some advantages over lame for id3 tag writing like no restriction for the size of the image file to use for the albumart and other stuffs.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900