After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 558235 - does not support lame mp3 gapless tag
does not support lame mp3 gapless tag
Status: RESOLVED OBSOLETE
Product: rhythmbox
Classification: Other
Component: iPod
0.11.x
Other All
: Normal enhancement
: ---
Assigned To: RhythmBox Maintainers
RhythmBox Maintainers
Depends on:
Blocks:
 
 
Reported: 2008-10-28 13:35 UTC by sarixe
Modified: 2018-05-24 13:44 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description sarixe 2008-10-28 13:35:45 UTC
Rhythmbox claims to support gapless playback. It does for the most part, but on mp3's, it doesn't. This is due to the design of mp3 frames. Each frame is a predetermined length of time, and the last frame is no exception, which causes a small silence at the end of each song. LAME has a workaround for this: embed a tag that tells a decoder exactly how long the song should be. iTunes, iPod, and libgpod support this. Rhythmbox neither makes use of this tag in its normal playback, nor for syncing songs to an iPod.

The bug is present in all versions of Rhythmbox.
Comment 1 Christophe Fergeau 2008-10-28 13:40:11 UTC
I know libgpod has some fields to put the gapless playback information, but I'm not really sure what to put in there. If you have some pointers explaining it all (what is in the lame tag and what the ipod expects), or even better, if you can write a patch ;), that would be great
Comment 2 sarixe 2008-10-28 13:47:08 UTC
I'm not exactly sure what should go in the field either, but I know that in gtkpod, if you edit the information in a file, you can see a field called "length".  In this field, is a time in the format of mm:ss.### (minutes:seconds.milliseconds).  Also, in audacious, you can see the length field as (I believe) milliseconds only.  
Comment 3 sarixe 2008-10-29 02:47:45 UTC
If I want to try patching this, what do I have to do?  Is there CVS or SVN that I can use?  Or should I patch this against 0.11.x?
Comment 4 Christophe Fergeau 2008-10-29 09:37:10 UTC
A patch against the 0.11.x release would be enough I think, though it's generally more convenient to work from svn, rhythmbox is hosted on svn.gnome.org. The changes for the ipod code would have to be done in plugins/ipod/rb-ipod-source.c (there's a function creating a Itdb_Track structure from a RhythmDBEntry)
Comment 5 Jonathan Matthew 2008-10-29 13:19:08 UTC
The playback side of this would probably be mostly in GStreamer rather than rhythmbox.
Comment 6 sarixe 2008-10-29 15:20:30 UTC
Thanks for the tips, Christophe and Jonathan.
Comment 7 sarixe 2008-10-31 05:38:36 UTC
Here's what I've found by poking around in the 0.11.6 source.

in plugins/ipod/rb-ipod-source.c, in the function create_ipod_song_from_entry(...):

line 479: track->tracklen = rhythmdb_entry_get_ulong(entry, RHYTHMDB_PROP_DURATION);
line 480: track->tracklen *= 1000;

track is a struct of type Itdb_Track, which is typedef'd by libgpod.  track->tracklen is presumably the length in seconds as returned by rhythmdb_entry_get_ulong(...) * 1000, for milliseconds.  i'm not sure what's in lame's length tag, but i would venture to say that it's a value in milliseconds for the length.  

Somewhere along the way, a value should be read from lame's length tag, but it seems this isn't being done.  It should be done right here (instead of grabbing it from rhythmbox's database) along the lines of:
track->tracklen = get_id3_length_milliseconds(filename);
and skip the multiplication by 1000.  however, this will only solve the problem for ipods, and not for playback within rhythmbox itself.

looking in rhythmdb.c at rhythmdb_entry_get_ulong(...), we see that the problem really lies in the rhythmbox database.  Within the function, there are the two lines:

line 4817: case RHYTHMDB_PROP_DURATION:
line 4818: return entry->duration;

which are being used on this specific call of the function.  entry (i would guess) is directly from rhythmbox's database, and that's where we're getting the track length in seconds from.  i don't know how this could be changed in order to actually work, as i'm not familiar with how the playback end of rhythmbox works.  

another thing to consider is other formats that ipod supports.  the example of track->tracklen = get_id3_length_milliseconds(filename); should probably only be implemented for mp3's, and from the looks of it, there should be no problem discerning filetypes.
Comment 8 amano 2010-07-30 01:21:10 UTC
Why do we have to reinvent the wheel here? There is a fine open source MP3 decoder that supports gapless MP3 playback (skipping encoder/decoder padding/junk) and probably any feature you would ever like to support in the future. It is LGPL'ed, actively maintained and calles mpg123. Why not just use simply that?

http://www.mpg123.de/features.shtml
Comment 9 Jonathan Matthew 2010-07-30 01:39:13 UTC
Maybe someone has created a GStreamer plugin using mpg123.  If so, you could try it out and see if it does gapless playback properly.  If not, maybe you could do it yourself.  What wheel do you think is being reinvented?
Comment 10 amano 2010-07-30 11:59:27 UTC
Well, it's probably rather a GStreamer problem then because the current GStreamer MP3 decoder plugin doesn't make use of the existing and working mpg123 library (the linux mpg123 command line tool actually plays back MP3 files with an intact LAME info tag). Maybe the "product" should be changed to GStreamer and I wonder why the component is classified as "IPod" as well. 

I will check if there are exsisting GStreamer plugins based on mpg123, but if not, I highly doubt that I am able to convert the mpg123 library into a GStreamer plugin. There is just too little GStreamer knowledge on my part.

The bad thing is that no player seems to playback MP3 gaplessly (except for the mpg123 commandline tool). Even Audacious which doesn't depend on GStreamer and ships its own decoders instead doesn't have its MPEG decoder compiled against mpg123 but against the much older libmad library (from 2004).
Comment 11 amano 2010-07-30 12:14:00 UTC
There is actually a mpg123 Gstreamer plugin at http://gst.homeunix.net/ which offers even a Debian package. It is called libgst-mpg123_0.1.deb but works apparently just for the i386 architecture (I am on AMD64 here). I will report back if I can get it to work on this machine and post my results...
Comment 12 amano 2010-07-30 17:20:35 UTC
I uploaded good test samples to the corrispondent Ubuntu  bug:
https://bugs.launchpad.net/ubuntu/+source/gstreamer0.10/+bug/290150

I tried out those samples with the libgst-mpg123_0.1.deb on Rhythmbox 0.12.0 on Jaunty Jackalope (because that is my only 32 bit install on my HDD). I had to enable the crossfading option first with this version (still required to to that then) and was able to playback the ogg files fine. 

But altough I know that the mpg123 library can handle the info tags (the command line mpg123 tool plays eben gaplessly on Jaunty) and although the Gstreamer pipeline seems to be fine (because I can playback ogg and lossless flawlessly), there are still gaps. What am I missing here?

Is there an old mpg123 library used for libgst-mpg123? Or are there some features simply not implemented?
Comment 13 Jonathan Matthew 2010-07-30 22:33:42 UTC
I have no idea.  Perhaps the author of the mpg123 GStreamer plugin could help you with that.
Comment 14 GNOME Infrastructure Team 2018-05-24 13:44:07 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/rhythmbox/issues/651.