I am currently implementing LAME gapless support into XMMS2's mad-decoder. I have some questions and I hope that someone here can help me clarify some issues.
This is what I currently do:
In the Xing parser I parse the normal Xing tag and then I read the LAME tag, like this:
CODE
if (strncmp ((gchar *)ptr.byte, "LAME", 4) == 0) {
mad_bit_skip (&ptr, 8 * 20);
mad_bit_skip (&ptr, 16);
lame->peak_amplitude = mad_bit_read (&ptr, 32);
lame->radio_gain = mad_bit_read (&ptr, 16);
lame->audiophile_gain = mad_bit_read (&ptr, 16);
mad_bit_skip (&ptr, 16);
lame->encoder_delay_start = mad_bit_read (&ptr, 12);
lame->encoder_delay_stop = mad_bit_read (&ptr, 12);
mad_bit_skip (&ptr, 8);
lame->mp3_gain = mad_bit_read (&ptr, 8);
}
Then I use these numbers in the mp3 decoder to do something like this:
CODE
data->samples_to_skip = lame->encoder_delay_start;
data->samples_to_skip_end = lame->encoder_delay_stop;
data->samples_to_play = (guint64)(((guint64)xmms_xing_get_frames (data->xing) * (guint64)1152) - (guint64)lame->encoder_delay_stop);
And then in the decoding phase:
CODE
if (data->synthpos < data->synth.pcm.length) {
if (data->samples_to_skip <= 0 && data->samples_to_play >= 0) {
out[j++] = scale_linear (data->synth.pcm.samples[0][data->synthpos]);
if (data->channels == 2) {
out[j++] = scale_linear (data->synth.pcm.samples[1][data->synthpos]);
read += 2 * xmms_sample_size_get (XMMS_SAMPLE_FORMAT_S16);
data->samples_to_play -= 2;
} else {
read += xmms_sample_size_get (XMMS_SAMPLE_FORMAT_S16);
data->samples_to_play --;
}
} else {
if (data->channels == 2) {
data->samples_to_skip -= 2;
} else {
data->samples_to_skip --;
}
}
data->synthpos++;
continue;
}
Still have some clicks between songs that play beautifully in foobar2000. Am I understanding something wrong? Any tips would be helpful.
The full code is available here:
http://git.xmms.se/?p=xmms2-devel.git;a=tr...src/plugins/mad
Thanks in advance.
// Tobias - xmms2 developer