Reputation: 307
I'm trying to convert a WAV file into MP3 file using LAME (win7,vs2010,c++).
I found this code:
The convert works fine, but when i'm trying to open the file using windows media player the length of the file is wrong.
Is there any way to fix this using lame lib?(not with another program or another lib or command line,only with c++ code...)
EDITED: after some reading i did i tried to use the lame_get_lametag_frame function as sellibitze suggested. here is my code:
#include <stdio.h>
#include <lame/lame.h>
int main(void)
{
int read, write;
FILE *pcm = fopen("in.pcm", "rb");
FILE *mp3 = fopen("out.mp3", "wb");
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE*2];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_VBR(lame, vbr_default);
lame_set_write_id3tag_automatic(lame, 0);
lame_init_params(lame);
char buffer[256];
int imp3=lame_get_id3v2_tag(gfp, buffer, sizeof(buffer));
fwrite(buffer, 1, imp3, outf);
long audio_pos=ftell(outf); // store beginning of audio data
do {
read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
if (read == 0)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
imp3=lame_get_id3v1_tag(gfp, buffer, sizeof(buffer));
fwrite(buffer, 1, imp3, outf);
imp3=lame_get_lametag_frame(gfp, buffer, sizeof(buffer));
fseek(outf,audio_pos,SEEK_SET); // remember beginning of audio data
fwrite(buffer, 1, imp3, outf);
lame_close(lame);
fclose(mp3);
fclose(pcm);
return 0;
}
FIXED:
I manged to fix the problem but i don't really understand how it fix it. i change the name of the mp3 file from "out.mp3" to any other name and wmp show the right length. also i tried to change the name of files already created from out to something else and it worked. can anybody explain to me way it's happened? is the name out.mp3 saved?
Upvotes: 1
Views: 1816
Reputation: 28087
The example code you liked to uses the VBR mode. Length information in that case is typically put into the first frame as metadata. This is known as Xing/VBR header. It also includes a low accuracy seek table. But this information is obviously only available after you passed all the audio data to LAME. I suggest you look for a function in the LAME API that is able to update the Xing/VBR header to reflect the correct length and seek table and call it before you close the file.
lame_encode_flush does not take your FILE* thingy so it cannot seek back to the beginning of the file and update the first mp3 frame with the Xing/VBR header.
Upvotes: 0