Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e239009295 | ||
![]() |
3fae2150f5 | ||
![]() |
f9ca2f52c1 | ||
![]() |
4b81cf0c2c | ||
![]() |
e7acbf112c | ||
![]() |
304d45b551 | ||
![]() |
0f488dcecf | ||
![]() |
17039aec70 | ||
![]() |
fb6cb07912 | ||
![]() |
e9e0e02db3 | ||
![]() |
03507037e8 | ||
![]() |
66a8fac25e | ||
![]() |
1b902e00b4 | ||
![]() |
923e66738c | ||
![]() |
ff3e2c0514 | ||
![]() |
6922a2f55e | ||
![]() |
ca5a400dbe | ||
![]() |
63fe4d1d17 | ||
![]() |
ca06d9d3bf | ||
![]() |
ed2db04f43 | ||
![]() |
de0afa0e08 | ||
![]() |
f0d3227d7b | ||
![]() |
fb07a7cecc | ||
![]() |
c6b08a4d48 | ||
![]() |
040e87ad8d | ||
![]() |
d5521ead56 | ||
![]() |
f8468451c9 | ||
![]() |
65df6ca14e | ||
![]() |
36dec47bf7 | ||
![]() |
478cedcadf |
15
NEWS
15
NEWS
@@ -1,3 +1,18 @@
|
||||
ver 0.21.10 (2019/06/05)
|
||||
* decoder
|
||||
- opus: fix duplicate tags
|
||||
* output
|
||||
- httpd: reject some well-known URIs
|
||||
* fix crash bug (0.21.9 regression)
|
||||
|
||||
ver 0.21.9 (2019/05/20)
|
||||
* input
|
||||
- buffer: fix deadlock bug
|
||||
* Android
|
||||
- fix crash on ARMv7
|
||||
- request storage permission on Android 6+
|
||||
* fix spurious "single" mode bug
|
||||
|
||||
ver 0.21.8 (2019/04/23)
|
||||
* input
|
||||
- smbclient: download to buffer instead of throttling transfer
|
||||
|
@@ -2,8 +2,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.musicpd"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="30"
|
||||
android:versionName="0.21.8">
|
||||
android:versionCode="33"
|
||||
android:versionName="0.21.10">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
|
||||
|
||||
|
@@ -138,6 +138,12 @@ class AndroidNdkToolchain:
|
||||
libstdcxx_ldflags = libstdcxx_flags + ' -L' + libcxx_libs_path
|
||||
libstdcxx_libs = '-lc++_static -lc++abi'
|
||||
|
||||
if self.is_armv7:
|
||||
# On 32 bit ARM, clang generates no ".eh_frame" section;
|
||||
# instead, the LLVM unwinder library is used for unwinding
|
||||
# the stack after a C++ exception was thrown
|
||||
libstdcxx_libs += ' -lunwind'
|
||||
|
||||
if use_cxx:
|
||||
self.cxxflags += ' ' + libstdcxx_cxxflags
|
||||
self.ldflags += ' ' + libstdcxx_ldflags
|
||||
|
@@ -6,7 +6,7 @@ android_sdk = get_option('android_sdk')
|
||||
android_abi = get_option('android_abi')
|
||||
|
||||
android_sdk_build_tools_version = '27.0.0'
|
||||
android_sdk_platform = 'android-21'
|
||||
android_sdk_platform = 'android-23'
|
||||
|
||||
android_build_tools_dir = join_paths(android_sdk, 'build-tools', android_sdk_build_tools_version)
|
||||
android_sdk_platform_dir = join_paths(android_sdk, 'platforms', android_sdk_platform)
|
||||
|
@@ -21,10 +21,12 @@ package org.musicpd;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -178,6 +180,14 @@ public class Settings extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
/* TODO: this sure is the wrong place to request
|
||||
permissions - it will cause MPD to quit
|
||||
immediately; we should request permissions when we
|
||||
need them, but implementing that is complicated, so
|
||||
for now, we do it here to give users a quick
|
||||
solution for the problem */
|
||||
requestAllPermissions();
|
||||
|
||||
setContentView(R.layout.settings);
|
||||
mRunButton = (ToggleButton) findViewById(R.id.run);
|
||||
mRunButton.setOnCheckedChangeListener(mOnRunChangeListener);
|
||||
@@ -203,6 +213,31 @@ public class Settings extends Activity {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
private void checkRequestPermission(String permission) {
|
||||
if (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED)
|
||||
return;
|
||||
|
||||
try {
|
||||
this.requestPermissions(new String[]{permission}, 0);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "requestPermissions(" + permission + ") failed",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestAllPermissions() {
|
||||
if (android.os.Build.VERSION.SDK_INT < 23)
|
||||
/* we don't need to request permissions on
|
||||
this old Android version */
|
||||
return;
|
||||
|
||||
/* starting with Android 6.0, we need to explicitly
|
||||
request all permissions before using them;
|
||||
mentioning them in the manifest is not enough */
|
||||
|
||||
checkRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
}
|
||||
|
||||
private void connectClient() {
|
||||
mClient = new Main.Client(this, new Main.Client.Callback() {
|
||||
|
||||
|
@@ -38,7 +38,7 @@ author = 'Max Kellermann'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.21.8'
|
||||
version = '0.21.10'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
|
@@ -2,12 +2,12 @@ Developer's Manual
|
||||
##################
|
||||
|
||||
Introduction
|
||||
============
|
||||
************
|
||||
|
||||
This is a guide for those who wish to hack on the MPD source code. MPD is an open project, and we are always happy about contributions. So far, more than 150 people have contributed patches. This document is work in progress. Most of it may be incomplete yet. Please help!
|
||||
|
||||
Code Style
|
||||
==========
|
||||
**********
|
||||
|
||||
* indent with tabs (width 8)
|
||||
* don't write CPP when you can write C++: use inline functions and constexpr instead of macros
|
||||
@@ -18,7 +18,6 @@ Code Style
|
||||
* classes and functions names use CamelCase; variables are lower-case with words separated by underscore
|
||||
|
||||
Some example code:
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -33,7 +32,7 @@ Some example code:
|
||||
}
|
||||
|
||||
Hacking The Source
|
||||
==================
|
||||
******************
|
||||
|
||||
MPD sources are managed in a git repository on
|
||||
`Github <https://github.com/MusicPlayerDaemon/>`_.
|
||||
@@ -59,7 +58,7 @@ possible, to be sure that you don't break any disabled code.
|
||||
Don't mix several changes in one single patch. Create a separate patch for every change. Tools like :program:`stgit` help you with that. This way, we can review your patches more easily, and we can pick the patches we like most first.
|
||||
|
||||
Basic stgit usage
|
||||
-----------------
|
||||
=================
|
||||
|
||||
stgit allows you to create a set of patches and refine all of them: you can go back to any patch at any time, and re-edit it (both the code and the commit message). You can reorder patches and insert new patches at any position. It encourages creating separate patches for tiny changes.
|
||||
|
||||
@@ -94,33 +93,7 @@ When the whole patch series is finished, convert stgit patches to git commits:
|
||||
stg commit
|
||||
|
||||
Submitting Patches
|
||||
==================
|
||||
******************
|
||||
|
||||
Submit pull requests on GitHub:
|
||||
https://github.com/MusicPlayerDaemon/MPD/pulls
|
||||
|
||||
Development Tools
|
||||
=================
|
||||
|
||||
Clang Static Analyzer
|
||||
---------------------
|
||||
|
||||
The `static analyzer <http://clang-analyzer.llvm.org/>`_ is a tool that helps find bugs. To run it on the MPD code base, install LLVM and clang. configure MPD to use clang:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./configure --enable-debug CXX=clang++ CC=clang ...
|
||||
|
||||
It is recommended to use :code:`--enable-debug`, because the analyzer
|
||||
takes advantage of :dfn:`assert()` calls, which are only enabled in
|
||||
the debug build.
|
||||
|
||||
Now run the analyzer:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
scan-build --use-c++=clang++ --use-cc=clang make
|
||||
|
||||
The options :code:`--use-c++` and :code:`--use-cc` are necessary
|
||||
because it invokes :command:`cc` for actually compiling the sources by
|
||||
default. That breaks, because MPD requires a C99 compiler.
|
||||
|
@@ -140,7 +140,6 @@ of database.
|
||||
.B auto_update_depth <N>
|
||||
Limit the depth of the directories being watched, 0 means only watch
|
||||
the music directory itself. There is no limit by default.
|
||||
.TP
|
||||
.SH REQUIRED AUDIO OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B type <type>
|
||||
@@ -164,57 +163,12 @@ Specifies how replay gain is applied. The default is "software",
|
||||
which uses an internal software volume control. "mixer" uses the
|
||||
configured (hardware) mixer control. "none" disables replay gain on
|
||||
this audio output.
|
||||
.SH OPTIONAL ALSA OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B device <dev>
|
||||
This specifies the device to use for audio output. The default is "default".
|
||||
.TP
|
||||
.B mixer_type <hardware, software or none>
|
||||
Specifies which mixer should be used for this audio output: the
|
||||
hardware mixer (available for ALSA, OSS and PulseAudio), the software
|
||||
mixer or no mixer ("none"). By default, the hardware mixer is used
|
||||
for devices which support it, and none for the others.
|
||||
.TP
|
||||
.B mixer_device <mixer dev>
|
||||
This specifies which mixer to use. The default is "default". To use
|
||||
the second sound card in a system, use "hw:1".
|
||||
.TP
|
||||
.B mixer_control <mixer ctrl>
|
||||
This specifies which mixer control to use (sometimes referred to as
|
||||
the "device"). The default is "PCM". Use "amixer scontrols" to see
|
||||
the list of possible controls.
|
||||
.TP
|
||||
.B mixer_index <mixer index>
|
||||
A number identifying the index of the named mixer control. This is
|
||||
probably only useful if your alsa device has more than one
|
||||
identically\-named mixer control. The default is "0". Use "amixer
|
||||
scontrols" to see the list of controls with their indexes.
|
||||
.TP
|
||||
.B auto_resample <yes or no>
|
||||
Setting this to "no" disables ALSA's software resampling, if the
|
||||
hardware does not support a specific sample rate. This lets MPD do
|
||||
the resampling. "yes" is the default and allows ALSA to resample.
|
||||
.TP
|
||||
.B auto_channels <yes or no>
|
||||
Setting this to "no" disables ALSA's channel conversion, if the
|
||||
hardware does not support a specific number of channels. Default: "yes".
|
||||
.TP
|
||||
.B auto_format <yes or no>
|
||||
Setting this to "no" disables ALSA's sample format conversion, if the
|
||||
hardware does not support a specific sample format. Default: "yes".
|
||||
.TP
|
||||
.B buffer_time <time in microseconds>
|
||||
This sets the length of the hardware sample buffer in microseconds. Increasing
|
||||
it may help to reduce or eliminate skipping on certain setups. Most users do
|
||||
not need to change this. The default is 500000 microseconds (0.5 seconds).
|
||||
.TP
|
||||
.B period_time <time in microseconds>
|
||||
This sets the time between hardware sample transfers in microseconds.
|
||||
Increasing this can reduce CPU usage while lowering it can reduce underrun
|
||||
errors on bandwidth-limited devices. Some users have reported good results
|
||||
with this set to 50000, but not all devices support values this high. Most
|
||||
users do not need to change this. The default is 256000000 / sample_rate(kHz),
|
||||
or 5804 microseconds for CD-quality audio.
|
||||
.SH FILES
|
||||
.TP
|
||||
.BI ~/.mpdconf
|
||||
|
198
doc/plugins.rst
198
doc/plugins.rst
@@ -4,10 +4,10 @@ Plugin reference
|
||||
.. _database_plugins:
|
||||
|
||||
Database plugins
|
||||
----------------
|
||||
================
|
||||
|
||||
simple
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
The default plugin. Stores a copy of the database in memory. A file is used for permanent storage.
|
||||
|
||||
@@ -25,7 +25,7 @@ The default plugin. Stores a copy of the database in memory. A file is used for
|
||||
- Compress the database file using gzip? Enabled by default (if built with zlib).
|
||||
|
||||
proxy
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
Provides access to the database of another :program:`MPD` instance using libmpdclient. This is useful when you run mount the music directory via NFS/SMB, and the file server already runs a :program:`MPD` instance. Only the file server needs to update the database.
|
||||
|
||||
@@ -45,30 +45,30 @@ Provides access to the database of another :program:`MPD` instance using libmpdc
|
||||
- Send TCP keepalive packets to the "master" :program:`MPD` instance? This option can help avoid certain firewalls dropping inactive connections, at the expensive of a very small amount of additional network traffic. Disabled by default.
|
||||
|
||||
upnp
|
||||
~~~~
|
||||
----
|
||||
|
||||
Provides access to UPnP media servers.
|
||||
|
||||
Storage plugins
|
||||
---------------
|
||||
===============
|
||||
|
||||
local
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
The default plugin which gives :program:`MPD` access to local files. It is used when music_directory refers to a local directory.
|
||||
|
||||
curl
|
||||
~~~~
|
||||
----
|
||||
|
||||
A WebDAV client using libcurl. It is used when :code:`music_directory` contains a http:// or https:// URI, for example :samp:`https://the.server/dav/`.
|
||||
|
||||
smbclient
|
||||
~~~~~~~~~
|
||||
---------
|
||||
|
||||
Load music files from a SMB/CIFS server. It is used when :code:`music_directory` contains a smb:// URI, for example :samp:`smb://myfileserver/Music`.
|
||||
|
||||
nfs
|
||||
~~~
|
||||
---
|
||||
|
||||
Load music files from a NFS server. It is used when :code:`music_directory` contains a nfs:// URI according to RFC2224, for example :samp:`nfs://servername/path`.
|
||||
|
||||
@@ -81,7 +81,7 @@ This plugin uses libnfs, which supports only NFS version 3. Since :program:`MPD`
|
||||
Don't fear: "insecure" does not mean that your NFS server is insecure. A few decades ago, people thought the concept of "privileged ports" would make network services "secure", which was a fallacy. The absence of this obsolete "security" measure means little.
|
||||
|
||||
udisks
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Mount file systems (e.g. USB sticks or other removable media) using
|
||||
the udisks2 daemon via D-Bus. To obtain a valid udisks2 URI, consult
|
||||
@@ -106,29 +106,30 @@ MPD user.
|
||||
.. _neighbor_plugin:
|
||||
|
||||
Neighbor plugins
|
||||
----------------
|
||||
================
|
||||
|
||||
smbclient
|
||||
~~~~~~~~~
|
||||
---------
|
||||
|
||||
Provides a list of SMB/CIFS servers on the local network.
|
||||
|
||||
udisks
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Queries the udisks2 daemon via D-Bus and obtain a list of file systems (e.g. USB sticks or other removable media).
|
||||
|
||||
upnp
|
||||
~~~~
|
||||
----
|
||||
|
||||
Provides a list of UPnP servers on the local network.
|
||||
|
||||
.. _input_plugins:
|
||||
|
||||
Input plugins
|
||||
-------------
|
||||
=============
|
||||
|
||||
alsa
|
||||
~~~~
|
||||
----
|
||||
|
||||
Allows :program:`MPD` on Linux to play audio directly from a soundcard using the scheme alsa://. Audio is formatted as 44.1 kHz 16-bit stereo (CD format). Examples:
|
||||
|
||||
@@ -141,7 +142,7 @@ Allows :program:`MPD` on Linux to play audio directly from a soundcard using the
|
||||
mpc add alsa://hw:1,0 plays audio from device hw:1,0 cdio_paranoia
|
||||
|
||||
cdio_paranoia
|
||||
~~~~~~~~~~~~~
|
||||
-------------
|
||||
|
||||
Plays audio CDs using libcdio. The URI has the form: "cdda://[DEVICE][/TRACK]". The simplest form cdda:// plays the whole disc in the default drive.
|
||||
|
||||
@@ -157,7 +158,7 @@ Plays audio CDs using libcdio. The URI has the form: "cdda://[DEVICE][/TRACK]".
|
||||
- Request CDParanoia cap the extraction speed to Nx normal CD audio rotation speed, keeping the drive quiet.
|
||||
|
||||
curl
|
||||
~~~~
|
||||
----
|
||||
|
||||
Opens remote files or streams over HTTP using libcurl.
|
||||
|
||||
@@ -179,22 +180,22 @@ Note that unless overridden by the below settings (e.g. by setting them to a bla
|
||||
- Verify the certificate's name against host? `More information <http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html>`_.
|
||||
|
||||
ffmpeg
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Access to various network protocols implemented by the FFmpeg library: gopher://, rtp://, rtsp://, rtmp://, rtmpt://, rtmps://
|
||||
|
||||
file
|
||||
~~~~
|
||||
----
|
||||
|
||||
Opens local files
|
||||
|
||||
mms
|
||||
~~~
|
||||
---
|
||||
|
||||
Plays streams with the MMS protocol using `libmms <https://launchpad.net/libmms>`_.
|
||||
|
||||
nfs
|
||||
~~~
|
||||
---
|
||||
|
||||
Allows :program:`MPD` to access files on NFSv3 servers without actually mounting them (i.e. in userspace, without help from the kernel's VFS layer). All URIs with the nfs:// scheme are used according to RFC2224. Example:
|
||||
|
||||
@@ -205,7 +206,7 @@ Allows :program:`MPD` to access files on NFSv3 servers without actually mounting
|
||||
Note that this usually requires enabling the "insecure" flag in the server's /etc/exports file, because :program:`MPD` cannot bind to so-called "privileged" ports. Don't fear: this will not make your file server insecure; the flag was named in a time long ago when privileged ports were thought to be meaningful for security. By today's standards, NFSv3 is not secure at all, and if you believe it is, you're already doomed.
|
||||
|
||||
smbclient
|
||||
~~~~~~~~~
|
||||
---------
|
||||
|
||||
Allows :program:`MPD` to access files on SMB/CIFS servers (e.g. Samba or Microsoft Windows). All URIs with the smb:// scheme are used. Example:
|
||||
|
||||
@@ -214,7 +215,7 @@ Allows :program:`MPD` to access files on SMB/CIFS servers (e.g. Samba or Microso
|
||||
mpc add smb://servername/sharename/filename.ogg
|
||||
|
||||
qobuz
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
Play songs from the commercial streaming service Qobuz. It plays URLs in the form qobuz://track/ID, e.g.:
|
||||
|
||||
@@ -240,7 +241,7 @@ Play songs from the commercial streaming service Qobuz. It plays URLs in the for
|
||||
- The `Qobuz format identifier <https://github.com/Qobuz/api-documentation/blob/master/endpoints/track/getFileUrl.md#parameters>`_, i.e. a number which chooses the format and quality to be requested from Qobuz. The default is "5" (320 kbit/s MP3).
|
||||
|
||||
tidal
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
Play songs from the commercial streaming service `Tidal <http://tidal.com/>`_. It plays URLs in the form tidal://track/ID, e.g.:
|
||||
|
||||
@@ -266,10 +267,10 @@ Play songs from the commercial streaming service `Tidal <http://tidal.com/>`_. I
|
||||
.. _decoder_plugins:
|
||||
|
||||
Decoder plugins
|
||||
---------------
|
||||
===============
|
||||
|
||||
adplug
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Decodes AdLib files using libadplug.
|
||||
|
||||
@@ -283,17 +284,17 @@ Decodes AdLib files using libadplug.
|
||||
- The sample rate that shall be synthesized by the plugin. Defaults to 48000.
|
||||
|
||||
audiofile
|
||||
~~~~~~~~~
|
||||
---------
|
||||
|
||||
Decodes WAV and AIFF files using libaudiofile.
|
||||
|
||||
faad
|
||||
~~~~
|
||||
----
|
||||
|
||||
Decodes AAC files using libfaad.
|
||||
|
||||
ffmpeg
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Decodes various codecs using FFmpeg.
|
||||
|
||||
@@ -309,12 +310,12 @@ Decodes various codecs using FFmpeg.
|
||||
- Sets the FFmpeg muxer option probesize, which specifies probing size in bytes, i.e. the size of the data to analyze to get stream information. The `FFmpeg formats documentation <https://ffmpeg.org/ffmpeg-formats.html>`_ has more information.
|
||||
|
||||
flac
|
||||
~~~~
|
||||
----
|
||||
|
||||
Decodes FLAC files using libFLAC.
|
||||
|
||||
dsdiff
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Decodes DFF files containing DSDIFF data (e.g. SACD rips).
|
||||
|
||||
@@ -328,12 +329,12 @@ Decodes DFF files containing DSDIFF data (e.g. SACD rips).
|
||||
- Decode the least significant bit first. Default is no.
|
||||
|
||||
dsf
|
||||
~~~
|
||||
---
|
||||
|
||||
Decodes DSF files containing DSDIFF data (e.g. SACD rips).
|
||||
|
||||
fluidsynth
|
||||
~~~~~~~~~~
|
||||
----------
|
||||
|
||||
MIDI decoder based on `FluidSynth <http://www.fluidsynth.org/>`_.
|
||||
|
||||
@@ -349,7 +350,7 @@ MIDI decoder based on `FluidSynth <http://www.fluidsynth.org/>`_.
|
||||
- The absolute path of the soundfont file. Defaults to :file:`/usr/share/sounds/sf2/FluidR3_GM.sf2`.
|
||||
|
||||
gme
|
||||
~~~
|
||||
---
|
||||
|
||||
Video game music file emulator based on `game-music-emu <https://bitbucket.org/mpyne/game-music-emu/wiki/Home>`_.
|
||||
|
||||
@@ -363,7 +364,7 @@ Video game music file emulator based on `game-music-emu <https://bitbucket.org/m
|
||||
- Enable more accurate sound emulation.
|
||||
|
||||
hybrid_dsd
|
||||
~~~~~~~~~~
|
||||
----------
|
||||
|
||||
`Hybrid-DSD
|
||||
<http://dsdmaster.blogspot.de/p/bitperfect-introduces-hybrid-dsd-file.html>`_
|
||||
@@ -386,12 +387,12 @@ of the file is better.
|
||||
- This specifies whether to support gapless playback of MP3s which have the necessary headers. Useful if your MP3s have headers with incorrect information. If you have such MP3s, it is highly recommended that you fix them using `vbrfix <http://www.willwap.co.uk/Programs/vbrfix.php>`_ instead of disabling gapless MP3 playback. The default is to support gapless MP3 playback.
|
||||
|
||||
mad
|
||||
~~~
|
||||
---
|
||||
|
||||
Decodes MP3 files using `libmad <http://www.underbit.com/products/mad/>`_.
|
||||
|
||||
mikmod
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Module player based on `MikMod <http://mikmod.sourceforge.net/>`_.
|
||||
|
||||
@@ -407,7 +408,7 @@ Module player based on `MikMod <http://mikmod.sourceforge.net/>`_.
|
||||
- Sets the sample rate generated by libmikmod. Default is 44100.
|
||||
|
||||
modplug
|
||||
~~~~~~~
|
||||
-------
|
||||
|
||||
Module player based on MODPlug.
|
||||
|
||||
@@ -421,27 +422,27 @@ Module player based on MODPlug.
|
||||
- Number of times to loop the module if it uses backward loops. Default is 0 which prevents looping. -1 loops forever.
|
||||
|
||||
mpcdec
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Decodes Musepack files using `libmpcdec <http://www.musepack.net/>`_.
|
||||
|
||||
mpg123
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Decodes MP3 files using `libmpg123 <http://www.mpg123.de/>`_.
|
||||
|
||||
opus
|
||||
~~~~
|
||||
----
|
||||
|
||||
Decodes Opus files using `libopus <http://www.opus-codec.org/>`_.
|
||||
|
||||
pcm
|
||||
~~~
|
||||
---
|
||||
|
||||
Read raw PCM samples. It understands the "audio/L16" MIME type with parameters "rate" and "channels" according to RFC 2586. It also understands the MPD-specific MIME type "audio/x-mpd-float".
|
||||
|
||||
sidplay
|
||||
~~~~~~~
|
||||
-------
|
||||
|
||||
C64 SID decoder based on `libsidplayfp <https://sourceforge.net/projects/sidplay-residfp/>`_ or `libsidplay2 <https://sourceforge.net/projects/sidplay2/>`_.
|
||||
|
||||
@@ -463,23 +464,23 @@ C64 SID decoder based on `libsidplayfp <https://sourceforge.net/projects/sidplay
|
||||
- Only libsidplayfp. Absolute path to basic rom image file.
|
||||
|
||||
sndfile
|
||||
~~~~~~~
|
||||
-------
|
||||
|
||||
Decodes WAV and AIFF files using `libsndfile <http://www.mega-nerd.com/libsndfile/>`_.
|
||||
|
||||
|
||||
vorbis
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Decodes Ogg-Vorbis files using `libvorbis <http://www.xiph.org/ogg/vorbis/>`_.
|
||||
|
||||
wavpack
|
||||
~~~~~~~
|
||||
-------
|
||||
|
||||
Decodes WavPack files using `libwavpack <http://www.wavpack.com/>`_.
|
||||
|
||||
wildmidi
|
||||
~~~~~~~~
|
||||
--------
|
||||
|
||||
MIDI decoder based on `libwildmidi <http://www.mindwerks.net/projects/wildmidi/>`_.
|
||||
|
||||
@@ -495,10 +496,11 @@ MIDI decoder based on `libwildmidi <http://www.mindwerks.net/projects/wildmidi/>
|
||||
.. _encoder_plugins:
|
||||
|
||||
Encoder plugins
|
||||
---------------
|
||||
===============
|
||||
|
||||
flac
|
||||
~~~~
|
||||
----
|
||||
|
||||
Encodes into `FLAC <https://xiph.org/flac/>`_ (lossless).
|
||||
|
||||
.. list-table::
|
||||
@@ -511,7 +513,7 @@ Encodes into `FLAC <https://xiph.org/flac/>`_ (lossless).
|
||||
- Sets the libFLAC compression level. The levels range from 0 (fastest, least compression) to 8 (slowest, most compression).
|
||||
|
||||
lame
|
||||
~~~~
|
||||
----
|
||||
|
||||
Encodes into MP3 using the `LAME <http://lame.sourceforge.net/>`_ library.
|
||||
|
||||
@@ -527,12 +529,12 @@ Encodes into MP3 using the `LAME <http://lame.sourceforge.net/>`_ library.
|
||||
- Sets the bit rate in kilobit per second. Cannot be used with quality.
|
||||
|
||||
null
|
||||
~~~~
|
||||
----
|
||||
|
||||
Does not encode anything, passes the input PCM data as-is.
|
||||
|
||||
shine
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
Encodes into MP3 using the `Shine <https://github.com/savonet/shine>`_ library.
|
||||
|
||||
@@ -546,7 +548,7 @@ Encodes into MP3 using the `Shine <https://github.com/savonet/shine>`_ library.
|
||||
- Sets the bit rate in kilobit per second.
|
||||
|
||||
twolame
|
||||
~~~~~~~
|
||||
-------
|
||||
|
||||
Encodes into MP2 using the `TwoLAME <http://www.twolame.org/>`_ library.
|
||||
|
||||
@@ -562,7 +564,7 @@ Encodes into MP2 using the `TwoLAME <http://www.twolame.org/>`_ library.
|
||||
- Sets the bit rate in kilobit per second. Cannot be used with quality.
|
||||
|
||||
opus
|
||||
~~~~
|
||||
----
|
||||
|
||||
Encodes into `Ogg Opus <http://www.opus-codec.org/>`_.
|
||||
|
||||
@@ -584,7 +586,7 @@ Encodes into `Ogg Opus <http://www.opus-codec.org/>`_.
|
||||
.. _vorbis_plugin:
|
||||
|
||||
vorbis
|
||||
~~~~~~
|
||||
------
|
||||
|
||||
Encodes into `Ogg Vorbis <http://www.vorbis.com/>`_.
|
||||
|
||||
@@ -600,13 +602,13 @@ Encodes into `Ogg Vorbis <http://www.vorbis.com/>`_.
|
||||
- Sets the bit rate in kilobit per second. Cannot be used with quality.
|
||||
|
||||
wave
|
||||
~~~~
|
||||
----
|
||||
Encodes into WAV (lossless).
|
||||
|
||||
.. _resampler_plugins:
|
||||
|
||||
Resampler plugins
|
||||
-----------------
|
||||
=================
|
||||
|
||||
The resampler can be configured in a block named resampler, for example:
|
||||
|
||||
@@ -629,12 +631,12 @@ The following table lists the resampler options valid for all plugins:
|
||||
- The name of the plugin.
|
||||
|
||||
internal
|
||||
~~~~~~~~
|
||||
--------
|
||||
|
||||
A resampler built into :program:`MPD`. Its quality is very poor, but its CPU usage is low. This is the fallback if :program:`MPD` was compiled without an external resampler.
|
||||
|
||||
libsamplerate
|
||||
~~~~~~~~~~~~~
|
||||
-------------
|
||||
|
||||
A resampler using `libsamplerate <http://www.mega-nerd.com/SRC/>`_ a.k.a. Secret Rabbit Code (SRC).
|
||||
|
||||
@@ -667,7 +669,7 @@ The following converter types are provided by libsamplerate:
|
||||
- Linear interpolator, very fast, poor quality.
|
||||
|
||||
soxr
|
||||
~~~~
|
||||
----
|
||||
|
||||
A resampler using `libsoxr <http://sourceforge.net/projects/soxr/>`_, the SoX Resampler library
|
||||
|
||||
@@ -693,12 +695,12 @@ Valid quality values for libsoxr:
|
||||
.. _output_plugins:
|
||||
|
||||
Output plugins
|
||||
--------------
|
||||
==============
|
||||
|
||||
.. _alsa_plugin:
|
||||
|
||||
alsa
|
||||
~~~~
|
||||
----
|
||||
|
||||
The `Advanced Linux Sound Architecture (ALSA) <http://www.alsa-project.org/>`_ plugin uses libasound. It is recommended if you are using Linux.
|
||||
|
||||
@@ -757,7 +759,7 @@ The following attributes can be configured at runtime using the outputset comman
|
||||
|
||||
|
||||
ao
|
||||
~~
|
||||
--
|
||||
The ao plugin uses the portable `libao <https://www.xiph.org/ao/>`_ library. Use only if there is no native plugin for your operating system.
|
||||
|
||||
.. list-table::
|
||||
@@ -774,7 +776,8 @@ The ao plugin uses the portable `libao <https://www.xiph.org/ao/>`_ library. Use
|
||||
- This specifies how many bytes to write to the audio device at once. This parameter is to work around a bug in older versions of libao on sound cards with very small buffers. The default is 1024.
|
||||
|
||||
sndio
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
The sndio plugin uses the `sndio <http://www.sndio.org/>`_ library. It should normally be used on OpenBSD.
|
||||
|
||||
.. list-table::
|
||||
@@ -789,7 +792,7 @@ The sndio plugin uses the `sndio <http://www.sndio.org/>`_ library. It should no
|
||||
- Set the application buffer time in milliseconds.
|
||||
|
||||
fifo
|
||||
~~~~
|
||||
----
|
||||
|
||||
The fifo plugin writes raw PCM data to a FIFO (First In, First Out) file. The data can be read by another program.
|
||||
|
||||
@@ -803,7 +806,7 @@ The fifo plugin writes raw PCM data to a FIFO (First In, First Out) file. The da
|
||||
- This specifies the path of the FIFO to write to. Must be an absolute path. If the path does not exist, it will be created when MPD is started, and removed when MPD is stopped. The FIFO will be created with the same user and group as MPD is running as. Default permissions can be modified by using the builtin shell command umask. If a FIFO already exists at the specified path it will be reused, and will not be removed when MPD is stopped. You can use the "mkfifo" command to create this, and then you may modify the permissions to your liking.
|
||||
|
||||
haiku
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
Use the SoundPlayer API on the Haiku operating system.
|
||||
|
||||
@@ -812,7 +815,8 @@ removed soon, unless there is a new maintainer.
|
||||
|
||||
|
||||
jack
|
||||
~~~~
|
||||
----
|
||||
|
||||
The jack plugin connects to a `JACK server <http://jackaudio.org/>`_.
|
||||
|
||||
.. list-table::
|
||||
@@ -835,7 +839,8 @@ The jack plugin connects to a `JACK server <http://jackaudio.org/>`_.
|
||||
- Sets the size of the ring buffer for each channel. Do not configure this value unless you know what you're doing.
|
||||
|
||||
httpd
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
The httpd plugin creates a HTTP server, similar to `ShoutCast <http://www.shoutcast.com/>`_ / `IceCast <http://icecast.org/>`_. HTTP streaming clients like mplayer, VLC, and mpv can connect to it.
|
||||
|
||||
It is highly recommended to configure a fixed format, because a stream cannot switch its audio format on-the-fly when the song changes.
|
||||
@@ -856,7 +861,8 @@ It is highly recommended to configure a fixed format, because a stream cannot sw
|
||||
- Sets a limit, number of concurrent clients. When set to 0 no limit will apply.
|
||||
|
||||
null
|
||||
~~~~
|
||||
----
|
||||
|
||||
The null plugin does nothing. It discards everything sent to it.
|
||||
|
||||
.. list-table::
|
||||
@@ -871,7 +877,8 @@ The null plugin does nothing. It discards everything sent to it.
|
||||
.. _oss_plugin:
|
||||
|
||||
oss
|
||||
~~~
|
||||
---
|
||||
|
||||
The "Open Sound System" plugin is supported on most Unix platforms.
|
||||
|
||||
On Linux, OSS has been superseded by ALSA. Use the ALSA output plugin :ref:`alsa_plugin` instead of this one on Linux.
|
||||
@@ -899,7 +906,7 @@ The according hardware mixer plugin understands the following settings:
|
||||
- Choose a mixer control, defaulting to PCM.
|
||||
|
||||
openal
|
||||
~~~~~~
|
||||
------
|
||||
The "OpenAL" plugin uses `libopenal <http://kcat.strangesoft.net/openal.html>`_. It is supported on many platforms. Use only if there is no native plugin for your operating system.
|
||||
|
||||
.. list-table::
|
||||
@@ -912,7 +919,7 @@ The "OpenAL" plugin uses `libopenal <http://kcat.strangesoft.net/openal.html>`_.
|
||||
- Sets the device which should be used. This can be any valid OpenAL device name. If not specified, then libopenal will choose a default device.
|
||||
|
||||
osx
|
||||
~~~
|
||||
---
|
||||
The "Mac OS X" plugin uses Apple's CoreAudio API.
|
||||
|
||||
.. list-table::
|
||||
@@ -933,7 +940,7 @@ The "Mac OS X" plugin uses Apple's CoreAudio API.
|
||||
The channel map may not refer to outputs that do not exist according to the format. If the format is "*:*:1" (mono) and you have a four-channel sound card then "-1,-1,0,0" (dual mono output on the second pair of sound card outputs) is a valid channel map but "-1,-1,0,1" is not because the second channel ('1') does not exist when the output is mono.
|
||||
|
||||
pipe
|
||||
~~~~
|
||||
----
|
||||
|
||||
The pipe plugin starts a program and writes raw PCM data into its standard input.
|
||||
|
||||
@@ -949,7 +956,7 @@ The pipe plugin starts a program and writes raw PCM data into its standard input
|
||||
.. _pulse_plugin:
|
||||
|
||||
pulse
|
||||
~~~~~
|
||||
-----
|
||||
The pulse plugin connects to a `PulseAudio <http://www.freedesktop.org/wiki/Software/PulseAudio/>`_ server. Requires libpulse.
|
||||
|
||||
.. list-table::
|
||||
@@ -966,7 +973,7 @@ The pulse plugin connects to a `PulseAudio <http://www.freedesktop.org/wiki/Soft
|
||||
- Specifies a linear scaling coefficient (ranging from 0.5 to 5.0) to apply when adjusting volume through :program:`MPD`. For example, chosing a factor equal to ``"0.7"`` means that setting the volume to 100 in :program:`MPD` will set the PulseAudio volume to 70%, and a factor equal to ``"3.5"`` means that volume 100 in :program:`MPD` corresponds to a 350% PulseAudio volume.
|
||||
|
||||
recorder
|
||||
~~~~~~~~
|
||||
--------
|
||||
The recorder plugin writes the audio played by :program:`MPD` to a file. This may be useful for recording radio streams.
|
||||
|
||||
.. list-table::
|
||||
@@ -978,13 +985,13 @@ The recorder plugin writes the audio played by :program:`MPD` to a file. This ma
|
||||
* - **path P**
|
||||
- Write to this file.
|
||||
* - **format_path P**
|
||||
- An alternative to path which provides a format string referring to tag values. The special tag iso8601 emits the current date and time in `ISO8601 <https://en.wikipedia.org/wiki/ISO_8601>`_ format (UTC). Every time a new song starts or a new tag gets received from a radio station, a new file is opened. If the format does not render a file name, nothing is recorded. A tag name enclosed in percent signs ('%') is replaced with the tag value. Example: :file:`~/.mpd/recorder/%artist% - %title%.ogg`. Square brackets can be used to group a substring. If none of the tags referred in the group can be found, the whole group is omitted. Example: [~/.mpd/recorder/[%artist% - ]%title%.ogg] (this omits the dash when no artist tag exists; if title also doesn't exist, no file is written). The operators "|" (logical "or") and "&" (logical "and") can be used to select portions of the format string depending on the existing tag values. Example: ~/.mpd/recorder/[%title%|%name%].ogg (use the "name" tag if no title exists)
|
||||
- An alternative to path which provides a format string referring to tag values. The special tag iso8601 emits the current date and time in `ISO8601 <https://en.wikipedia.org/wiki/ISO_8601>`_ format (UTC). Every time a new song starts or a new tag gets received from a radio station, a new file is opened. If the format does not render a file name, nothing is recorded. A tag name enclosed in percent signs ('%') is replaced with the tag value. Example: :file:`-/.mpd/recorder/%artist% - %title%.ogg`. Square brackets can be used to group a substring. If none of the tags referred in the group can be found, the whole group is omitted. Example: [-/.mpd/recorder/[%artist% - ]%title%.ogg] (this omits the dash when no artist tag exists; if title also doesn't exist, no file is written). The operators "|" (logical "or") and "&" (logical "and") can be used to select portions of the format string depending on the existing tag values. Example: -/.mpd/recorder/[%title%|%name%].ogg (use the "name" tag if no title exists)
|
||||
* - **encoder NAME**
|
||||
- Chooses an encoder plugin. A list of encoder plugins can be found in the encoder plugin reference :ref:`encoder_plugins`.
|
||||
|
||||
|
||||
shout
|
||||
~~~~~
|
||||
-----
|
||||
The shout plugin connects to a ShoutCast or IceCast server using libshout. It forwards tags to this server.
|
||||
|
||||
You must set a format.
|
||||
@@ -1028,7 +1035,7 @@ You must set a format.
|
||||
.. _sles_output:
|
||||
|
||||
sles
|
||||
~~~~
|
||||
----
|
||||
|
||||
Plugin using the `OpenSL ES <https://www.khronos.org/opensles/>`__
|
||||
audio API. Its primary use is local playback on Android, where
|
||||
@@ -1036,7 +1043,7 @@ audio API. Its primary use is local playback on Android, where
|
||||
|
||||
|
||||
solaris
|
||||
~~~~~~~
|
||||
-------
|
||||
The "Solaris" plugin runs only on SUN Solaris, and plays via /dev/audio.
|
||||
|
||||
.. list-table::
|
||||
@@ -1052,22 +1059,22 @@ The "Solaris" plugin runs only on SUN Solaris, and plays via /dev/audio.
|
||||
.. _filter_plugins:
|
||||
|
||||
Filter plugins
|
||||
--------------
|
||||
==============
|
||||
|
||||
normalize
|
||||
~~~~~~~~~
|
||||
---------
|
||||
|
||||
Normalize the volume during playback (at the expensve of quality).
|
||||
|
||||
|
||||
null
|
||||
~~~~
|
||||
----
|
||||
|
||||
A no-op filter. Audio data is returned as-is.
|
||||
|
||||
|
||||
route
|
||||
~~~~~
|
||||
-----
|
||||
|
||||
Reroute channels.
|
||||
|
||||
@@ -1084,43 +1091,44 @@ Reroute channels.
|
||||
.. _playlist_plugins:
|
||||
|
||||
Playlist plugins
|
||||
----------------
|
||||
================
|
||||
|
||||
asx
|
||||
~~~
|
||||
---
|
||||
|
||||
Reads .asx playlist files.
|
||||
|
||||
cue
|
||||
~~~
|
||||
---
|
||||
Reads .cue files.
|
||||
|
||||
embcue
|
||||
~~~~~~
|
||||
------
|
||||
Reads CUE sheets from the "CUESHEET" tag of song files.
|
||||
|
||||
m3u
|
||||
~~~
|
||||
---
|
||||
Reads .m3u playlist files.
|
||||
|
||||
extm3u
|
||||
~~~~~~
|
||||
------
|
||||
Reads extended .m3u playlist files.
|
||||
|
||||
flac
|
||||
~~~~
|
||||
----
|
||||
Reads the cuesheet metablock from a FLAC file.
|
||||
|
||||
pls
|
||||
~~~
|
||||
---
|
||||
Reads .pls playlist files.
|
||||
|
||||
rss
|
||||
~~~
|
||||
---
|
||||
Reads music links from .rss files.
|
||||
|
||||
soundcloud
|
||||
~~~~~~~~~~
|
||||
----------
|
||||
|
||||
Download playlist from SoundCloud. It accepts URIs starting with soundcloud://.
|
||||
|
||||
.. list-table::
|
||||
@@ -1133,5 +1141,5 @@ Download playlist from SoundCloud. It accepts URIs starting with soundcloud://.
|
||||
- An API key to access the SoundCloud servers.
|
||||
|
||||
xspf
|
||||
~~~~
|
||||
----
|
||||
Reads XSPF playlist files.
|
||||
|
@@ -14,6 +14,9 @@ Once the client is connected to the server, they conduct a
|
||||
conversation until the client closes the connection. The
|
||||
conversation flow is always initiated by the client.
|
||||
|
||||
All data between the client and the server is encoded in
|
||||
UTF-8.
|
||||
|
||||
The client transmits a command sequence, terminated by the
|
||||
newline character ``\n``. The server will
|
||||
respond with one or more lines, the last of which will be a
|
||||
@@ -42,9 +45,6 @@ quotation marks.
|
||||
Argument strings are separated from the command and any other
|
||||
arguments by linear white-space (' ' or '\\t').
|
||||
|
||||
All data between the client and the server is encoded in
|
||||
UTF-8.
|
||||
|
||||
Responses
|
||||
=========
|
||||
|
||||
@@ -52,6 +52,28 @@ A command returns ``OK`` on completion or
|
||||
``ACK some error`` on failure. These
|
||||
denote the end of command execution.
|
||||
|
||||
Some commands return more data before the response ends with ``OK``.
|
||||
Each line is usually in the form ``NAME: VALUE``. Example::
|
||||
|
||||
foo: bar
|
||||
OK
|
||||
|
||||
.. _binary:
|
||||
|
||||
Binary Responses
|
||||
----------------
|
||||
|
||||
Some commands can return binary data. This is initiated by a line
|
||||
containing ``binary: 1234`` (followed as usual by a newline). After
|
||||
that, the specified number of bytes of binary data follows, then a
|
||||
newline, and finally the ``OK`` line. Example::
|
||||
|
||||
foo: bar
|
||||
binary: 42
|
||||
<42 bytes>
|
||||
OK
|
||||
|
||||
|
||||
Failure responses
|
||||
-----------------
|
||||
|
||||
@@ -112,9 +134,9 @@ list begins with `command_list_begin` or
|
||||
`command_list_ok_begin` and ends with
|
||||
`command_list_end`.
|
||||
|
||||
It does not execute any commands until the list has ended.
|
||||
The return value is whatever the return for a list of commands
|
||||
is. On success for all commands,
|
||||
It does not execute any commands until the list has ended. The
|
||||
response is a concatentation of all individual responses.
|
||||
On success for all commands,
|
||||
``OK`` is returned. If a command
|
||||
fails, no more commands are executed and the appropriate
|
||||
``ACK`` error is returned. If
|
||||
@@ -178,8 +200,9 @@ of:
|
||||
file's time stamp with the given value (ISO 8601 or UNIX
|
||||
time stamp).
|
||||
|
||||
- ``(AudioFormat == 'SAMPLERATE:BITS:CHANNELS')``:
|
||||
compares the audio format with the given value.
|
||||
- ``(AudioFormat == 'SAMPLERATE:BITS:CHANNELS')``: compares the audio
|
||||
format with the given value. See :ref:`audio_output_format` for a
|
||||
detailed explanation.
|
||||
|
||||
- ``(AudioFormat =~ 'SAMPLERATE:BITS:CHANNELS')``:
|
||||
matches the audio format with the given mask (i.e. one
|
||||
@@ -423,7 +446,9 @@ Querying :program:`MPD`'s status
|
||||
- ``xfade``: ``crossfade`` in seconds
|
||||
- ``mixrampdb``: ``mixramp`` threshold in dB
|
||||
- ``mixrampdelay``: ``mixrampdelay`` in seconds
|
||||
- ``audio``: The format emitted by the decoder plugin during playback, format: ``*samplerate:bits:channels*``. Check the user manual for a detailed explanation.
|
||||
- ``audio``: The format emitted by the decoder plugin during
|
||||
playback, format: ``samplerate:bits:channels``. See
|
||||
:ref:`audio_output_format` for a detailed explanation.
|
||||
- ``updating_db``: ``job id``
|
||||
- ``error``: if there is an error, returns message here
|
||||
|
||||
@@ -791,7 +816,7 @@ The music database
|
||||
|
||||
Returns the file size and actual number
|
||||
of bytes read at the requested offset, followed
|
||||
by the chunk requested as raw bytes, then a
|
||||
by the chunk requested as raw bytes (see :ref:`binary`), then a
|
||||
newline and the completion code.
|
||||
|
||||
Example::
|
||||
@@ -799,8 +824,7 @@ The music database
|
||||
albumart
|
||||
size: 1024768
|
||||
binary: 8192
|
||||
<8192 bytes>
|
||||
OK
|
||||
<8192 bytes>OK
|
||||
|
||||
:command:`count {FILTER} [group {GROUPTYPE}]`
|
||||
Count the number of songs and their total playtime in
|
||||
|
86
doc/user.rst
86
doc/user.rst
@@ -402,14 +402,9 @@ The following table lists the audio_output options valid for all plugins:
|
||||
- The name of the plugin
|
||||
* - **name**
|
||||
- The name of the audio output. It is visible to the client. Some plugins also use it internally, e.g. as a name registered in the PULSE server.
|
||||
* - **format**
|
||||
- Always open the audio output with the specified audio format samplerate:bits:channels), regardless of the format of the input file. This is optional for most plugins.
|
||||
|
||||
Any of the three attributes may be an asterisk to specify that this attribute should not be enforced, example: 48000:16:*. *:*:* is equal to not having a format specification.
|
||||
|
||||
The following values are valid for bits: 8 (signed 8 bit integer samples), 16, 24 (signed 24 bit integer samples padded to 32 bit), 32 (signed 32 bit integer samples), f (32 bit floating point, -1.0 to 1.0), "dsd" means DSD (Direct Stream Digital). For DSD, there are special cases such as "dsd64", which allows you to omit the sample rate (e.g. dsd512:2 for stereo DSD512, i.e. 22.5792 MHz).
|
||||
|
||||
The sample rate is special for DSD: :program:`MPD` counts the number of bytes, not bits. Thus, a DSD "bit" rate of 22.5792 MHz (DSD512) is 2822400 from :program:`MPD`'s point of view (44100*512/8).
|
||||
* - **format samplerate:bits:channels**
|
||||
- Always open the audio output with the specified audio format, regardless of the format of the input file. This is optional for most plugins.
|
||||
See :ref:`audio_output_format` for a detailed description of the value.
|
||||
* - **enabed yes|no**
|
||||
- Specifies whether this audio output is enabled when :program:`MPD` is started. By default, all audio outputs are enabled. This is just the default setting when there is no state file; with a state file, the previous state is restored.
|
||||
* - **tags yes|no**
|
||||
@@ -504,13 +499,34 @@ reference.
|
||||
Audio Format Settings
|
||||
---------------------
|
||||
|
||||
Global Audio Format
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
.. _audio_output_format:
|
||||
|
||||
The setting audio_output_format forces :program:`MPD` to use one audio format for all outputs. Doing that is usually not a good idea. The values are the same as in format in the audio_output section.
|
||||
Global Audio Format
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The setting ``audio_output_format`` forces :program:`MPD` to use one
|
||||
audio format for all outputs. Doing that is usually not a good idea.
|
||||
|
||||
The value is specified as ``samplerate:bits:channels``.
|
||||
|
||||
Any of the three attributes may be an asterisk to specify that this
|
||||
attribute should not be enforced, example: ``48000:16:*``.
|
||||
``*:*:*`` is equal to not having a format specification.
|
||||
|
||||
The following values are valid for bits: ``8`` (signed 8 bit integer
|
||||
samples), ``16``, ``24`` (signed 24 bit integer samples padded to 32
|
||||
bit), ``32`` (signed 32 bit integer samples), ``f`` (32 bit floating
|
||||
point, -1.0 to 1.0), ``dsd`` means DSD (Direct Stream Digital). For
|
||||
DSD, there are special cases such as ``dsd64``, which allows you to
|
||||
omit the sample rate (e.g. ``dsd512:2`` for stereo DSD512,
|
||||
i.e. 22.5792 MHz).
|
||||
|
||||
The sample rate is special for DSD: :program:`MPD` counts the number
|
||||
of bytes, not bits. Thus, a DSD "bit" rate of 22.5792 MHz (DSD512) is
|
||||
2822400 from :program:`MPD`'s point of view (44100*512/8).
|
||||
|
||||
Resampler
|
||||
~~~~~~~~~
|
||||
^^^^^^^^^
|
||||
|
||||
Sometimes, music needs to be resampled before it can be played; for example, CDs use a sample rate of 44,100 Hz while many cheap audio chips can only handle 48,000 Hz. Resampling reduces the quality and consumes a lot of CPU. There are different options, some of them optimized for high quality and others for low CPU usage, but you can't have both at the same time. Often, the resampler is the component that is responsible for most of :program:`MPD`'s CPU usage. Since :program:`MPD` comes with high quality defaults, it may appear that :program:`MPD` consumes more CPU than other software.
|
||||
|
||||
@@ -523,7 +539,7 @@ Client Connections
|
||||
.. _listeners:
|
||||
|
||||
Listeners
|
||||
~~~~~~~~~
|
||||
^^^^^^^^^
|
||||
|
||||
The setting :code:`bind_to_address` specifies which addresses
|
||||
:program:`MPD` listens on for connections from clients. It can be
|
||||
@@ -566,7 +582,7 @@ used.
|
||||
|
||||
|
||||
Permissions and Passwords
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
By default, all clients are unauthenticated and have a full set of permissions. This can be restricted with the settings :code:`default_permissions` and :code:`password`.
|
||||
|
||||
@@ -629,7 +645,7 @@ Other Settings
|
||||
Section :ref:`tags` contains a list of supported tags.
|
||||
|
||||
The State File
|
||||
~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The state file is a file where :program:`MPD` saves and restores its state (play queue, playback position etc.) to keep it persistent across restarts and reboots. It is an optional setting.
|
||||
|
||||
@@ -647,7 +663,7 @@ The State File
|
||||
- Auto-save the state file this number of seconds after each state change. Defaults to 120 (2 minutes).
|
||||
|
||||
The Sticker Database
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
"Stickers" are pieces of information attached to songs. Some clients
|
||||
use them to store ratings and other volatile data. This feature
|
||||
@@ -664,7 +680,7 @@ requires :program:`SQLite`, compile-time configure option
|
||||
- The location of the sticker database.
|
||||
|
||||
Resource Limitations
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These settings are various limitations to prevent :program:`MPD` from using too many resources (denial of service).
|
||||
|
||||
@@ -686,7 +702,7 @@ These settings are various limitations to prevent :program:`MPD` from using too
|
||||
- The maximum size of the output buffer to a client (maximum response size). Default is 8192 (8 MiB).
|
||||
|
||||
Buffer Settings
|
||||
~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Do not change these unless you know what you are doing.
|
||||
|
||||
@@ -700,7 +716,7 @@ Do not change these unless you know what you are doing.
|
||||
- Adjust the size of the internal audio buffer. Default is 4096 (4 MiB).
|
||||
|
||||
Zeroconf
|
||||
~~~~~~~~
|
||||
^^^^^^^^
|
||||
|
||||
If Zeroconf support (`Avahi <http://avahi.org/>`_ or Apple's Bonjour)
|
||||
was enabled at compile time with :code:`-Dzeroconf=...`,
|
||||
@@ -786,10 +802,12 @@ You can verify whether the real-time scheduler is active with the ps command:
|
||||
|
||||
The CLS column shows the CPU scheduler; TS is the normal scheduler; FF and RR are real-time schedulers. In this example, two threads use the real-time scheduler: the output thread and the rtio (real-time I/O) thread; these two are the important ones. The database update thread uses the idle scheduler ("IDL in ps), which only gets CPU when no other process needs it.
|
||||
|
||||
Note
|
||||
~~~~
|
||||
.. note::
|
||||
|
||||
There is a rumor that real-time scheduling improves audio quality. That is not true. All it does is reduce the probability of skipping (audio buffer xruns) when the computer is under heavy load.
|
||||
There is a rumor that real-time scheduling improves audio
|
||||
quality. That is not true. All it does is reduce the probability of
|
||||
skipping (audio buffer xruns) when the computer is under heavy
|
||||
load.
|
||||
|
||||
Using MPD
|
||||
*********
|
||||
@@ -817,7 +835,7 @@ Depending on the size of your music collection and the speed of the storage, thi
|
||||
To exclude a file from the update, create a file called :file:`.mpdignore` in its parent directory. Each line of that file may contain a list of shell wildcards. Matching files in the current directory and all subdirectories are excluded.
|
||||
|
||||
Mounting other storages into the music directory
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:program:`MPD` has various storage plugins of which multiple instances can be "mounted" into the music directory. This way, you can use local music, file servers and USB sticks at the same time. Example:
|
||||
|
||||
@@ -885,7 +903,7 @@ To verify if :program:`MPD` converts the audio format, enable verbose logging, a
|
||||
.. code-block:: none
|
||||
|
||||
decoder: audio_format=44100:24:2, seekable=true
|
||||
output: opened plugin=alsa name="An ALSA output"audio_format=44100:16:2
|
||||
output: opened plugin=alsa name="An ALSA output" audio_format=44100:16:2
|
||||
output: converting from 44100:24:2
|
||||
|
||||
This example shows that a 24 bit file is being played, but the sound chip cannot play 24 bit. It falls back to 16 bit, discarding 8 bit.
|
||||
@@ -912,7 +930,7 @@ Check list for bit-perfect playback:
|
||||
device (:samp:`hw:0,0` or similar).
|
||||
* Don't use software volume (setting :code:`mixer_type`).
|
||||
* Don't force :program:`MPD` to use a specific audio format (settings
|
||||
:code:`format`, :code:`audio_output_format`).
|
||||
:code:`format`, :ref:`audio_output_format <audio_output_format>`).
|
||||
* Verify that you are really doing bit-perfect playback using :program:`MPD`'s verbose log and :file:`/proc/asound/card*/pcm*p/sub*/hw_params`. Some DACs can also indicate the audio format.
|
||||
|
||||
Direct Stream Digital (DSD)
|
||||
@@ -963,18 +981,18 @@ Support
|
||||
-------
|
||||
|
||||
Getting Help
|
||||
~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The :program:`MPD` project runs a `forum <https://forum.musicpd.org/>`_ and an IRC channel (#mpd on Freenode) for requesting help. Visit the MPD help page for details on how to get help.
|
||||
|
||||
Common Problems
|
||||
~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
1. Database
|
||||
^^^^^^^^^^^
|
||||
"""""""""""
|
||||
|
||||
Question: I can't see my music in the MPD database!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Check your :code:`music_directory` setting.
|
||||
* Does the MPD user have read permission on all music files, and read+execute permission on all music directories (and all of their parent directories)?
|
||||
@@ -982,22 +1000,22 @@ Question: I can't see my music in the MPD database!
|
||||
* Did you enable all relevant decoder plugins at compile time? :command:`mpd --version` will tell you.
|
||||
|
||||
Question: MPD doesn't read ID3 tags!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* You probably compiled :program:`MPD` without libid3tag. :command:`mpd --version` will tell you.
|
||||
|
||||
2. Playback
|
||||
^^^^^^^^^^^
|
||||
"""""""""""
|
||||
|
||||
Question: I can't hear music on my client!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* That problem usually follows a misunderstanding of the nature of :program:`MPD`. :program:`MPD` is a remote-controlled music player, not a music distribution system. Usually, the speakers are connected to the box where :program:`MPD` runs, and the :program:`MPD` client only sends control commands, but the client does not actually play your music.
|
||||
|
||||
:program:`MPD` has output plugins which allow hearing music on a remote host (such as httpd), but that is not :program:`MPD`'s primary design goal.
|
||||
|
||||
Question: "Device or resource busy"
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* This ALSA error means that another program uses your sound hardware exclusively. You can stop that program to allow :program:`MPD` to use it.
|
||||
|
||||
@@ -1016,7 +1034,7 @@ Your bug report should contain:
|
||||
* be clear about what you expect MPD to do, and what is actually happening
|
||||
|
||||
MPD crashes
|
||||
~~~~~~~~~~~
|
||||
^^^^^^^^^^^
|
||||
|
||||
All :program:`MPD` crashes are bugs which must be fixed by a developer, and you should write a bug report. (Many crash bugs are caused by codec libraries used by :program:`MPD`, and then that library must be fixed; but in any case, the :program:`MPD` `bug tracker <https://github.com/MusicPlayerDaemon/MPD/issues>`_ is a good place to report it first if you don't know.)
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
project(
|
||||
'mpd',
|
||||
['c', 'cpp'],
|
||||
version: '0.21.8',
|
||||
version: '0.21.10',
|
||||
meson_version: '>= 0.49.0',
|
||||
default_options: [
|
||||
'c_std=c99',
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2018 The Music Player Daemon Project
|
||||
* Copyright 2003-2019 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef MPD_OPUS_READER_HXX
|
||||
#define MPD_OPUS_READER_HXX
|
||||
|
||||
#include "util/StringView.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -81,18 +83,16 @@ public:
|
||||
return ReadWord(length) && Skip(length);
|
||||
}
|
||||
|
||||
char *ReadString() {
|
||||
StringView ReadString() {
|
||||
uint32_t length;
|
||||
if (!ReadWord(length) || length >= 65536)
|
||||
if (!ReadWord(length))
|
||||
return nullptr;
|
||||
|
||||
const char *src = (const char *)Read(length);
|
||||
if (src == nullptr)
|
||||
return nullptr;
|
||||
|
||||
char *dest = new char[length + 1];
|
||||
*std::copy_n(src, length, dest) = 0;
|
||||
return dest;
|
||||
return {src, length};
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -24,6 +24,8 @@
|
||||
#include "tag/ParseName.hxx"
|
||||
#include "ReplayGainInfo.hxx"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -91,18 +93,25 @@ ScanOpusTags(const void *data, size_t size,
|
||||
return false;
|
||||
|
||||
while (n-- > 0) {
|
||||
char *p = r.ReadString();
|
||||
if (p == nullptr)
|
||||
const auto s = r.ReadString();
|
||||
if (s == nullptr)
|
||||
return false;
|
||||
|
||||
char *eq = strchr(p, '=');
|
||||
if (eq != nullptr && eq > p) {
|
||||
*eq = 0;
|
||||
if (s.size >= 4096)
|
||||
continue;
|
||||
|
||||
ScanOneOpusTag(p, eq + 1, rgi, handler);
|
||||
}
|
||||
const auto eq = s.Find('=');
|
||||
if (eq == nullptr || eq == s.data)
|
||||
continue;
|
||||
|
||||
delete[] p;
|
||||
auto name = s, value = s;
|
||||
name.SetEnd(eq);
|
||||
value.MoveFront(eq + 1);
|
||||
|
||||
const std::string name2(name.data, name.size);
|
||||
const std::string value2(value.data, value.size);
|
||||
|
||||
ScanOneOpusTag(name2.c_str(), value2.c_str(), rgi, handler);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -59,6 +59,9 @@ BufferedInputStream::~BufferedInputStream() noexcept
|
||||
void
|
||||
BufferedInputStream::Check()
|
||||
{
|
||||
if (read_error)
|
||||
std::rethrow_exception(read_error);
|
||||
|
||||
if (input)
|
||||
input->Check();
|
||||
}
|
||||
@@ -101,7 +104,7 @@ BufferedInputStream::IsEOF() noexcept
|
||||
bool
|
||||
BufferedInputStream::IsAvailable() noexcept
|
||||
{
|
||||
return IsEOF() || buffer.Read(offset).HasData();
|
||||
return IsEOF() || buffer.Read(offset).HasData() || read_error;
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -164,6 +167,32 @@ BufferedInputStream::RunThread() noexcept
|
||||
idle = false;
|
||||
seek = false;
|
||||
client_cond.signal();
|
||||
} else if (!idle && !read_error &&
|
||||
offset != input->GetOffset() &&
|
||||
!IsAvailable()) {
|
||||
/* a past Seek() call was a no-op because data
|
||||
was already available at that position, but
|
||||
now we've reached a new position where
|
||||
there is no more data in the buffer, and
|
||||
our input is reading somewhere else (maybe
|
||||
stuck at the end of the file); to find a
|
||||
way out, we now seek our input to our
|
||||
reading position to be able to fill our
|
||||
buffer */
|
||||
|
||||
try {
|
||||
input->Seek(offset);
|
||||
} catch (...) {
|
||||
/* this is really a seek error, but we
|
||||
register it as a read_error,
|
||||
because seek_error is only checked
|
||||
by Seek(), and at our frontend (our
|
||||
own InputStream interface) is in
|
||||
"read" mode */
|
||||
read_error = std::current_exception();
|
||||
client_cond.signal();
|
||||
InvokeOnAvailable();
|
||||
}
|
||||
} else if (!idle && !read_error &&
|
||||
input->IsAvailable() && !input->IsEOF()) {
|
||||
const auto read_offset = input->GetOffset();
|
||||
|
@@ -71,10 +71,10 @@ HttpdClient::HandleLine(const char *line) noexcept
|
||||
assert(state != State::RESPONSE);
|
||||
|
||||
if (state == State::REQUEST) {
|
||||
if (memcmp(line, "HEAD /", 6) == 0) {
|
||||
if (strncmp(line, "HEAD /", 6) == 0) {
|
||||
line += 6;
|
||||
head_method = true;
|
||||
} else if (memcmp(line, "GET /", 5) == 0) {
|
||||
} else if (strncmp(line, "GET /", 5) == 0) {
|
||||
line += 5;
|
||||
} else {
|
||||
/* only GET is supported */
|
||||
@@ -83,8 +83,19 @@ HttpdClient::HandleLine(const char *line) noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
/* blacklist some well-known request paths */
|
||||
if ((strncmp(line, "favicon.ico", 11) == 0 &&
|
||||
(line[11] == '\0' || line[11] == ' ')) ||
|
||||
(strncmp(line, "robots.txt", 10) == 0 &&
|
||||
(line[10] == '\0' || line[10] == ' ')) ||
|
||||
(strncmp(line, "sitemap.xml", 11) == 0 &&
|
||||
(line[11] == '\0' || line[11] == ' ')) ||
|
||||
(strncmp(line, ".well-known/", 12) == 0)) {
|
||||
should_reject = true;
|
||||
}
|
||||
|
||||
line = strchr(line, ' ');
|
||||
if (line == nullptr || memcmp(line + 1, "HTTP/", 5) != 0) {
|
||||
if (line == nullptr || strncmp(line + 1, "HTTP/", 5) != 0) {
|
||||
/* HTTP/0.9 without request headers */
|
||||
|
||||
if (head_method)
|
||||
@@ -129,14 +140,21 @@ HttpdClient::SendResponse() noexcept
|
||||
|
||||
assert(state == State::RESPONSE);
|
||||
|
||||
if (metadata_requested) {
|
||||
if (should_reject) {
|
||||
response =
|
||||
"HTTP/1.1 404 not found\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"
|
||||
"404 not found";
|
||||
} else if (metadata_requested) {
|
||||
allocated =
|
||||
icy_server_metadata_header(httpd.name, httpd.genre,
|
||||
httpd.website,
|
||||
httpd.content_type,
|
||||
metaint);
|
||||
response = allocated.c_str();
|
||||
} else { /* revert to a normal HTTP request */
|
||||
} else { /* revert to a normal HTTP request */
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
@@ -415,7 +433,7 @@ HttpdClient::OnSocketInput(void *data, size_t length) noexcept
|
||||
if (!SendResponse())
|
||||
return InputResult::CLOSED;
|
||||
|
||||
if (head_method) {
|
||||
if (head_method || should_reject) {
|
||||
LockClose();
|
||||
return InputResult::CLOSED;
|
||||
}
|
||||
|
@@ -83,6 +83,11 @@ class HttpdClient final
|
||||
*/
|
||||
bool head_method = false;
|
||||
|
||||
/**
|
||||
* Should we reject this request?
|
||||
*/
|
||||
bool should_reject = false;
|
||||
|
||||
/* ICY */
|
||||
|
||||
/**
|
||||
|
@@ -996,7 +996,7 @@ Player::Run() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
if (dc.IsIdle() && queued && dc.pipe == pipe) {
|
||||
if (dc.IsIdle() && queued && IsDecoderAtCurrentSong()) {
|
||||
/* the decoder has finished the current song;
|
||||
make it decode the next song */
|
||||
|
||||
@@ -1058,6 +1058,16 @@ Player::Run() noexcept
|
||||
|
||||
SongBorder();
|
||||
} else if (dc.IsIdle()) {
|
||||
if (queued)
|
||||
/* the decoder has just stopped,
|
||||
between the two IsIdle() checks,
|
||||
probably while UnlockCheckOutputs()
|
||||
left the mutex unlocked; to restart
|
||||
the decoder instead of stopping
|
||||
playback completely, let's re-enter
|
||||
this loop */
|
||||
continue;
|
||||
|
||||
/* check the size of the pipe again, because
|
||||
the decoder thread may have added something
|
||||
since we last checked */
|
||||
|
Reference in New Issue
Block a user