Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Click in between playback of files (mp3, opus) AKA not gapless #601

Closed
averms opened this issue Jul 8, 2019 · 5 comments
Closed

Click in between playback of files (mp3, opus) AKA not gapless #601

averms opened this issue Jul 8, 2019 · 5 comments
Labels

Comments

@averms
Copy link

averms commented Jul 8, 2019

Bug report

I got a sample of a Telemann sonata encoded in FLAC 16/44.1 and split it into two. The two tracks play back gaplessly in FLAC form, but if I encode them into mp3 or opus they aren't gapless anymore. The files are in https://mega.nz/#F!amAQ1CCZ!ltKHdQo4kib8McMYbvd-VA.

Describe the bug

Make a queue like so:

01.split-track01.flac
01.split-track02.flac
02.split-track01.mp3
02.split-track02.mp3
03.split-track01.opus
03.split-track02.opus

Listen to them in order. On my machine there was no audible click between the FLAC files. There was an audible click in between the 01 and 02 versions of the opus-encoded and mp3-encoded files.

Expected Behavior

No click for any of the files. This is the case if I use cmus or mpv.

Actual Behavior

There is a click

Version

Music Player Daemon 0.21.11 (0.21.11)
Copyright 2003-2007 Warren Dukes <warren.dukes@gmail.com>
Copyright 2008-2018 Max Kellermann <max.kellermann@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Database plugins:
 simple proxy upnp

Storage plugins:
 local smbclient udisks nfs curl

Neighbor plugins:
 smbclient upnp udisks

Decoders plugins:
 [mad] mp3 mp2
 [mpg123] mp3
 [vorbis] ogg oga
 [oggflac] ogg oga
 [flac] flac
 [opus] opus ogg oga
 [sndfile] wav aiff aif au snd paf iff svx sf voc w64 pvf xi htk caf sd2
 [audiofile] wav au aiff aif
 [dsdiff] dff
 [dsf] dsf
 [hybrid_dsd] m4a
 [faad] aac
 [mpcdec] mpc
 [wavpack] wv
 [modplug] 669 amf ams dbm dfm dsm far it med mdl mod mtm mt2 okt s3m stm ult umx xm
 [mikmod] amf dsm far gdm imf it med mod mtm s3m stm stx ult uni xm
 [wildmidi] mid
 [fluidsynth] mid
 [ffmpeg] 16sv 3g2 3gp 4xm 8svx aa3 aac ac3 adx afc aif aifc aiff al alaw amr anim apc ape asf atrac au aud avi avm2 avs bap bfi c93 cak cin cmv cpk daud dct divx dts dv dvd dxa eac3 film flac flc fli fll flx flv g726 gsm gxf iss m1v m2v m2t m2ts m4a m4b m4v mad mj2 mjpeg mjpg mka mkv mlp mm mmf mov mp+ mp1 mp2 mp3 mp4 mpc mpeg mpg mpga mpp mpu mve mvi mxf nc nsv nut nuv oga ogm ogv ogx oma ogg omg opus psp pva qcp qt r3d ra ram rl2 rm rmvb roq rpl rvc shn smk snd sol son spx str swf tak tgi tgq tgv thp ts tsp tta xa xvid uv uv2 vb vid vob voc vp6 vmd wav webm wma wmv wsaud wsvga wv wve
 [gme] ay gbs gym hes kss nsf nsfe sap spc vgm vgz
 [pcm]

Filters:
 libsamplerate soxr

Tag plugins:
 id3tag

Output plugins:
 shout null fifo pipe alsa ao oss openal solaris pulse jack httpd recorder

Encoder plugins:
 null vorbis opus lame twolame wave flac

Archive plugins:
 [bz2] bz2
 [zzip] zip
 [iso] iso

Input plugins:
 file archive alsa tidal qobuz curl ffmpeg smbclient nfs mms cdio_paranoia

Playlist plugins:
 extm3u m3u pls xspf asx rss soundcloud flac cue embcue

Protocols:
 file:// alsa:// tidal:// qobuz:// http:// https:// gopher:// rtp:// rtsp:// rtmp:// rtmpt:// rtmps:// smb:// nfs:// mms:// mmsh:// mmst:// mmsu:// cdda://

Other features:
 avahi dbus udisks epoll icu inotify ipv6 systemd tcp un

Log

Jul 08 18:06 : client: [3] opened from local
Jul 08 18:06 : client: [3] process command "play "0""
Jul 08 18:06 : playlist: play 0:"test/01.split-track01.flac"
Jul 08 18:06 : decoder_thread: probing plugin flac
Jul 08 18:06 : client: [3] command returned 0
Jul 08 18:06 : decoder: audio_format=44100:16:2, seekable=true
Jul 08 18:06 : playlist: queue song 1:"test/01.split-track02.flac"
Jul 08 18:06 : output: opened "pulsey" (pulse) audio_format=44100:16:2
Jul 08 18:06 : client: [3] process command list
Jul 08 18:06 : client: process command "status"
Jul 08 18:06 : client: command returned 0
Jul 08 18:06 : client: process command "currentsong"
Jul 08 18:06 : client: command returned 0
Jul 08 18:06 : client: [3] process command list returned 0
Jul 08 18:06 : client: [3] closed
Jul 08 18:06 : decoder_thread: probing plugin flac
Jul 08 18:06 : decoder: audio_format=44100:16:2, seekable=true
Jul 08 18:06 : state_file: Saving state file /home/aman/.local/share/mpd/state
Jul 08 18:06 : player: played "test/01.split-track01.flac"
Jul 08 18:06 : playlist: queue song 2:"test/02.split-track01.mp3"
Jul 08 18:06 : decoder_thread: probing plugin mad
Jul 08 18:06 : mad: detected LAME version 3.100 ("LAME3.100")
Jul 08 18:06 : mad: LAME peak found: 0.000000
Jul 08 18:06 : mad: encoder delay is 576, encoder padding is 972
Jul 08 18:06 : decoder: audio_format=44100:24:2, seekable=true
Jul 08 18:06 : state_file: Saving state file /home/aman/.local/share/mpd/state
Jul 08 18:06 : player: played "test/01.split-track02.flac"
Jul 08 18:06 : playlist: queue song 3:"test/02.split-track02.mp3"
Jul 08 18:06 : output: opened "pulsey" (pulse) audio_format=44100:24:2
Jul 08 18:06 : decoder_thread: probing plugin mad
Jul 08 18:06 : mad: detected LAME version 3.100 ("LAME3.100")
Jul 08 18:06 : mad: LAME peak found: 0.000000
Jul 08 18:06 : mad: encoder delay is 576, encoder padding is 1475
Jul 08 18:06 : decoder: audio_format=44100:24:2, seekable=true
Jul 08 18:06 : state_file: Saving state file /home/aman/.local/share/mpd/state
Jul 08 18:06 : player: played "test/02.split-track01.mp3"
Jul 08 18:06 : playlist: queue song 4:"test/03.split-track01.opus"
Jul 08 18:06 : decoder_thread: probing plugin opus
Jul 08 18:06 : decoder: audio_format=48000:16:2, seekable=true
Jul 08 18:06 : state_file: Saving state file /home/aman/.local/share/mpd/state
Jul 08 18:06 : player: played "test/02.split-track02.mp3"
Jul 08 18:06 : playlist: queue song 5:"test/03.split-track02.opus"
Jul 08 18:06 : output: opened "pulsey" (pulse) audio_format=48000:16:2
Jul 08 18:06 : decoder_thread: probing plugin opus
Jul 08 18:06 : decoder: audio_format=48000:16:2, seekable=true
Jul 08 18:06 : client: [4] opened from local
Jul 08 18:06 : client: [4] process command list
Jul 08 18:06 : client: process command "status"
Jul 08 18:06 : client: command returned 0
Jul 08 18:06 : client: process command "currentsong"
Jul 08 18:06 : client: command returned 0
Jul 08 18:06 : client: [4] process command list returned 0
Jul 08 18:06 : client: [4] closed
Jul 08 18:06 : state_file: Saving state file /home/aman/.local/share/mpd/state
Jul 08 18:06 : player: played "test/03.split-track01.opus"
Jul 08 18:06 : playlist: queue song 6:"test/magnificat_24-096.flac"
Jul 08 18:06 : decoder_thread: probing plugin flac
Jul 08 18:06 : decoder: audio_format=96000:24:2, seekable=true
Jul 08 18:06 : state_file: Saving state file /home/aman/.local/share/mpd/state
Jul 08 18:06 : client: [5] opened from local
Jul 08 18:06 : client: [5] process command "stop"
Jul 08 18:06 : playlist: stop
Jul 08 18:06 : player: played "test/03.split-track02.opus"
Jul 08 18:06 : output: closed "pulsey" (pulse)
Jul 08 18:06 : client: [5] command returned 0
Jul 08 18:06 : client: [5] process command list
Jul 08 18:06 : client: process command "status"
Jul 08 18:06 : client: command returned 0
Jul 08 18:06 : client: process command "currentsong"
Jul 08 18:06 : client: command returned 0
Jul 08 18:06 : client: [5] process command list returned 0
Jul 08 18:06 : client: [5] closed
@Diomendius
Copy link
Contributor

I decided to test this by having MPD output to a wav file through the "recorder" output type. After some surgery in Audacity I found out that the output from MPD is in perfect sample-sync compared with the two FLAC files spliced together, except that MPD skips 1681 samples at the end of the first MP3 file.

Here's some screenshots to illustrate what I mean:

MPD's output on top, both FLAC files together on bottom with the last 1681 samples of the first FLAC file highlighted:
before

The same, but with the highlighted region removed:
after

Zoomed in view of the track boundary with the unedited FLAC audio on bottom:
before-zoomed

The same, after cutting the FLAC audio:
after-zoomed

I have no idea why specifically 1681 samples get skipped (in addition to the padding that already gets skipped for MP3 files). I haven't yet tested whether using different MP3 files results in different degrees of skipping.

I have not yet tested the Opus files, but I have checked that they produce no gaps when decoded with opusdec, although for some reason ffmpeg doesn't skip some padding at the start of the files.

@MaxKellermann
Copy link
Member

MaxKellermann commented Aug 2, 2019 via email

@Diomendius
Copy link
Contributor

That's good to hear. Does the bug affect MP3/Vorbis/Opus equally, or are you talking about something specific to Vorbis?

MaxKellermann added a commit that referenced this issue Aug 2, 2019
The "end of stream" packet is not special; it contains normal data,
and thus we should pass it to OnOggPacket().

This fixes one part of #601
@MaxKellermann
Copy link
Member

Only Vorbis and Opus.

MaxKellermann added a commit that referenced this issue Aug 3, 2019
The Xing/LAME frame indicates how many frames there are, but that
excludes the initial Xing/LAME frame.  Therefore, it should not be
counted.

This fixes an off-by-one bug which caused the last frame to be
skipped, fixing one part of
#601
MaxKellermann added a commit that referenced this issue Aug 3, 2019
libmad requires padding the input buffer with "MAD_BUFFER_GUARD" zero
bytes at the end of the file, or else it is unable to decode the last
frame.

This fixes yet another bug which prevented this plugin from decoding
the last frame, see
#601
@averms
Copy link
Author

averms commented Aug 3, 2019

Awesome, thanks for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants