View Full Version : Yet another gapless playback thread, and a long one at that!
I wanna see QMP support smooth, gapless playback right from a fresh install. No messing around with output plugins, no needless crossfade, and certainly no late-night trips to the store for an eye of newt. This is a really long post, and I really don't expect very many people to read the whole thing. For you brave souls who do (and I hope this includes Paul :) ), grab yourself a can of Pork Soda, settle in, and hear me out....
PART I - The Current Experience (AKA: This Sucks)
From a fresh install, QMP uses Wave Out as its playback plugin. That's not likely to change (http://www.quinnware.com/forum/showpost.php?p=39087&postcount=6). By default, QMP will play your CDs gaplessly, and that's pretty much it. Even formats that should play gaplessly on their own, like Vorbis, have gaps between songs.
If a user is feeling adventurous, they might try switching over to the Crossfading Directsound output plugin. By default, both Seamless Playback and Remove Leading/Trailing Silence are disabled, and Crossfading on. Turning Crossfading off (crossfading can be thought of as a negative gap, we want ZERO gap) and Seamless Playback on, things seem to be about the same. I'm not sure what's so 'seamless' about seamless playback, at least on this build, I still get gaps even on wav files!
The closest I've found to decent gapless playback with QMP's bundled plugins is using the crossfading DSound plugin, crossfading turned off, seamless playback checked, remove leading/trailing silence checked, and silence threshold set all the way to the right (-100dB). On most material that's supposed to play back without gaps, it plays with no audible defects. It may not be sample-perfect, but most would say it's within reason. But it has some weaknesses.
I've found at least one example where I can still hear a little glitch between the tracks. It's not really a gap, more like a tiny crackle at the transition between the songs. Playing the same files in foobar gave no audible defect. To be fair, I found another pair of tracks where I could hear that sort of a glitch in both players. That case I'm willing to write off as a defect in the MP3 that's probably not correctable.
What annoys me about this setup is that I lose silent passages that are supposed to be there. I'll be listening to an album, and all of a sudden... "Gah, those two songs just don't sound right butted up against each other like that!" When I play an album, I want the playback time to be as close to the original CD as possible.
PART II - A Few Possible Ways To Tackle The Problem (AKA: This Might Suck Less)
MP3 ain't naturally gapless. Track lengths have to be a multiple of 576 samples (note: I've heard a few different numbers for that), so there's almost always going to be some 'leftover' space at the ends of the file. That's one of the main causes of the gaps heard when playing MP3s.
As far as I'm aware, the 'cleanest' way to get MP3s to play gaplessly is to read the LAME info tag (http://gabriel.mp3-tech.org/mp3infotag.html) to determine the exact encoder delay and padding (beginning and end, respectively) used on the MP3. Then just remove that many from the decoded output, and you should have a nice, smooth transition. Theoreticly, (number of frames * samples per frame) - those values = exact number of samples in the original wav.
That does have its limitations, of course. Namely, unless you rip all your MP3s yourself, you probably have some files that weren't encoded by LAME. So one way or another, you have to be able to deal with those too.
Foobar has a utility called Fix MP3 Header that can be used to manually create a LAME-style delay/padding tag for files created by other encoders. Info about it is here (http://www.hydrogenaudio.org/forums/index.php?showtopic=11669), with a tutorial at the bottom of the page. I tried it, it seems to work well. It's a somewhat involved process, though. I would be comfortable using a tool like that, but I can definately see it confusing a lot of users. There would probably be some trying to use it on songs that don't even need to be gapless in the first place. Still, it might make a good addition to the Advanced tab in the tag editor. I think there's a few other apps out there that can do this too, but I've never really looked into it.
I've said it before, and I'll say it again: I don't think that the output plugin is the best place to be trimming a small number of samples to get MP3s to play gaplessly. Probably the best argument I can present for this is that the benefits aren't available to all the output plugins at your disposal. From the sound of it, Wave Out ain't going away anytime soon as the default playback plugin. Therefore, I think there should be an effort to get gapless playback support working for Wave Out, in the interest of making things 'just work' out of the box. In foobar, I can switch between WaveOut, DirectSound, and Kernel Streaming, and it has no noticable impact on gapless playback. I want to see the same in QMP.
If it's not practical for this to be handled by the input plugins, would it be possible to move some/all of the gap-kill functionallity to a DSP? If a DSP can change the playback rate of your music (http://www.quinnware.com/list_plugins.php?plugin=147), I would think it should be able to handle removing gaps too. Yes, there would be added latency, but who cares?
It would probably need to be the first DSP in the chain, in case another DSP alters stretches/compresses the playing time/speed of the songs. For that matter, it might be beneficial to consider it a 'special case' DSP, as you're likely to want to use its trimming capabilities at times when you wouldn't want to use other DSPs that alter the sound of a track. For example, when you're decoding a file to WAV, or encoding into another format. In theory, I should be able to encode a WAV to MP3 with LAME, then write it back to disk as a WAV from within QMP, and have it come out with the same number of samples as it started with, with no offset.
It might also be a good idea if it could automaticly turn itself off, or maybe just switch to a different mode, when it's not really needed. Perhaps the input plugin (and possibly in conjunction with the tag reader) could 'hint' the DSP about whether or not file(s) currently being played need any extra help with playing gaplessly. An MP3 plugin could say that it needs gap killing most of the time, but could switch it off when a stream is being played, as there's not much need for it. An MP4/AAC plugin might switch it on when playing a raw AAC file, and off when playing an MP4. The point is that plugin authors could re-use this, someone writing an MP3 plugin wouldn't have to completely reinvent the wheel to get gapless playback working well, nor would someone writing a new output plugin, like an updated ASIO plugin.
Once the gap has been removed, send it on to the output plugin of the user's choice, all in one piece. Don't close the WaveOut session or anything.
Now back to my peeve with the current DSound plugin's silence remover. I want gap killing to remove the gap caused by standard characteristics of the MP3 format. No less, and just as importantly, no more. With the current silence remover, there's no way to stop it from removing more than it needs to, leading to songs playing immediately after each other, when there's supposed to be a pause between them. Worse yet, if I don't have the silence threshold set all the way to the right (-100dB), I can hear it cut off part of the music itself. At the default value of -40dB, I've seen it slash a minute off of a song's playing time. LAME's delay/padding tag uses 12 bits to store each value. That gives a worst case scenario of 4095 samples to be removed from each end of the file, which comes to about one-tenth of a second at 44.1kHz. Beyond that is overkill.
What I think would make the most sense is to have a single checkbox marked something like "Attempt to correct unintended gaps caused by the MP3 architecture". If LAME tags are available, it uses them. If not, it removes up to one-tenth of a second from each end of the file (IOW, a total of two-tenths of a second at the division between two tracks). This is done with a very low silence threshold (or is that high?), because the gaps that we're trying to remove here are going to be either dead silent or damn near it.
I stand in awe of anyone who actually reads this whole thing.
Links:
lame tag http://gabriel.mp3-tech.org/mp3infotag.html
enc delays of various encoders http://mp3decoders.mp3-tech.org/decoders_lame.html#delays
fb2k vbrfix http://www.hydrogenaudio.org/forums/index.php?showtopic=11669 (tutorial at bottom of page)
biggman15
06-13-2005, 11:04 AM
I read the whole thing...... And you gave me enough Reason to switch back to the Simple DSound Plugin..... I switched 2 days ago to see if Crossfading and what not was Worth anything..... I too have noticed it cutting off A minute.... Heck it cuts off between 4 or 5 on 1 track.... Thank you for pointing This out.... I'm more comfortable without the cross fading anyway....
acozz
06-13-2005, 12:43 PM
What did you expect to happen when you turned on "Remove leading and trailing silence"? I like its functionality the way it is.
Willow of Oz
06-13-2005, 01:21 PM
Hmmm.
It would be interesting with a random mix of songs, some of which come from a gapless source...
matty28carter
06-13-2005, 01:37 PM
I agree with what your saying Toe. I also find it annoying that the "remove leading and trailing silence" often removes bits of (especially at the end) the song. There should be some kindo of "one for all" setting. I hope the gapless gets worked on at the same time as my suggestions for the crossfading. I know crossfading isn't everyones taste but I like it and so do many other people. There are times when I prefer a song to be played gaplessly back to back with another song and other times when I prefer them to crossfade *at the right moment* that being the key thing. Crossfading in my opinion relies on gapless play-back.
hedge
06-13-2005, 03:58 PM
yep agree with everything said by Toe. Gapless definitely needs some serious work done, and if its not too much work (which i somehow think it might be), a core method of gapless which doesn't require anything done in the output plugin would be awesome.
Inthewoods
06-13-2005, 11:38 PM
With the current silence remover, there's no way to stop it from removing more than it needs to, leading to songs playing immediately after each other, when there's supposed to be a pause between them.You're asling the silence remover to somehow guess which songs are supposed to have a gap (silence) between them?? A properly working silence remover does just what the name says, it removes silence within the music. period. That's different than a gap remover that closes the gaps between songs, which are not part of the file itself. If I'm understanding you, you're referring to the gaps.
That said, QCD/QMP's implementation does not provide true gapless playback and never has. But if you expect the plugin (or the program itself) to sometimes remove silence and other times leave it in, based on whether there's "supposed to be a pause" as you say, that's not gonna happen. If the silence is there and it meets the criteria for length and dB level, it's gonna be gone.
What did you expect to happen when you turned on "Remove leading and trailing silence"? I like its functionality the way it is.
I never suggested that we get rid of the existing Remove Silence function, my suggestion would be a compliment to it, with different purposes in mind. Same goes for crossfading, for that matter.
You're asling the silence remover to somehow guess which songs are supposed to have a gap (silence) between them??
Again, this is a supplement to, not a replacement for, the existing silence remover. In the case where there's a LAME tag present, there's no need for it to guess in the first place. It would trim the extra samples as indicated by the file itself, and that would be that.
That said, QCD/QMP's implementation does not provide true gapless playback and never has. But if you expect the plugin (or the program itself) to sometimes remove silence and other times leave it in, based on whether there's "supposed to be a pause" as you say, that's not gonna happen. If the silence is there and it meets the criteria for length and dB level, it's gonna be gone.
Your last sentence skiped over the critical point here: Currently, the program doesn't HAVE a criteria for length! And for the non-LAME-tagged case, that's exactly what I think it needs. When it's turned on, and the input plugin says the file is a format that likely needs to be trimmed (the 'hint' I refered to above), then it would trim a MAXIMUM of one-tenth of a second from each end of the track. In most cases the actual amount would be less than half that, in the sample I posted here (http://www.quinnware.com/forum/showpost.php?p=37522&postcount=5), about .03s needs to be trimmed. The gap killer would look at that first/last tenth of a second, and trim it much like the existing silence remover would, with a VERY conservative silence threshold. If the track is supposed to be gapless, that should remove the gap without cutting into the music. If the track is supposed to have a 3 second gap at the end, it would have one tenth of a second of silence trimmed, and I don't think anyone will complain.
After it's been through that gap-kill, then it can be passed on to the existing silence remover, which operates outside that tenth of a second boundry. (Assuming the user has it turned on, of course.) Internally, they would probably both be done on the same pass.
Inthewoods
06-14-2005, 02:52 AM
I never suggested that we get rid of the existing Remove Silence function, my suggestion would be a compliment to it, with different purposes in mind. Same goes for crossfading, for that matter.
Again, this is a supplement to, not a replacement for, the existing silence remover. In the case where there's a LAME tag present, there's no need for it to guess in the first place. It would trim the extra samples as indicated by the file itself, and that would be that.
Your last sentence skiped over the critical point here: Currently, the program doesn't HAVE a criteria for length! And for the non-LAME-tagged case, that's exactly what I think it needs. When it's turned on, and the input plugin says the file is a format that likely needs to be trimmed (the 'hint' I refered to above), then it would trim a MAXIMUM of one-tenth of a second from each end of the track. In most cases the actual amount would be less than half that, in the sample I posted here (http://www.quinnware.com/forum/showpost.php?p=37522&postcount=5), about .03s needs to be trimmed. The gap killer would look at that first/last tenth of a second, and trim it much like the existing silence remover would, with a VERY conservative silence threshold. If the track is supposed to be gapless, that should remove the gap without cutting into the music. If the track is supposed to have a 3 second gap at the end, it would have one tenth of a second of silence trimmed, and I don't think anyone will complain.
After it's been through that gap-kill, then it can be passed on to the existing silence remover, which operates outside that tenth of a second boundry. (Assuming the user has it turned on, of course.) Internally, they would probably both be done on the same pass.Your response tells me that you either skipped or ignored my critical point about the difference between gap removal and silence skipping. The mp3 files created by a correctly ripped CD of say, a live concert, will have have no silence at the end (or the beginning), so cutting into them, even slightly will do more harm than good from a seamless standpoint. The idea is not to cut into the actual musical content, but rather to handle the partial frames at the beginning (and/or end) of the files in such a way that their effect is inaudible and indistinguishable from full frames. Any kind of "trim on the fly" process is going to trash the listenability.
You're right about there being no minimum silence length, but the maximum is defined by the buffer length. In any case, seamless/gapless playback has nothing to do with trimming any part of the files themselves, but rather the methodology used to interleave 2 consecutive files.
Your response tells me that you either skipped or ignored my critical point about the difference between gap removal and silence skipping.
Silence is silence. Either it's supposed to be there or it's not.
The mp3 files created by a correctly ripped CD of say, a live concert, will have have no silence at the end (or the beginning),
Sorry, but that's just plain wrong. The MP3 standard requires that files be written in blocks of either 576 samples (long block) or 192 samples (short block), and each frame must be 1192 samples. (2 long blocks, 6 short blocks, or a combination.) Because of those length requirements, the length of the MP3 will almost never match up perfectly with the number of samples in the original WAV as ripped from the CD. There will always be some extra samples padded to the end to complete the last frame. And can you guess what these extra samples produce? Silence! The LAME encoder padding tag indicates how many samples the encoder had to pad at the end of the track to complete the last frame. If the player supports it, it can read that tag and find out exactly how many samples of silence it needs to remove to get back to the number that were in the original WAV.
If that LAME tag isn't the number of samples added, then please enlighten me as to what it is.
Tell me, what is this 'correct' way to rip a CD you speak of?
Ripping the whole CD as one big waveform and encoding that as one solid MP3? Get real.
lame --nogap? That an old, largely deprecated hack that still doesn't get around the player-side support requirement. AFAIK the padding tag is considered a better way to go. The --nogap switch isn't even in the documentation for LAME (http://lame.sourceforge.net/USAGE). (Though the fact that such a switch even exists should tell you something about the nature of MP3)
The only other thing that I know of that can produce a 'gap' is when players are designed in such a way that they have to reinitialize the wave output device between tracks. That's what I was refering to earlier when I said "Don't close the WaveOut session or anything." Part of me suspects that this is what you're refering to when you try to distinguish between 'silence' and a 'gap'. But since you never directly mentioned it, I'm really not sure. What I'm also not sure of is whether or not this is the case with QMP.
A good read on gaps in MP3 playback:
http://www.pretentiousname.com/mp3players/
A word on --nogap from one of LAME's devs:
http://www.hydrogenaudio.org/forums/index.php?showtopic=16020&view=findpost&p=211791
EDIT: I'm just gonna edit this thread with a couple other links...
Ota-chan's mpg123 variant (http://translate.google.com/translate?hl=en&sl=ja&u=http://www3.cypress.ne.jp/otachan/in_mpg123.html&prev=/search%3Fq%3D%2Bsite:www3.cypress.ne.jp%2Bota-chan%26hl%3Den%26lr%3D%26c2coff%3D1%26safe%3Doff%2 6client%3Dfirefox-a%26rls%3Dorg.mozilla:en-US:official) supports reading of the LAME tag.
Just to clarify something: Vorbis and AAC both have the same sample-padding 'characteristic' as MP3. However, their container formats (Ogg and MP4, respectively) both contain info on how much sample padding was done, and that data is an official part of the standard (unlike the LAME tag, which is not part of the official MP3 standard). And AFAIK all variants of their decoders (and input plugins) that support those container formats also use their data to make the track play without the extra silence at the ends. This is why I'm puzzled when Paul says that removing these gaps can't be done in the input plugin.
On a related note, it's actually perfectly to spec to put an MP3 stream inside of an MP4 container, and use the MP4 container for the gapless playback info. MP3 audio is part of the MPEG-4 spec, after all. However, there's quite a few practical concerns against this approach, mainly the matter of having players that can actually deal with a file in this format.
EIDT: Oh yeah, if anyone's not familiar with what a container format is, read this:
http://wiki.hydrogenaudio.org/index.php?title=Container_format
bingle
08-13-2005, 03:03 AM
I'm pretty late on this thread, but I wanted to add that Winamp has a gapless playback plugin (or rather, older versions had one). It may just be a silence remover, but it doesn't look like it from the options. Here's a link to where I found the plugin:
http://www.oro.net/~tfabris/gapkill.htm. Unfortunately, no source or explanation is provided, but I thought it might help.
I'd also like to add my voice to the calls for gapless - I listen to a lot of albums where even a tiny gap is noticable. For me, the problem would be 99% fixed simply by correcting the padding in LAME files and dealing with gapless Ogg. The ability to deal with non-LAME MP3s would be an added bonus.
Thanks.
vBulletin® v3.8.4, Copyright ©2000-2010, Jelsoft Enterprises Ltd.