MusicPlayerDaemon / MPD

Music Player Daemon
https://www.musicpd.org/
GNU General Public License v2.0
2.2k stars 350 forks source link

MPD 24bit playback in zip is not bit perfect #1349

Closed Wang-Yue closed 3 years ago

Wang-Yue commented 3 years ago

Bug report

Describe the bug

put a 24 bits wav file in zip. mpd cannot play the file bit perfectly.

NOTE: MPD is able to play the same file in folder (not in zip) bit perfectly. MPD is also able to play 16 and 32 bits file in zip bit perfectly.

So this only happens when 24 bit file is compressed in a zip archive.

reproduce steps

  1. There is a bit test zip archive in RME website : https://synthax.jp/bittestwav.html just download https://synthax.jp/tl_files/tools/bit_test_wavs.zip and put it in MPD music folder directly.

  2. pick any 24 bit file (I use 192_24_adi2pro_bittest 4s.wav). decompress a copy and put it in the same folder.

  3. Now play the file in the zip archive

  4. Play the decompressed version in the folder

  5. On RME ADI-2 products, you'll find the first try didn't pass their bit test, but the second one passed.

  6. If you don't have an RME ADI-2, it's fine --- you'll see in log file that ffmpeg is not able to process the file. error message is

ffmpeg/pcm_s24le: Invalid PCM packet, data has size 2 but at least a size of 6 was expected
ffmpeg: avcodec_send_packet() failed: Invalid data found when processing input

for the file in the zip archive.

Version

Music Player Daemon 0.23.3 (v0.23.3)
Copyright 2003-2007 Warren Dukes <warren.dukes@gmail.com>
Copyright 2008-2021 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 udisks nfs curl

Neighbor plugins:
 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
 [sidplay] sid mus str prg P00
 [wildmidi] mid
 [fluidsynth] mid
 [adplug] amd d00 hsc laa rad raw sa2
 [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 rtp:// rtsp:// rtsps://
 [gme] ay gbs gym hes kss nsf nsfe rsn sap spc vgm vgz
 [pcm]

Filters:
 libsamplerate soxr

Tag plugins:
 id3tag

Output plugins:
 shout null fifo sndio pipe alsa ao openal pulse jack httpd snapcast recorder

Encoder plugins:
 null vorbis opus lame twolame wave flac shine

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

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

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

Protocols:
 file:// alsa:// cdda:// ftp:// ftps:// gopher:// hls+http:// hls+https:// http:// https:// mms:// mmsh:// mmst:// mmsu:// nfs:// qobuz:// rtmp:// rtmps:// rtmpt:// rtmpts:// rtp:// rtsp:// rtsps:// scp:// sftp:// smb:// srtp://

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

Log

Nov 16 23:40 : exception: Seek failed: zzip_seek() has failed
Nov 16 23:40 : sndfile: sf_open_virtual() failed: Error in WAV file. No 'data' chunk marker.
Nov 16 23:40 : exception: Seek failed: zzip_seek() has failed
Nov 16 23:40 : audiofile: Cannot seek in file
Nov 16 23:40 : audiofile: unrecognized audio file format
Nov 16 23:40 : ffmpeg/pcm_s24le: Multiple frames in a packet.
Nov 16 23:40 : ffmpeg/pcm_s24le: Invalid PCM packet, data has size 2 but at least a size of 6 was expected
Nov 16 23:40 : ffmpeg: avcodec_send_packet() failed: Invalid data found when processing input
Nov 16 23:40 : player: played "bit_test/bit_test_wavs.zip/192_24_adi2pro_bittest 4s.wav"
Nov 16 23:40 : player: played "bit_test/192_24_adi2pro_bittest 4s.wav"

Note: See the error is thrown when playing bit_test/bit_test_wavs.zip/192_24_adi2pro_bittest 4s.wav. But there's no error when playing bit_test/192_24_adi2pro_bittest 4s.wav

MaxKellermann commented 3 years ago

I can't reproduce this problem. I never see those seeking problems, and both sndfile and audiofile can decode the file from inside the ZIP archive. This is where you should debug: why does zzip_seek() fail? This is not MPD code, it's a third-party library.

Wang-Yue commented 3 years ago

@MaxKellermann I just compiled the same version on macOS and it did pass the bit-perfection test. The above test I reported yesterday was performed under Linux (Raspbian) on Raspberry Pi. So I guess this is an ARM only (or 32bit only?) issue.

neheb commented 3 years ago

most likely 32-bit.

MaxKellermann commented 3 years ago

So this bug report is not about the decoder errors, but only about bit-perfectness? The log you pasted does not show any successful playback at all. If you want this to be about bit-perfectness, you should provide enough information.

Wang-Yue commented 3 years ago

So this bug report is not about the decoder errors, but only about bit-perfectness? The log you pasted does not show any successful playback at all.

It is about decoder error, that results to non bit perfect playback. (file still being played, but not correctly, with lots of hiccups)

You can see from the top pasted log that I played two files, one with a lot of errors, including unrecognized audio file format then ended with played "bit_test/bit_test_wavs.zip/192_24_adi2pro_bittest 4s.wav, and the other ended player: played "bit_test/192_24_adi2pro_bittest 4s.wav without any error. The only difference is the former is in a compressed archive.

To explain the above log further ---

Here is the log when playing 24 bit files in a zip archive

Nov 16 23:40 : exception: Seek failed: zzip_seek() has failed
Nov 16 23:40 : sndfile: sf_open_virtual() failed: Error in WAV file. No 'data' chunk marker.
Nov 16 23:40 : exception: Seek failed: zzip_seek() has failed
Nov 16 23:40 : audiofile: Cannot seek in file
Nov 16 23:40 : audiofile: unrecognized audio file format
Nov 16 23:40 : ffmpeg/pcm_s24le: Multiple frames in a packet.
Nov 16 23:40 : ffmpeg/pcm_s24le: Invalid PCM packet, data has size 2 but at least a size of 6 was expected
Nov 16 23:40 : ffmpeg: avcodec_send_packet() failed: Invalid data found when processing input
Nov 16 23:40 : player: played "bit_test/bit_test_wavs.zip/192_24_adi2pro_bittest 4s.wav"

here's the log with play the same file in folder

Nov 16 23:40 : player: played "bit_test/192_24_adi2pro_bittest 4s.wav"

If you want this to be about bit-perfectness, you should provide enough information.

RME's ADI-2 DAC/Pro has a bit perfection checker. When playing the testing files they provided, the DAC will display something like "16-bit test Passed" so you know the entire software chain is bit perfect. I use this tool because it's very convenient (compared to recording from an artificial loopback device and do binary comparison).

On macOS the bit test passed, so I'm fully sure the entire chain is working fine. On Raspberry Pi the bit pass failed, and the audio is glitchy, and mpd is also throwing error messages, so something is not right.

MaxKellermann commented 3 years ago

In your log, no decoder reports that it succeeded decoding anything, and no output ever logged that it opened the audio device. It is incomplete. But in any case, I'm unable to debug your decoder error, because I can't reproduce it - as I said, please debug why zzip_seek() fails.

Wang-Yue commented 3 years ago

Here's the full log:

when playing in zip

pi@rpi4:~ $ mpd --no-daemon --stderr --verbose
config_file: loading file /home/pi/.mpd/mpd.conf
libsamplerate: libsamplerate converter 'Fastest Sinc Interpolator'
vorbis: Xiph.Org libVorbis 1.3.6
opus: libopus 1.3
sndfile: libsndfile-1.0.28
hybrid_dsd: The Hybrid DSD decoder is disabled because it was not explicitly enabled
decoder: Decoder plugin 'wildmidi' is unavailable: configuration file does not exist: /etc/timidity/timidity.cfg
adplug: adplug 2.2.1
simple_db: reading DB
input: Input plugin 'qobuz' is not configured: No Qobuz app_id configured
curl: version 7.64.0
curl: with GnuTLS/3.6.7
state_file: Loading state file /home/pi/.mpd/mpdstate
inotify: initializing inotify
inotify: watching music directory
client: [0] opened from 127.0.0.1:46094
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "plchanges "0""
client: [0] command returned 0
client: [0] process command "outputs"
client: [0] command returned 0
client: [0] process command "decoders"
client: [0] command returned 0
client: [0] process command "outputs"
client: [0] command returned 0
client: [0] process command "outputs"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "playid "1""
playlist: play 0:"bit_test/bit_test_wavs.zip/192_24_adi2pro_bittest 4s.wav"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
decoder_thread: probing plugin sndfile
exception: Seek failed: zzip_seek() has failed
sndfile: sf_open_virtual() failed: Error in WAV file. No 'data' chunk marker.
decoder_thread: probing plugin audiofile
exception: Seek failed: zzip_seek() has failed
audiofile: Cannot seek in file
audiofile: unrecognized audio file format
decoder_thread: probing plugin ffmpeg
ffmpeg/wav: Format wav probed with size=2048 and score=99
ffmpeg: detected input format 'wav' (WAV / WAVE (Waveform Audio))
ffmpeg/wav: Before avformat_find_stream_info() pos: 77824 bytes read:77824 seeks:0 nb_streams:1
ffmpeg/wav: parser not found for codec pcm_s24le, packets or times may be invalid.
ffmpeg/wav: parser not found for codec pcm_s24le, packets or times may be invalid.
ffmpeg/wav: All info found
ffmpeg/wav: stream 0: start_time: -48038396025285.289 duration: 3.890
ffmpeg/wav: format: start_time: -9223372036854.775 duration: 3.890 bitrate=9241 kb/s
ffmpeg/wav: After avformat_find_stream_info() pos: 282424 bytes read:282624 seeks:0 frames:50
ffmpeg: codec 'pcm_s24le'
decoder: audio_format=192000:32:2, seekable=true
alsa_output: opened hw:CARD=Pro57770499,DEV=0 type=HW
alsa_output: buffer: size=48..131072 time=250..682667
alsa_output: period: size=24..65536 time=125..341334
alsa_output: default period_time = buffer_time/4 = 500000/4 = 125000
alsa_output: format=S32_LE (Signed 32 bit Little Endian)
alsa_output: buffer_size=96000 period_size=24000
output: opened "RME ADI-2 Pro FS" (alsa) audio_format=192000:32:2
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
ffmpeg/pcm_s24le: Multiple frames in a packet.
ffmpeg/pcm_s24le: Invalid PCM packet, data has size 2 but at least a size of 6 was expected
ffmpeg: avcodec_send_packet() failed: Invalid data found when processing input
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
player: played "bit_test/bit_test_wavs.zip/192_24_adi2pro_bittest 4s.wav"
client: [0] command returned 0
playlist: stop
output: closed "RME ADI-2 Pro FS" (alsa)
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] closed

when playing in folder.

pi@rpi4:~ $ mpd --no-daemon --stderr --verbose
config_file: loading file /home/pi/.mpd/mpd.conf
libsamplerate: libsamplerate converter 'Fastest Sinc Interpolator'
vorbis: Xiph.Org libVorbis 1.3.6
opus: libopus 1.3
sndfile: libsndfile-1.0.28
hybrid_dsd: The Hybrid DSD decoder is disabled because it was not explicitly enabled
decoder: Decoder plugin 'wildmidi' is unavailable: configuration file does not exist: /etc/timidity/timidity.cfg
adplug: adplug 2.2.1
simple_db: reading DB
input: Input plugin 'qobuz' is not configured: No Qobuz app_id configured
curl: version 7.64.0
curl: with GnuTLS/3.6.7
state_file: Loading state file /home/pi/.mpd/mpdstate
inotify: initializing inotify
inotify: watching music directory
client: [0] opened from 127.0.0.1:46122
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "plchanges "0""
client: [0] command returned 0
client: [0] process command "outputs"
client: [0] command returned 0
client: [0] process command "decoders"
client: [0] command returned 0
client: [0] process command "outputs"
client: [0] command returned 0
client: [0] process command "outputs"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "playid "1""
playlist: play 0:"bit_test/192_24_adi2pro_bittest 4s.wav"
decoder_thread: probing plugin sndfile
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
decoder: audio_format=192000:32:2, seekable=true
alsa_output: opened hw:CARD=Pro57770499,DEV=0 type=HW
alsa_output: buffer: size=48..131072 time=250..682667
alsa_output: period: size=24..65536 time=125..341334
alsa_output: default period_time = buffer_time/4 = 500000/4 = 125000
alsa_output: format=S32_LE (Signed 32 bit Little Endian)
alsa_output: buffer_size=96000 period_size=24000
output: opened "RME ADI-2 Pro FS" (alsa) audio_format=192000:32:2
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
player: played "bit_test/192_24_adi2pro_bittest 4s.wav"
client: [0] command returned 0
playlist: stop
output: closed "RME ADI-2 Pro FS" (alsa)
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "status"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] closed

Seems sndfile/audiofile is not able to open the file, and mpd turn to ffmpeg in the compressed file case. while in the second case sndfile succeeded.

agree zzip is the issue.

Wang-Yue commented 3 years ago

I tried to print the seek location and it gives 0 at the first seek, then 12407427693644099592. Certainly this is something not right.

MaxKellermann commented 3 years ago

Where does this number come from?

MaxKellermann commented 3 years ago

One theory: are those libraries and MPD built with different LargeFile support settings, thus making them ABI-incompatible?

Wang-Yue commented 3 years ago

I'm just using the apt-get version of libzzip-dev.

Not sure if its an ABI issue --- 32/16 bits files are fine.

MaxKellermann commented 3 years ago

Without a useful reply, I assume that this is a LFS-specific ABI problem caused by zziplib or your distribution. Closing until somebody disproves my theory.