Closed koiuo closed 5 years ago
Post verbose log of start of playback, and tell me your MPD version number.
With audio_output_format *:24:2
$ mpd --no-daemon --stderr /etc/mpd.conf
...
client: [0] process command "playid "1""
playlist: play 0:"Silversun Pickups/2006 - Carnavas/08 Rusted Wheel.flac"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
decoder_thread: probing plugin flac
decoder: audio_format=44100:16:2, seekable=true
decoder: converting to 44100:24:2
exception: OutputThread could not get realtime scheduling, continuing anyway: sched_setscheduler failed: Operation not permitted
output: opened "Local PulseAudio server" (pulse) audio_format=44100:24:2
replay_gain: replay gain mode has changed off->album
replay_gain: scale=0.707946
replay_gain: scale=0.295461
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 "stop"
playlist: stop
player: played "Silversun Pickups/2006 - Carnavas/08 Rusted Wheel.flac"
output: closed "Local PulseAudio server" (pulse)
With audio_output_format
commented out
$ mpd --no-daemon --stderr /etc/mpd.conf
...
client: [0] process command "playid "1""
playlist: play 0:"Silversun Pickups/2006 - Carnavas/08 Rusted Wheel.flac"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
decoder_thread: probing plugin flac
decoder: audio_format=44100:16:2, seekable=true
exception: OutputThread could not get realtime scheduling, continuing anyway: sched_setscheduler failed: Operation not permitted
output: opened "Local PulseAudio server" (pulse) audio_format=44100:16:2
replay_gain: replay gain mode has changed off->album
replay_gain: scale=0.707946
replay_gain: scale=0.295461
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"
client: [0] command returned 0
client: [0] process command "idle"
client: [0] command returned 1
client: [0] process command "stop"
playlist: stop
player: played "Silversun Pickups/2006 - Carnavas/08 Rusted Wheel.flac"
output: closed "Local PulseAudio server" (pulse)
...
Config with stripped comments
music_directory "/mnt/sigma/media/music"
playlist_directory "~/mpd.playlists"
db_file "~/mpd.db"
log_file "~/mpd.log"
pid_file "~/mpd.pid"
state_file "~/mpd.state"
user "mpd"
auto_update "yes"
input {
plugin "curl"
}
audio_output_format "*:24:2"
audio_output {
type "alsa"
name "Default ALSA Device"
}
audio_output {
type "pulse"
name "Local PulseAudio Server"
}
replaygain "album"
replaygain_preamp "0"
replaygain_missing_preamp "-6"
filesystem_charset "UTF-8"
version
$ mpd --version
mpd --version
Music Player Daemon 0.21.7 (0.21.7)
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
Does it work if you use the "alsa" output instead of "pulse"?
I just tried to force 16 bit output (I should've tried this in the very begginning), and I hear similar noise with 24-bit files.
So the issue is with 16-bit output.
@MaxKellermann , yes, with ALSA I have the same noise, as with PulseAudio. With ALSA though, the noise is much louder (at least on E-MU 0404 USB, I don't have Audinst on me right now)
Try two more things:
hw0:0
reproducedreplaygain "off"
NOT reproducedAnother note, with replaygain "off"
and audio_output_format "*:16:2"
24-bit files have similar noise (but subjectively with few times higher base frequency).
I'd expect downsampling to impact sound quality, but I frankly would not expect the result to be this severe.
Applying software volume (which ReplayGain does, unless you configure it to use a hardware mixer) and converting 24 bit to 16 bit both uses dithering. So the problem may be MPD's dithering code.
Should we qualify this issue as a bug then? (I'll remove the [quesiton]
part from the title in this case).
Is there anything else I can do to help fixing the issue? (except for preparing a PR :sweat_smile: , I haven't ever written a line of production-grade C or C++ code)
Not yet - we don't know for sure if it's a bug. You can't do anything right now, thanks for the information so far, that was useful. (Unless you want to dig into MPD source code, see https://github.com/MusicPlayerDaemon/MPD/blob/master/src/pcm/PcmDither.cxx for the heart of the dithering code)
I checked the dithering code back and forth, and found no problem. Manipulating the volume on 16 bit samples works just fine, no noise (except for the floor noise caused by dithering, which is the very point of dithering). Same for converting 24 bit to 16 bit.
There is a unit test for this; you can run it with ninja test
(Meson needs to be configured with -Dtest=true
).
Can you record MPD's digital audio from a PulseAudio monitor? I'd like to see the noise.
Sorry making you wait.
Here's how the noise looks like.
Recordings are not exactly accurate because monitor, it seems, always records in 44100 Hz (which is also obvious from file sizes)
command I used to record
$ timeout 2 bash -c 'parec -d mpd.monitor > 16_44.pcm' & bash -c 'mpc play && sleep 2 && mpc stop'
In mpd config I have audio_output_format "*:16:2"
and replaygain "album"
mpd_dithering.zip
Your file shows dithering as expected. It's just that the levels of "non-silence" audio are extremely low; how can you even hear anything? If you pull your amp's volume knob high enough to be able to hear the actual music, then your amp will have amplified the dithering as well, making it audible as noise (which dithering is, by design). Usually, dithering is not audible.
@MaxKellermann , do you think it would make sense to adjust dithering algorithm so the output is limited by the amplitude of the original sample? In other words, don't do dithering, if there's silence in original audio.
BTW, this change does not require an excessive C++ knowledge, so I would be able to prepare a PR if you're open to the idea.
My last argument here would be that other players do not have this issue. Either they do not use dithering or they do some sort of normalization.
cmus and deadbeef both don't dither at all. While I would agree with making dithering a configuration option, I don't think MPD should determine this automatically. I rather think that there's something wrong with your setup - why is the volume level so extremely low? Of those 16 bits, you're only actually using 10 bits, the rest goes to the trash can. The dithering noise is just the most audible symptom of this problem.
@MaxKellermann , dithering noise is only audible on high volume levels - true. I can only notice it on some tracks, that have sort of "fade in" in them - true. I also use replaygain with no pregain, so usually dynamic range on my setup is a little bit narrower - true.
But I wouldn't say the setup is wrong. And also I've never noticed anything similar with any other player. So I'm blaming MPD here ;)
I personally didn't expect to see dithering in MPD. Hence, making dithering configurable is of course an option I'd like to see.
The other option I see is revising dithering algorithm. I'm not familiar with standard approach in this field, but let's think this way: the purpose of dithering is to mask quantization error, if dithering introduces an audible artifact which you can hear better than the quantization error, then something is wrong. Again, I'm not familiar with any existing open-source dithering algorithms for audio, but if we are to improve the one implemented in MPD already, I would consider limiting the amplitude of the dithering introduced. If on some interval of time our signal only occupies 3 bits, then my bet would be that by introducing 3 bit dithering we only make it worse. Of course we can perform measurements/calculations to prove that (and I'd be happy to do this over some weekend if needed).
Finally, setting output format to 24-bit resolves the issue for me, so I would be fine with leaving things as they are. But this issue is an interesting issue to tackle, so if you're open to changing this, I'd be eager to offer my help.
@edio I've tried to implement an optimization for you - please try it and give feedback.
@MaxKellermann, I apologize for responding just now. Had no chance to look at the change immediately after you made it (was travelling and had no proper setup to test) and then it just slipped my mind.
At first, thank you for addressing this!
Judging from the date of commit, this should've been included in 0.21.13 release, is this right?
I'm currently on 0.21.14, and I still observe a clear difference in sound when I comment/uncomment audio_output_format "*:24:2"
line in mpd.conf
.
I also, honestly, can not hear any difference between 0.21.10 and 0.21.14 with audio_output_format
property commented out.
This I guess is expected and by design. The dithering that mpd adds didn't go away. And improvement in the precision of software volume control I, apparently, can not hear. But knowing that it has improved gives a pleasent peace-of-mind feeling anyway :)
If you want another set of outputs recordings or any other tests performed with regards to this issue, let me know, I'd be happy to work on this.
Thanks again!
No, this is not included in 0.21.13. Why do you think so? Do you see it in the change log? This will be included in 0.22, and is currently in git master.
My bad. Will test with master later
$ mpd --version
Music Player Daemon 0.22~git (v0.21.14-618-gd63e2c264)
On 0.22~git I can still hear difference between *:24:2
and *:16:2
.
I don't hear any improvement comparing to 0.21.14, not saying it's not there, but I can't hear it. This is solely subjective, I haven't done any objective measurements.
I used the same config as I had with 0.21.14, did I miss some configuration option somewhere?
When listening to 16-bit files on a sound-card that supports 24-bit, while having
audio_output_format
commented out, mpd produces quiet, but yet audible noise. Subjectively I would characterize the noise as having line spectrum, with the base frequency quite low (up to tens of Hz) but certainly having lots of higher harmonics. I could try to record it if necessary, but would be happy to avoid this activity :)Today I discovered, that if I explicitly set sample format to
the noise disappears.
Since the workaround is found and I'm no longer impacted, I wouldn't say, that this is something requiring immediate attention.
But out of pure curiousity I'd like to understand what's going on, why MPD has noise for 16-bit files in its output if output format is not configured.
Please let me know if any additional information is required on this or if you'd like me to perform some tests or to attempt recording the noise.
P.S. I reported this before on an old Mantis tracker, however, couldn't provide good steps to reproduce back in the time.