aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--COPYING27
-rw-r--r--INSTALL32
-rw-r--r--Makefile.am4
-rw-r--r--NEWS75
-rw-r--r--README17
-rw-r--r--configure.ac79
-rw-r--r--doc/mpd.conf.518
-rw-r--r--doc/mpdconf.example403
-rw-r--r--doc/protocol.xml4
-rwxr-xr-xscripts/test.sh87
-rw-r--r--src/Makefile.am5
-rw-r--r--src/client.c13
-rw-r--r--src/command.c15
-rw-r--r--src/conf.c2
-rw-r--r--src/conf.h2
-rw-r--r--src/decoder/ffmpeg_plugin.c59
-rw-r--r--src/decoder/mp3_plugin.c8
-rw-r--r--src/decoder_api.c7
-rw-r--r--src/listen.c3
-rw-r--r--src/locate.c2
-rw-r--r--src/log.c6
-rw-r--r--src/ls.c61
-rw-r--r--src/ls.h12
-rw-r--r--src/mapper.c12
-rw-r--r--src/mapper.h8
-rw-r--r--src/output/ao_plugin.c6
-rw-r--r--src/output/osx_plugin.c49
-rw-r--r--src/output/shout_plugin.c6
-rw-r--r--src/output_thread.c10
-rw-r--r--src/pcm_utils.c6
-rw-r--r--src/player_control.c25
-rw-r--r--src/player_control.h8
-rw-r--r--src/playlist.c12
-rw-r--r--src/playlist_save.c4
-rw-r--r--src/stored_playlist.c6
-rw-r--r--src/stored_playlist.h1
-rw-r--r--src/update.c2
38 files changed, 676 insertions, 422 deletions
diff --git a/AUTHORS b/AUTHORS
index dbc4a1623..6943b8bbd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,7 +7,7 @@ Avuton Olrich <avuton@gmail.com>
Max Kellermann <max@duempel.org>
general
-José Anarch <anarchsss@gmail.com>
+José Anarch <anarchsss@gmail.com>
JACK plugin
Guus Sliepen <guus@sliepen.eu.org>
diff --git a/COPYING b/COPYING
index d60c31a97..d511905c1 100644
--- a/COPYING
+++ b/COPYING
@@ -1,8 +1,8 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
+the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
-
+
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
-
+
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
-
+
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
-
+
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-
+
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
+library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
diff --git a/INSTALL b/INSTALL
index b1a24fd06..cb58a5cd0 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,12 @@
Music Player Daemon (MPD) - INSTALL
+Introduction
+------------
+This document is a very small amount of documentation about what is needed to
+install MPD. If more information is desired see the community wiki at
+http://mpd.wikia.com.
+
Dependencies
------------
@@ -28,6 +34,18 @@ ALSA - http://www.alsa-project.org/
The Advanced Linux Sound Architecture. Recommended audio output if you use
Linux. You will need libasound.
+FIFO
+This is a mostly undocumented, developer plugin to transmit raw data.
+
+MVP - http://en.wikipedia.org/wiki/Hauppauge_MediaMVP
+A network media player.
+
+OSS - http://www.opensound.com
+Open Sound System.
+
+OSX - http://www.apple.com
+Necessary if you are on Mac OSX.
+
PulseAudio - http://www.pulseaudio.org/
An advanced sound daemon. You will need libpulse.
@@ -144,16 +162,14 @@ Run
$ mpd <config file>
-(if no config file is specified, mpd's looks for ~/.mpdconf then /etc/mpd.conf)
-
-an example would be:
-
-$ mpd playlists/.mpdconf
+First default is ~/.mpdconf then /etc/mpd.conf. If neither of these exist
+a mpd configuration file must be specified at runtime. A
-A sample config file is included with the source of MPD, mpdconf.example .
+A sample config file is included with the source of MPD, mpdconf.example.
-Note: The first time you run mpd, it will "explore" your mp3 directory for
-mp3's.
+The first time MPD is run it will attempt to discover all music in your
+music root, recursively. This can be affected by the symbolic link
+options specified in the example mpd.conf.
Using MPD
---------
diff --git a/Makefile.am b/Makefile.am
index 9c87591f2..ede4f6a0d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,9 @@ AUTOMAKE_OPTIONS = foreign 1.9 dist-bzip2
SUBDIRS = src doc
doc_DATA = AUTHORS COPYING NEWS README TODO UPGRADING
-EXTRA_DIST = $(doc_DATA) m4 autogen.sh scripts .gitignore
+EXTRA_DIST = $(doc_DATA) autogen.sh \
+ $(wildcard scripts/*.sh) scripts/mpd.spec \
+ .gitignore
sparse-check test:
$(MAKE) -C src $@
diff --git a/NEWS b/NEWS
index e65eeebe9..1ddc7a7a3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
-ver 0.14.0 (????/??/??)
+ver 0.15 - (200?/??/??)
+
+ver 0.14 (2008/12/25)
* audio outputs:
- wait 10 seconds before reopening a failed device
- fifo: new plugin
@@ -11,6 +13,7 @@ ver 0.14.0 (????/??/??)
- ffmpeg: new plugin
- wavpack: new plugin
- aac: stream support added
+ - mod: disabled by default due to critical bugs in all libmikmod versions
* commands:
- "addid" takes optional second argument to specify position
- "idle" notifies the client when a notable change occurs
@@ -105,17 +108,21 @@ ver 0.12.0 (2006/9/22)
* Lots of bug fixes, cleaned up code, and performance improvements
ver 0.11.5 (2004/11/1)
-1) New id3v1_encoding config option to configure the id3v1 tag encoding (patch from dottedmag)
+1) New id3v1_encoding config option to configure the id3v1 tag encoding (patch
+from dottedmag)
2) Strip '\r' from m3u playlists (thank you windows)
3) Use random() instead of rand() for playlist randomizing
4) Fix a bug trying skipping some commented lines in m3u playlist files
-5) Fix a bug when fetching metadata from streams that may cause certain weirdnesses
+5) Fix a bug when fetching metadata from streams that may cause certain
+weirdnesses
6) Fix a bug where replaygain preamp was used on files w/o replaygain tags
7) Fix a busy loop when trying to prebuffer a nonexistant or missing stream
-8) Fix a bug in forgetting to remove leading ' ' in content-type for http streams
+8) Fix a bug in forgetting to remove leading ' ' in content-type for http
+streams
9) Check for ice-name in http headers
10) Be sure the strip all '\n' chars in tags
-11) Set $HOME env variable when setuid'ing, this should fix the /root/.mcop errors triggered by arts/libao
+11) Set $HOME env variable when setuid'ing, this should fix the /root/.mcop
+errors triggered by arts/libao
ver 0.11.4 (2004/7/26)
1) Fixed a segfault when decoding mp3's with corrupt id3v2 tags
@@ -125,13 +132,21 @@ ver 0.11.3 (2004/7/21)
1) Add support for http authentication for streams
2) Added replaygain pre-amp support
3) Better error handling for fread() in inputStream_file
-4) Fixed a bug so that when a freeAllInterfaces is called, it sets max_interface_connections to 0. This prevents potential segfaults and other nastiness for forked processes, like the player and update-er (do to interfacePrintWithFD()).
-5) Allow blockingWrite() to handle errors more gracefully (for example, if the disc is full, and thus the write() fails or can't be completed, we just skip this write() and continue, instead of getting stuck in an infinite loop until the write() becomes successful)
+4) Fixed a bug so that when a freeAllInterfaces is called, it sets
+max_interface_connections to 0. This prevents potential segfaults and other
+nastiness for forked processes, like the player and update-er (do to
+interfacePrintWithFD()).
+5) Allow blockingWrite() to handle errors more gracefully (for example, if the
+disc is full, and thus the write() fails or can't be completed, we just skip
+this write() and continue, instead of getting stuck in an infinite loop until
+the write() becomes successful)
6) Updated mpdconf.example from sbh/avuton
-7) If "user" is specified, then convert ~ in paths to the user's home path specified by "user" config paramter (not the actual current user running mpd).
+7) If "user" is specified, then convert ~ in paths to the user's home path
+specified by "user" config paramter (not the actual current user running mpd).
ver 0.11.2 (2004/7/5)
-1) Work around in computing total time for mp3's whose first valid mpeg frame is not layer III
+1) Work around in computing total time for mp3's whose first valid mpeg frame is
+not layer III
2) Fix mp3 and mp4 decoders when seeking past the end of the file
3) Fix replaygain for flac and vorbis
4) Fix memory leaks in flac decoder (from normalperson)
@@ -143,16 +158,19 @@ ver 0.11.1 (2004/6/24)
3) Fix move commands so they don't mess up the song id's
4) Added support for HTTP Proxy
5) Detect and skip recursive links in the music directory
-6) Fix addPathToDB() so updating on a specific path doesn't exist correctly adds the parent directories to the DB
+6) Fix addPathToDB() so updating on a specific path doesn't exist correctly adds
+the parent directories to the DB
ver 0.11.0 (2004/6/18)
1) Support for playing mp3 and Ogg Vorbis streams
2) Non-blocking Update
3) Replaygain support for Ogg Vorbis and FLAC (by Eric Moore aka AliasMrJones)
-4) audio_output_format option that allows for all audio output to be converted to a format compatible with any sound card
+4) audio_output_format option that allows for all audio output to be converted
+to a format compatible with any sound card
5) Own routines for to always support UTF-8 <-> ISO-8859-1 conversion
6) Added "Id" and "Pos" metadata for songs in playlist
-7) Added commands: plchanges, currentsong, playid, seekid, playlistid, moveid, swapid, deleteid
+7) Added commands: plchanges, currentsong, playid, seekid, playlistid, moveid,
+swapid, deleteid
8) UTF-8 validation of all tags
9) Update specific files/directories (for fast, incremental updating)
10) Added ACK error codes
@@ -172,14 +190,17 @@ ver 0.10.4 (2004/5/26)
1) Fix configure problems on OpenBSD with langinfo and iconv
2) Fix an infinte loop when writing to an interface and it has expired
3) Fix a segfault in decoding flac's
-4) Ingore CRC stuff in mp3's since some encoders did not compute the CRC correctly
+4) Ingore CRC stuff in mp3's since some encoders did not compute the CRC
+correctly
5) Fix a segfault in processing faulty mp4 metadata
ver 0.10.3 (2004/4/2)
1) Fix a segfault when a blanck line is sent from a client
2) Fix for loading playlists on platforms where char is unsigned
-3) When pausing, release audio device after we say pause is successful (this makes pause appear to not lag)
-4) When returning errors for unknown types by player, be sure to copy the filename
+3) When pausing, release audio device after we say pause is successful (this
+makes pause appear to not lag)
+4) When returning errors for unknown types by player, be sure to copy the
+filename
5) add --disable-alsa for disabling alsa mixer support
6) Use select() for a portable usleep()
7) For alsa mixer, default to "Master' element, not first element
@@ -193,13 +214,15 @@ ver 0.10.2 (2004/3/25)
6) Fix unnecessary big endian byte swapping
7) If locale is "C" or "POSIX", then use ISO-8859-1 as the fs charset
8) Fix a bug where alsa mixer wasn't detecting volume changes
-9) For alsa and software mixer, show volume to be the same as it was set (even if its not the exact volume)
+9) For alsa and software mixer, show volume to be the same as it was set (even
+if its not the exact volume)
10) Report bitrate for wave files
11) Compute song length of CBR mp3's more accurately
ver 0.10.1 (2004/3/7)
1) Check to see if we need to add "-lm" when linking mpd
-2) Fix issues with skipping bad frames in an mp3 (this way we get the correct samplerate and such)
+2) Fix issues with skipping bad frames in an mp3 (this way we get the correct
+samplerate and such)
3) Fix crossfading bug with ogg's
4) Updated libmad and libid3tag included w/ source to 0.15.1b
@@ -219,17 +242,21 @@ ver 0.10.0 (2004/3/3)
13) Fix a segfault when doing: add ""
14) Fix a segfault with flac vorbis comments simply being "="
15) Fix a segfault/bug in queueNextSong with repeat+random
-16) Fix a bug, where one process may segfault, and cause more processes to spawn w/o killing ones that lost their parent.
+16) Fix a bug, where one process may segfault, and cause more processes to spawn
+w/o killing ones that lost their parent.
17) Fix a bug when the OSS device was unable to fetch the current volume,
-it would close the device (when it maybe previously closed by the exact same code)
+it would close the device (when it maybe previously closed by the exact same
+code)
18) command.c cleanup by mackstann
19) directory.c and command.c cleanup by tw-nym
ver 0.9.4 (2004/1/21)
1) Fix a bug where updated tag info wasn't being detected
-2) Set the default audio write size to 1024 bytes (should decrease cpu load a bit on some machines).
+2) Set the default audio write size to 1024 bytes (should decrease cpu load a
+bit on some machines).
3) Make audio write size configurable via "audio_write_size" config option
-4) Tweak output buffer size for connections by detecting the kernel output buffer size.
+4) Tweak output buffer size for connections by detecting the kernel output
+buffer size.
ver 0.9.3 (2003/10/31)
1) Store total time/length of songs in db and display in *info commands
@@ -245,7 +272,8 @@ ver 0.9.3 (2003/10/31)
ver 0.9.2 (2003/10/6)
1) Fix FreeBSD Compilation Problems
2) Fix bug in move command
-3) Add mixer_control options to configure which mixer control/device mpd controls
+3) Add mixer_control options to configure which mixer control/device mpd
+controls
4) Randomize on play -1
5) Fix a bug in toggling repeat off and at the end of the playlist
@@ -280,7 +308,8 @@ ver 0.8.7 (2003/9/3)
instead of calling fclose() on the fp that was opened with fdopen().
ver 0.8.6 (2003/8/25)
-1) Fix a memory leak when a buffered existed, and a connection was unexpectedly closed, and i wasn't free'ing the buffer apropriatly.
+1) Fix a memory leak when a buffered existed, and a connection was unexpectedly
+closed, and i wasn't free'ing the buffer apropriatly.
ver 0.8.5 (2003/8/17)
1) Fix a bug where an extra end of line is returned when attempting to play a
diff --git a/README b/README
index b6c4740a4..bc3cbc18f 100644
--- a/README
+++ b/README
@@ -1,16 +1,17 @@
- Music Player Daemon (MPD)
- http://www.musicpd.org
+ Music Player Daemon (MPD)
+ http://www.musicpd.org
A daemon for playing music of various formats. Music is played through the
server's audio device. The daemon stores info about all available music,
and this info can be easily searched and retrieved. Player control, info
retrieval, and playlist management can all be managed remotely.
-To install MPD, see INSTALL.
+For basic installation information see the INSTALL file.
+
+MPD is released under the GNU General Public License version 2, which is
+distributed in the COPYING file.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see <http://www.gnu.org/licenses/>.
-MPD is released under the GNU General Public License version 2.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-For the full license, see COPYING.
diff --git a/configure.ac b/configure.ac
index 9edf357fa..c8a2152ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ(2.60)
-AC_INIT(mpd, 0.14~beta1, musicpd-dev-team@lists.sourceforge.net)
+AC_INIT(mpd, 0.15~git, musicpd-dev-team@lists.sourceforge.net)
AC_CONFIG_SRCDIR([src/main.c])
AM_INIT_AUTOMAKE([foreign 1.9 dist-bzip2])
AM_CONFIG_HEADER(config.h)
@@ -94,8 +94,8 @@ AC_ARG_ENABLE(tcp,
[enable_tcp=yes])
AC_ARG_ENABLE(un,
- AS_HELP_STRING([--enable-un],
- [enable support for clients connecting via unix domain sockets (default: disable)]),
+ AS_HELP_STRING([--disable-un],
+ [disable support for clients connecting via unix domain sockets (default: enable)]),
[enable_un=$enableval],
[enable_un=yes])
@@ -121,14 +121,14 @@ AC_ARG_ENABLE(ao,
enable_ao=$enableval,
enable_ao=no)
-AC_ARG_ENABLE(shout_ogg,
- AS_HELP_STRING([--disable-shout_ogg],
+AC_ARG_ENABLE(shout-ogg,
+ AS_HELP_STRING([--disable-shout-ogg],
[disable support for ogg streaming through shout (default: enable)]),
[enable_shout_ogg=$enableval],
[enable_shout_ogg=yes])
-AC_ARG_ENABLE(shout_mp3,
- AS_HELP_STRING([--disable-shout_mp3],
+AC_ARG_ENABLE(shout-mp3,
+ AS_HELP_STRING([--disable-shout-mp3],
[disable support for mp3 streaming through shout (default: enable)]),
[enable_shout_mp3=$enableval],
[enable_shout_mp3=yes])
@@ -266,7 +266,7 @@ AC_ARG_ENABLE(mod,
AS_HELP_STRING([--enable-mod],
[enable MOD support (default: disable)]),
enable_mod=$enableval,
- enable_mod=yes)
+ enable_mod=no)
AC_ARG_ENABLE(mpc,
AS_HELP_STRING([--disable-mpc],
@@ -318,6 +318,9 @@ AC_CHECK_LIB(nsl,gethostbyname,MPD_LIBS="$MPD_LIBS -lnsl",)
AC_CHECK_LIB(m,exp,MPD_LIBS="$MPD_LIBS -lm",)
AC_CHECK_FUNCS(setenv)
+# Check for pkg-config before using it
+PKG_PROG_PKG_CONFIG
+
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.4 gthread-2.0],,
[AC_MSG_ERROR([glib-2.4 is required])])
@@ -381,10 +384,9 @@ fi
AM_CONDITIONAL(HAVE_CURL, test x$enable_curl = xyes)
if test x$enable_shout_ogg = xyes || test x$enable_shout_mp3 = xyes; then
- enable_shout=yes
- PKG_CHECK_MODULES([SHOUT], [shout],
- AC_DEFINE(HAVE_SHOUT, 1, [Define to enable libshout support]),
- enable_shout=no)
+ PKG_CHECK_MODULES([SHOUT], [shout],,
+ [enable_shout_ogg=no; enable_shout_mp3=no;
+ AC_MSG_WARN([disabling shout streaming support because libshout is not available])])
fi
if test x$enable_shout_ogg = xyes; then
@@ -396,10 +398,6 @@ if test x$enable_shout_ogg = xyes; then
AC_MSG_WARN([disabling ogg shout streaming support because tremor does not support vorbis encoding])
enable_shout_ogg=no
fi
- if test x$enable_shout = xno; then
- AC_MSG_WARN([disabling ogg shout streaming support because libshout is not found])
- enable_shout_ogg=no
- fi
if test x$enable_shout_ogg = xyes; then
PKG_CHECK_MODULES(VORBISENC, [vorbisenc],
AC_DEFINE(HAVE_SHOUT_OGG, 1, [Define to enable ogg streaming support]),
@@ -407,20 +405,28 @@ if test x$enable_shout_ogg = xyes; then
fi
fi
+if test x$enable_lame = xyes; then
+ AM_PATH_LAME([MPD_LIBS="$MPD_LIBS $LAME_LIBS" MPD_CFLAGS="$MPD_CFLAGS $LAME_CFLAGS"],
+ [enable_lame=no; AC_MSG_WARN(You need lame -- disabling lame support)])
+fi
+
if test x$enable_shout_mp3 = xyes; then
if test x$enable_lame = xno; then
AC_MSG_WARN([disabling mp3 shout streaming support because lame is not enabled])
enable_shout_mp3=no
fi
- if test x$enable_shout = xno; then
- AC_MSG_WARN([disabling mp3 shout streaming support because libshout is not found])
- enable_shout_mp3=no
- fi
if test x$enable_shout_mp3 = xyes; then
AC_DEFINE(HAVE_SHOUT_MP3, 1, [Define to enable mp3 streaming support])
fi
fi
+if test x$enable_shout_ogg = xyes || test x$enable_shout_mp3 = xyes; then
+ enable_shout=yes
+ AC_DEFINE(HAVE_SHOUT, 1, [Define to enable libshout support])
+else
+ enable_shout=no
+fi
+
AM_CONDITIONAL(HAVE_SHOUT, test x$enable_shout = xyes)
AM_CONDITIONAL(HAVE_SHOUT_OGG, test x$enable_shout_ogg = xyes)
AM_CONDITIONAL(HAVE_SHOUT_MP3, test x$enable_shout_mp3 = xyes)
@@ -508,11 +514,6 @@ fi
AM_CONDITIONAL(HAVE_MAD, test x$enable_mp3 = xyes)
-if test x$enable_lame = xyes; then
- AM_PATH_LAME([MPD_LIBS="$MPD_LIBS $LAME_LIBS" MPD_CFLAGS="$MPD_CFLAGS $LAME_CFLAGS"],
- [enable_lame=no;AC_MSG_WARN(You need lame -- disabling lame support)])
-fi
-
if test x$enable_mpc = xyes; then
if test "x$mpcdec_libraries" != "x" ; then
@@ -951,15 +952,6 @@ then
MPD_CHECK_FLAG([-pedantic])
fi
-
-dnl
-dnl generate files
-dnl
-
-
-AC_OUTPUT(doc/Makefile src/Makefile Makefile)
-
-
dnl
dnl pretty-print result
dnl
@@ -1192,6 +1184,13 @@ else
echo " Zeroconf support ..............disabled"
fi
+
+if test x$enable_curl != xno; then
+ echo " HTTP streaming (libcurl) ......enabled"
+else
+ echo " HTTP streaming (libcurl) ......disabled"
+fi
+
if test x$enable_bz2 = xyes; then
echo " BZ2 archives support ..........enabled"
else
@@ -1213,5 +1212,17 @@ fi
echo ""
echo "##########################################"
echo ""
+
+echo "Generating needed files for compilation"
+echo ""
+
+dnl
+dnl generate files
+dnl
+
+AC_OUTPUT(doc/Makefile src/Makefile Makefile)
+
+echo ""
+
echo "You are now ready to compile MPD"
echo "Type \"make\" to compile MPD"
diff --git a/doc/mpd.conf.5 b/doc/mpd.conf.5
index 4427b9798..b0f69eb58 100644
--- a/doc/mpd.conf.5
+++ b/doc/mpd.conf.5
@@ -38,7 +38,7 @@ This specifies the directory where saved playlists are stored.
.B follow_outside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing outside the music dir.
You must recreate the database after changing this option.
-The default is "no".
+The default is "yes".
.TP
.B follow_inside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing outside the music dir, potentially
@@ -66,12 +66,18 @@ the "kill" command. When mpd is restarted, it will read the state file and
restore the state of mpd (including the playlist).
.TP
.B user <username>
-This specifies the user that mpd will run as, if set.
+This specifies the user that MPD will run as, if set. MPD should
+never run as root, and you may use this option to make MPD change its
+user id after initialization. Do not use this option if you start MPD
+as an unprivileged user.
.TP
.B bind_to_address <ip address or hostname or any>
This specifies which address mpd binds to and listens on. Multiple
bind_to_address parameters may be specified. The default is "any", which binds
to all available addresses.
+
+To bind to a Unix domain socket, specify an absolute path. For a
+system-wide MPD, we suggest the path "\fB/var/run/mpd/socket\fP".
.TP
.B port <port>
This specifies the port that mpd listens on. The default is 6600.
@@ -189,14 +195,6 @@ song. Try increasing this if you hear skipping when manually changing songs.
The default is 10%, a little over 1 second of CD-quality audio with the default
buffer size.
.TP
-.B http_buffer_size <size in KiB>
-This specifies the size of the buffer used for playing HTTP streams. The
-default is 128.
-.TP
-.B http_prebuffer_size <size in KiB>
-This specifies how much of an HTTP stream should be buffered before beginning
-playback. The default is 32.
-.TP
.B http_proxy_host <hostname>
Use to specify the proxy host used for HTTP connections.
.TP
diff --git a/doc/mpdconf.example b/doc/mpdconf.example
index 151c9464f..d2d14098d 100644
--- a/doc/mpdconf.example
+++ b/doc/mpdconf.example
@@ -1,288 +1,331 @@
# An example configuration file for MPD
# See the mpd.conf man page for a more detailed description of each parameter.
-######################## REQUIRED PATHS ########################
-music_directory "~/music"
-playlist_directory "~/.mpd/playlists"
-db_file "~/.mpd/mpd.db"
-log_file "~/.mpd/mpd.log"
-error_file "~/.mpd/mpd.error"
-#follow_outside_symlinks "no"
-#follow_inside_symlinks "yes"
-################################################################
+# Required files and directories ##############################################
+#
+# This setting controls the top directory which MPD will search to discover the
+# available audio files and add them to the daemon's online database.
+#
+music_directory "~/music"
+#
+# This setting sets the MPD internal playlist directory. The purpose of this
+# directory is storage for playlists created by MPD. The server will use
+# playlist files not created by the server but only if they are in the MPD
+# format.
+#
+playlist_directory "~/.mpd/playlists"
+#
+# This setting sets the location of the MPD database. This file is used to
+# load the database at server start up and store the database while the
+# server is not up.
+#
+db_file "~/.mpd/database"
+#
+# These settings are the locations for the daemon log files for the daemon.
+# These logs are great for troubleshooting, depending on your log_level
+# settings.
+#
+log_file "~/.mpd/log"
+error_file "~/.mpd/error-log"
+###############################################################################
-######################## OPTIONAL PATHS ########################
+# Optional files ##############################################################
#
-# If you wish to use mpd --kill to stop MPD, then you must
-# specify a file here in which to store MPD's process ID.
+# This setting sets the location of the file which stores the process ID
+# for use of mpd --kill and some init scripts. This setting is disabled by
+# default.
#
-#pid_file "~/.mpd/mpd.pid"
+#pid_file "~/.mpd/pid"
#
-# If specified, MPD will save its current state (playlist,
-# current song, playing/paused, etc.) at exit. This will be
-# used to restore the session the next time it is run.
+# This setting sets the location of the file which contains information about
+# most variables to get MPD back into the same general shape it was in before
+# it was brought down. This setting is disabled by default.
#
-#state_file "~/.mpd/mpdstate"
+#state_file "~/.mpd/state"
#
-################################################################
+###############################################################################
-######################## DAEMON OPTIONS ########################
+# General music daemon options ################################################
+#
+# This setting specifies the user that MPD will run as, if set. MPD should
+# never run as root and you may use this setting to make MPD change its user
+# id after initialization. Do not use this setting if you start MPD as an
+# unprivileged user. This setting is disabled by default, and the server will
+# run as root.
+#
+#user "nobody"
#
-# If started as root, MPD will drop root privileges and run as
-# this user instead. Otherwise, MPD will run as the user it was
-# started by. If left unspecified, MPD will not drop root
-# privileges at all (not recommended).
+# This setting sets the address for the daemon to listen on. Careful attention
+# should be paid if this is assigned to anything other then the default, any.
+# This setting can deny access to control of the daemon.
#
-#user "nobody"
+# For network
+#bind_to_address "any"
#
-# The address and port to listen on.
+# And for Unix Socket
+#bind_to_address "~/.mpd/socket"
#
-#bind_to_address "any"
-#port "6600"
+# This setting is the port that is desired for the daemon to get assigned to.
#
-# Controls the amount of information that is logged. Can be
-# "default", "secure", or "verbose".
+#port "6600"
#
-#log_level "default"
+# This setting controls the type of information which is logged. Available
+# setting arguments are "default", "secure" or "verbose". The "verbose" setting
+# argument is recommended for troubleshooting, though can quickly stretch
+# available resources on limited hardware storage.
#
-################################################################
+#log_level "default"
+#
+# If you have a problem with your MP3s ending abruptly it is recommended that
+# you set this argument to "no" to attempt to fix the problem. If this solves
+# the problem, it is highly recommended to fix the MP3 files with vbrfix
+# (available from <http://www.willwap.co.uk/Programs/vbrfix.php>), at which
+# point gapless MP3 playback can be enabled.
+#
+#gapless_mp3_playback "yes"
+#
+# This setting enables MPD to create playlists in a format usable by other
+# music players.
+#
+#save_absolute_paths_in_playlists "no"
+#
+# This setting defines a list of tag types that will be extracted during the
+# audio file discovery process. Optionally, 'comment' can be added to this
+# list.
+#
+#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
+#
+###############################################################################
+# Symbolic link behavior ######################################################
+#
+# If this setting is set to "yes", MPD will discover audio files by following
+# symbolic links outside of the configured music_directory.
+#
+#follow_outside_symlinks "yes"
+#
+# If this setting is set to "yes, MPD will discover audio files by following
+# symbolic links inside of the configured music_directory.
+#
+#follow_inside_symlinks "yes"
+#
+###############################################################################
-########################### ZEROCONF ###########################
+# Zeroconf / Avahi Service Discovery ##########################################
#
-# If yes, service information will be published with Zeroconf.
+# If this setting is set to "yes", service information will be published with
+# Zeroconf / Avahi.
#
-#zeroconf_enabled "yes"
+#zeroconf_enabled "yes"
#
-# The service name to publish. This name should be unique on
-# your local network.
+# The argument to this setting will be the Zeroconf / Avahi unique name for
+# this MPD server on the network.
#
-#zeroconf_name "Music Player"
+#zeroconf_name "Music Player"
#
-################################################################
+###############################################################################
-########################## PERMISSIONS #########################
+# Permissions #################################################################
#
-# MPD can require that users specify a password before using it.
-# You may specify one ore more here, along with what users who
-# log in with that password are allowed to do.
+# If this setting is set, MPD will require password authorization. The password
+# can setting can be specified multiple times for different password profiles.
#
#password "password@read,add,control,admin"
#
-# Specifies what permissions a user who has not logged in with a
-# password has. By default, all users have full access to MPD
-# if no password is specified above, or no access if one or
-# more passwords are specified.
+# This setting specifies the permissions a user has who has not yet logged in.
#
#default_permissions "read,add,control,admin"
#
-################################################################
+###############################################################################
-########################## AUDIO OUTPUT ########################
+# Audio Output ################################################################
#
-# MPD supports many audio output types, as well as playing
-# through multiple audio outputs at the same time. You can
-# specify one or more here. If you don't specify any, MPD will
-# automatically scan for a usable audio output.
+# MPD supports various audio output types, as well as playing through multiple
+# audio outputs at the same time, through multiple audio_output settings
+# blocks. Setting this block is optional, though the server will only attempt
+# autodetection for one sound card.
#
-# See <http://mpd.wikia.com/wiki/Configuration#Audio_Outputs>
-# for examples of other audio outputs.
+# See <http://mpd.wikia.com/wiki/Configuration#Audio_Outputs> for examples of
+# other audio outputs.
#
# An example of an ALSA output:
#
#audio_output {
-# type "alsa"
-# name "My ALSA Device"
-# device "hw:0,0" # optional
-# format "44100:16:2" # optional
+# type "alsa"
+# name "My ALSA Device"
+# device "hw:0,0" # optional
+# format "44100:16:2" # optional
#}
#
# An example of an OSS output:
#
#audio_output {
-# type "oss"
-# name "My OSS Device"
-# device "/dev/dsp" # optional
-# format "44100:16:2" # optional
+# type "oss"
+# name "My OSS Device"
+# device "/dev/dsp" # optional
+# format "44100:16:2" # optional
#}
#
# An example of a shout output (for streaming to Icecast):
#
#audio_output {
-# type "shout"
-# encoding "ogg" # optional
-# name "My Shout Stream"
-# host "localhost"
-# port "8000"
-# mount "/mpd.ogg"
-# password "hackme"
-# quality "5.0"
-# bitrate "128"
-# format "44100:16:1"
-# protocol "icecast2" # optional
-# user "source" # optional
-# description "My Stream Description" # optional
-# genre "jazz" # optional
-# public "no" # optional
-# timeout "2" # optional
+# type "shout"
+# encoding "ogg" # optional
+# name "My Shout Stream"
+# host "localhost"
+# port "8000"
+# mount "/mpd.ogg"
+# password "hackme"
+# quality "5.0"
+# bitrate "128"
+# format "44100:16:1"
+# protocol "icecast2" # optional
+# user "source" # optional
+# description "My Stream Description" # optional
+# genre "jazz" # optional
+# public "no" # optional
+# timeout "2" # optional
#}
#
-# An example of a null output (for no audio output):
+# An example of a pulseaudio output (streaming to a remote pulseaudio server)
#
#audio_output {
-# type "null"
-# name "My Null Output"
+# type "pulse"
+# name "My Pulse Output"
+# server "remote_server"
+# sink "remote_server_sink"
#}
#
-# Force all decoded audio to be converted to this format before
-# being passed to the audio outputs.
+## An example of a null output (for no audio output):
#
-#audio_output_format "44100:16:2"
+#audio_output {
+# type "null"
+# name "My Null Output"
+#}
#
-# If MPD has been compiled with libsamplerate support, this
-# specifies the sample rate converter to use. Possible
-# values can be found in the mpd.conf man page or the
-# libsamplerate documentation.
+# This setting will change all decoded audio to be converted to the specified
+# format before being passed to the audio outputs. By default, this setting is
+# disabled.
#
-#samplerate_converter "Fastest Sinc Interpolator"
+#audio_output_format "44100:16:2"
#
-################################################################
+# If MPD has been compiled with libsamplerate support, this setting specifies
+# the sample rate converter to use. Possible values can be found in the
+# mpd.conf man page or the libsamplerate documentation. By default, this is
+# setting is disabled.
+#
+#samplerate_converter "Fastest Sinc Interpolator"
+#
+###############################################################################
-############################# MIXER ############################
+# Volume control mixer ########################################################
#
-# MPD needs to know what mixer settings to change when you
-# adjust the volume. If you don't specify one here, MPD will
-# pick one based on which ones it was compiled with support for.
+# MPD has limited volume controls, to use them pick one below. If one is not
+# specified it may be autodetected at startup, depending on the dependencies
+# which were compiled into the server.
#
# An example for controlling an ALSA mixer:
#
-#mixer_type "alsa"
-#mixer_device "default"
-#mixer_control "PCM"
+#mixer_type "alsa"
+#mixer_device "default"
+#mixer_control "PCM"
#
# An example for controlling an OSS mixer:
#
-#mixer_type "oss"
-#mixer_device "/dev/mixer"
-#mixer_control "PCM"
+#mixer_type "oss"
+#mixer_device "/dev/mixer"
+#mixer_control "PCM"
#
-# If you want MPD to adjust the volume of audio sent to the
-# audio outputs, you can tell it to use the software mixer:
+# This example is a general volume control mixer, it is used to adjust the
+# volume of the audio sent to the audio output, and will work with all outputs.
#
-#mixer_type "software"
+#mixer_type "software"
#
-################################################################
+###############################################################################
-######################### NORMALIZATION ########################
+# Normalization automatic volume adjustments ##################################
#
-# Specifies the type of ReplayGain to use. Can be "album" or
-# "track". ReplayGain will not be used if not specified. See
-# <http://www.replaygain.org> for more details.
+# This setting specifies the type of ReplayGain to use. This setting can have
+# the argument "album" or "track". See <http://www.replaygain.org> for more
+# details. By default this setting is disabled.
#
-#replaygain "album"
+#replaygain "album"
#
-# Sets the pre-amp used for files that have ReplayGain tags.
+# This setting sets the pre-amp used for files that have ReplayGain tags. By
+# default this setting is disabled.
#
-#replaygain_preamp "0"
+#replaygain_preamp "0"
#
-# Enable on the fly volume normalization. This will cause the
-# volume of all songs played to be adjusted so that they sound
-# as though they are of equal loudness.
+# This setting enables on-the-fly normalization volume adjustment. This will
+# result in the volume of all playing audio to be adjusted so the output has
+# equal "loudness".
#
-#volume_normalization "no"
+#volume_normalization "no"
#
-################################################################
+###############################################################################
-########################### BUFFERING ##########################
-#
-# The size of the buffer containing decoded audio. You probably
-# shouldn't change this.
-#
-#audio_buffer_size "2048"
+# MPD Internal Buffering ######################################################
#
-# How much of the buffer to fill before beginning to play.
-# Increase this if you hear skipping when changing songs.
+# This setting adjusts the size of internal decoded audio buffering. Changing
+# this may have undesired effects. Don't change this if you don't know what you
+# are doing.
#
-#buffer_before_play "10%"
+#audio_buffer_size "2048"
#
-# Similar options for the HTTP stream buffer. If you hear
-# skipping while playing HTTP streams, you may wish to increase
-# these.
+# This setting controls the percentage of the buffer which is filled before
+# beginning to play. Increasing this reduces the chance of audio file skipping,
+# at the cost of increased time prior to audio playback.
#
-#http_buffer_size "128"
-#http_prebuffer_size "25%"
+#buffer_before_play "10%"
#
-################################################################
+###############################################################################
-########################### HTTP PROXY #########################
+# HTTP Streaming Proxy ########################################################
#
-# Specifies the HTTP proxy to use for playing HTTP streams.
+# This setting specifies the HTTP proxy to use for playing HTTP streams. By
+# default, these settings will be disabled.
#
-#http_proxy_host "proxy.isp.com"
-#http_proxy_port "8080"
-#http_proxy_user "user"
-#http_proxy_password "password"
+#http_proxy_host "proxy.isp.com"
+#http_proxy_port "8080"
+#http_proxy_user "user"
+#http_proxy_password "password"
#
-################################################################
+###############################################################################
-############################# LIMITS ###########################
+# Resource Limitations ########################################################
#
-# These are various limits to prevent MPD from using too many
-# resources. You should only change them if they start
-# restricting your usage of MPD.
+# These settings are various limitations to prevent MPD from using too many
+# resources. Generally, these settings should be minimized to prevent security
+# risks, depending on the operating resources.
#
-#connection_timeout "60"
-#max_connections "5"
-#max_playlist_length "16384"
-#max_command_list_size "2048"
-#max_output_buffer_size "8192"
+#connection_timeout "60"
+#max_connections "10"
+#max_playlist_length "16384"
+#max_command_list_size "2048"
+#max_output_buffer_size "8192"
#
-################################################################
+###############################################################################
-###################### CHARACTER ENCODINGS #####################
-#
-# If file or directory names do not display correctly, then you
-# may need to change this. In most cases it should be either
-# "ISO-8859-1" or "UTF-8". You must recreate your database
-# after changing this (use mpd --create-db).
-#
-#filesystem_charset "ISO-8859-1"
-#
-# The encoding that ID3v1 tags should be converted from.
-#
-#id3v1_encoding "ISO-8859-1"
-#
-################################################################
-
-
-######################### OTHER OPTIONS ########################
-#
-# Try disabling this if you have MP3s which appear to end
-# abruptly. If this solves the problem, it is highly
-# recommended that you fix your MP3s with vbrfix (available from
-# <http://www.willwap.co.uk/Programs/vbrfix.php>), at which
-# point you can re-enable support for gapless MP3 playback.
-#
-#gapless_mp3_playback "yes"
+# Character Encoding ##########################################################
#
-# Enable this if you wish to use your MPD created playlists in
-# other music players.
+# If file or directory names do not display correctly for your locale then you
+# may need to modify this setting. After modification of this setting mpd
+# --create-db must be run to change the database.
#
-#save_absolute_paths_in_playlists "no"
+#filesystem_charset "UTF-8"
#
-# A list of tag types that MPD will scan for and make available
-# to clients.
+# This setting controls the encoding that ID3v1 tags should be converted from.
#
-#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
+#id3v1_encoding "ISO-8859-1"
#
-################################################################
+###############################################################################
diff --git a/doc/protocol.xml b/doc/protocol.xml
index 304b492b1..ff5d4838f 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -924,12 +924,12 @@ OK
<cmdsynopsis>
<command>playlistdelete</command>
<arg choice="req"><replaceable>NAME</replaceable></arg>
- <arg choice="req"><replaceable>SONGID</replaceable></arg>
+ <arg choice="req"><replaceable>SONGPOS</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
- Deletes <varname>SONGID</varname> from the
+ Deletes <varname>SONGPOS</varname> from the
playlist <filename>NAME.m3u</filename>.
</para>
</listitem>
diff --git a/scripts/test.sh b/scripts/test.sh
new file mode 100755
index 000000000..0f13f94d4
--- /dev/null
+++ b/scripts/test.sh
@@ -0,0 +1,87 @@
+#!/bin/sh -e
+#
+# This shell script tests the build of MPD with various compile-time
+# options.
+#
+# Author: Max Kellermann <max@duempel.org>
+
+PREFIX=/tmp/mpd
+rm -rf $PREFIX
+
+export CFLAGS="-Os"
+
+test -x configure || NOCONFIGURE=1 ./autogen.sh
+
+# all features on
+./configure --prefix=$PREFIX/full \
+ --disable-dependency-tracking --enable-debug --enable-werror \
+ --enable-un \
+ --enable-ao --enable-mod --enable-mvp
+make -j2 install
+make distclean
+
+# no UN, no oggvorbis, no flac, enable oggflac
+./configure --prefix=$PREFIX/small \
+ --disable-dependency-tracking --enable-debug --enable-werror \
+ --disable-un \
+ --disable-flac --disable-oggvorbis --enable-oggflac
+make -j2 install
+make distclean
+
+# strip down (disable TCP, disable nearly all plugins)
+CFLAGS="$CFLAGS -DNDEBUG" \
+./configure --prefix=$PREFIX/tiny \
+ --disable-dependency-tracking --disable-debug --enable-werror \
+ --disable-tcp \
+ --disable-curl \
+ --disable-id3 --disable-lsr \
+ --disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
+ --disable-shout-ogg --disable-shout-mp3 --disable-lame \
+ --disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
+ --disable-flac --disable-oggvorbis --disable-oggflac --disable-audiofile \
+ --with-zeroconf=no
+make -j2 install
+make distclean
+
+# shout: ogg without mp3
+./configure --prefix=$PREFIX/shout_ogg \
+ --disable-dependency-tracking --disable-debug --enable-werror \
+ --disable-tcp \
+ --disable-curl \
+ --disable-id3 --disable-lsr \
+ --disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
+ --enable-shout-ogg --disable-shout-mp3 --disable-lame \
+ --disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
+ --disable-flac --enable-oggvorbis --disable-oggflac --disable-audiofile \
+ --with-zeroconf=no
+make -j2 install
+make distclean
+
+# shout: mp3 without ogg
+./configure --prefix=$PREFIX/shout_mp3 \
+ --disable-dependency-tracking --disable-debug --enable-werror \
+ --disable-tcp \
+ --disable-curl \
+ --disable-id3 --disable-lsr \
+ --disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
+ --disable-shout-ogg --enable-shout-mp3 --enable-lame \
+ --disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
+ --disable-flac --disable-oggvorbis --disable-oggflac --disable-audiofile \
+ --with-zeroconf=no
+make -j2 install
+make distclean
+
+# oggvorbis + oggflac
+./configure --prefix=$PREFIX/oggvorbisflac \
+ --disable-dependency-tracking --disable-debug --enable-werror \
+ --disable-tcp \
+ --disable-curl \
+ --disable-id3 --disable-lsr \
+ --disable-mp3 \
+ --disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
+ --disable-shout-ogg --disable-shout-mp3 --disable-lame \
+ --disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
+ --disable-flac --enable-oggvorbis --enable-oggflac --disable-audiofile \
+ --with-zeroconf=no
+make -j2 install
+make distclean
diff --git a/src/Makefile.am b/src/Makefile.am
index 0ec95ee82..38ba8b223 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -325,10 +325,13 @@ mpd_LDADD = $(MPD_LIBS) \
# URL: git://www.kernel.org/pub/scm/devel/sparse/sparse.git
SPARSE = sparse
SPARSE_FLAGS =
+SPARSE_CPPFLAGS = $(DEFAULT_INCLUDES) \
+ -I$(shell $(CC) -print-file-name=include) \
+ -I$(shell $(CC) -print-file-name=include-fixed)
sparse-check:
for i in $(mpd_SOURCES); \
do \
- $(SPARSE) -I. $(mpd_CFLAGS) $(SPARSE_FLAGS) $(srcdir)/$$i || exit; \
+ $(SPARSE) -I. $(mpd_CFLAGS) $(mpd_CPPFLAGS) $(SPARSE_FLAGS) $(SPARSE_CPPFLAGS) $(srcdir)/$$i || exit; \
done
TEST_CFLAGS = -DUNIT_TEST
diff --git a/src/client.c b/src/client.c
index f654797b7..74b31392a 100644
--- a/src/client.c
+++ b/src/client.c
@@ -700,10 +700,19 @@ static void client_write_output(struct client *client)
if (client_is_expired(client) || !client->send_buf_used)
return;
- if (!g_queue_is_empty(client->deferred_send))
+ if (!g_queue_is_empty(client->deferred_send)) {
client_defer_output(client, client->send_buf,
client->send_buf_used);
- else
+
+ /* try to flush the deferred buffers now; the current
+ server command may take too long to finish, and
+ meanwhile try to feed output to the client,
+ otherwise it will time out. One reason why
+ deferring is slow might be that currently each
+ client_write() allocates a new deferred buffer.
+ This should be optimized after MPD 0.14. */
+ client_write_deferred(client);
+ } else
client_write_direct(client, client->send_buf,
client->send_buf_used);
diff --git a/src/command.c b/src/command.c
index c725282aa..9793830c1 100644
--- a/src/command.c
+++ b/src/command.c
@@ -275,7 +275,8 @@ handle_urlhandlers(struct client *client,
{
if (client_get_uid(client) > 0)
client_puts(client, "handler: file://\n");
- return printRemoteUrlHandlers(client);
+ printRemoteUrlHandlers(client);
+ return COMMAND_RETURN_OK;
}
static enum command_return
@@ -449,6 +450,12 @@ handle_add(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
if (isRemoteUrl(path))
return addToPlaylist(path, NULL);
+ if (uri_has_scheme(path)) {
+ command_error(client, ACK_ERROR_NO_EXIST,
+ "unsupported URI scheme");
+ return COMMAND_RETURN_ERROR;
+ }
+
result = addAllIn(path);
if (result == (enum playlist_result)-1) {
command_error(client, ACK_ERROR_NO_EXIST,
@@ -1222,7 +1229,11 @@ handle_playlistadd(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
if (isRemoteUrl(path))
result = spl_append_uri(path, playlist);
- else
+ else if (uri_has_scheme(path)) {
+ command_error(client, ACK_ERROR_NO_EXIST,
+ "unsupported URI scheme");
+ return COMMAND_RETURN_ERROR;
+ } else
result = addAllInToStoredPlaylist(path, playlist);
if (result == (enum playlist_result)-1) {
diff --git a/src/conf.c b/src/conf.c
index cdcb917f6..680a5fb1c 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -171,8 +171,6 @@ void initConf(void)
registerConfigParam(CONF_SAMPLERATE_CONVERTER, 0, 0);
registerConfigParam(CONF_AUDIO_BUFFER_SIZE, 0, 0);
registerConfigParam(CONF_BUFFER_BEFORE_PLAY, 0, 0);
- registerConfigParam(CONF_HTTP_BUFFER_SIZE, 0, 0);
- registerConfigParam(CONF_HTTP_PREBUFFER_SIZE, 0, 0);
registerConfigParam(CONF_HTTP_PROXY_HOST, 0, 0);
registerConfigParam(CONF_HTTP_PROXY_PORT, 0, 0);
registerConfigParam(CONF_HTTP_PROXY_USER, 0, 0);
diff --git a/src/conf.h b/src/conf.h
index e2e50c5bc..2b73bb6d7 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -49,8 +49,6 @@
#define CONF_SAMPLERATE_CONVERTER "samplerate_converter"
#define CONF_AUDIO_BUFFER_SIZE "audio_buffer_size"
#define CONF_BUFFER_BEFORE_PLAY "buffer_before_play"
-#define CONF_HTTP_BUFFER_SIZE "http_buffer_size"
-#define CONF_HTTP_PREBUFFER_SIZE "http_prebuffer_size"
#define CONF_HTTP_PROXY_HOST "http_proxy_host"
#define CONF_HTTP_PROXY_PORT "http_proxy_port"
#define CONF_HTTP_PROXY_USER "http_proxy_user"
diff --git a/src/decoder/ffmpeg_plugin.c b/src/decoder/ffmpeg_plugin.c
index f9e40e2f5..7f7978b9d 100644
--- a/src/decoder/ffmpeg_plugin.c
+++ b/src/decoder/ffmpeg_plugin.c
@@ -106,7 +106,7 @@ static int64_t mpd_ffmpeg_seek(URLContext *h, int64_t pos, int whence)
static int mpd_ffmpeg_close(URLContext *h)
{
- h->priv_data = 0;
+ h->priv_data = NULL;
return 0;
}
@@ -208,30 +208,46 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
AVCodecContext *codec_context,
const AVRational *time_base)
{
+ enum decoder_command cmd = DECODE_COMMAND_NONE;
int position;
uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
int len, audio_size;
+ uint8_t *packet_data;
+ int packet_size;
- position = av_rescale_q(packet->pts, *time_base,
- (AVRational){1, 1});
+ packet_data = packet->data;
+ packet_size = packet->size;
- audio_size = sizeof(audio_buf);
- len = avcodec_decode_audio2(codec_context,
- (int16_t *)audio_buf,
- &audio_size,
- packet->data, packet->size);
+ while ((packet_size > 0) && (cmd == DECODE_COMMAND_NONE)) {
+ audio_size = sizeof(audio_buf);
+ len = avcodec_decode_audio2(codec_context,
+ (int16_t *)audio_buf,
+ &audio_size,
+ packet_data, packet_size);
- if (len < 0) {
- g_message("skipping frame\n");
- return decoder_get_command(decoder);
- }
- assert(audio_size >= 0);
+ position = av_rescale_q(packet->pts, *time_base,
+ (AVRational){1, 1});
+
+ if (len < 0) {
+ /* if error, we skip the frame */
+ g_message("decoding failed\n");
+ break;
+ }
- return decoder_data(decoder, is,
- audio_buf, audio_size,
- position,
- codec_context->bit_rate / 1000, NULL);
+ packet_data += len;
+ packet_size -= len;
+
+ if (audio_size <= 0) {
+ g_message("no audio frame\n");
+ continue;
+ }
+ cmd = decoder_data(decoder, is,
+ audio_buf, audio_size,
+ position,
+ codec_context->bit_rate / 1000, NULL);
+ }
+ return cmd;
}
static bool
@@ -263,7 +279,7 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
}
//there is some problem with this on some demux (mp3 at least)
- if (format_context->duration != (int)AV_NOPTS_VALUE) {
+ if (format_context->duration != (int64_t)AV_NOPTS_VALUE) {
total_time = format_context->duration / AV_TIME_BASE;
}
@@ -314,7 +330,7 @@ static bool ffmpeg_tag_internal(struct ffmpeg_context *ctx)
const AVFormatContext *f = ctx->format_context;
tag->time = 0;
- if (f->duration != (int)AV_NOPTS_VALUE)
+ if (f->duration != (int64_t)AV_NOPTS_VALUE)
tag->time = f->duration / AV_TIME_BASE;
if (f->author[0])
tag_add_item(tag, TAG_ITEM_ARTIST, f->author);
@@ -368,8 +384,9 @@ static struct tag *ffmpeg_tag(const char *file)
*/
static const char *const ffmpeg_suffixes[] = {
- "wma", "asf", "wmv", "mpeg", "mpg", "avi", "vob", "mov", "qt", "swf", "rm", "swf",
- "mp1", "mp2", "mp3", "mp4", "m4a", "flac", "ogg", "wav", "au", "aiff", "aif", "ac3", "aac", "mpc",
+ "wma", "asf", "wmv", "mpeg", "mpg", "avi", "vob", "mov", "qt", "swf",
+ "rm", "swf", "mp1", "mp2", "mp3", "mp4", "m4a", "flac", "ogg", "wav",
+ "au", "aiff", "aif", "ac3", "aac", "mpc", "ape",
NULL
};
diff --git a/src/decoder/mp3_plugin.c b/src/decoder/mp3_plugin.c
index a3643b842..3a908299f 100644
--- a/src/decoder/mp3_plugin.c
+++ b/src/decoder/mp3_plugin.c
@@ -323,8 +323,8 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize,
#endif
static enum mp3_action
-decode_next_frame_header(struct mp3_data *data, struct tag **tag,
- struct replay_gain_info **replay_gain_info_r)
+decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag,
+ G_GNUC_UNUSED struct replay_gain_info **replay_gain_info_r)
{
enum mad_layer layer;
@@ -705,7 +705,7 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag,
struct lame lame;
struct mad_bitptr ptr;
int bitlen;
- int ret;
+ enum mp3_action ret;
/* stfu gcc */
memset(&xing, 0, sizeof(struct xing));
@@ -976,7 +976,7 @@ static bool
mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r)
{
struct decoder *decoder = data->decoder;
- int ret;
+ enum mp3_action ret;
enum decoder_command cmd;
mp3_update_timer_next_frame(data);
diff --git a/src/decoder_api.c b/src/decoder_api.c
index bf389222b..dd7096017 100644
--- a/src/decoder_api.c
+++ b/src/decoder_api.c
@@ -249,6 +249,13 @@ decoder_data(struct decoder *decoder,
length = pcm_convert(&dc.in_audio_format, _data,
length, &dc.out_audio_format,
data, &decoder->conv_state);
+
+ /* under certain circumstances, pcm_convert() may
+ return an empty buffer - this condition should be
+ investigated further, but for now, do this check as
+ a workaround: */
+ if (length == 0)
+ return DECODE_COMMAND_NONE;
}
if (replay_gain_info != NULL && (replay_gain_mode != REPLAY_GAIN_OFF))
diff --git a/src/listen.c b/src/listen.c
index 0e3467364..5a2b8d3da 100644
--- a/src/listen.c
+++ b/src/listen.c
@@ -112,7 +112,8 @@ static int establishListen(int pf, const struct sockaddr *addrp,
return 0;
}
-static void parseListenConfigParam(unsigned int port, ConfigParam * param)
+static void
+parseListenConfigParam(G_GNUC_UNUSED unsigned int port, ConfigParam * param)
{
const struct sockaddr *addrp;
socklen_t addrlen;
diff --git a/src/locate.c b/src/locate.c
index 6b8e87734..2004b132d 100644
--- a/src/locate.c
+++ b/src/locate.c
@@ -138,7 +138,7 @@ strstrSearchTag(struct song *song, enum tag_type type, char *str)
song_get_url(song, path_max_tmp);
p = g_utf8_casefold(path_max_tmp, -1);
- if (strstr(path_max_tmp, str))
+ if (strstr(p, str))
ret = 1;
g_free(p);
if (ret == 1 || type == LOCATE_TAG_FILE_TYPE)
diff --git a/src/log.c b/src/log.c
index e09aaf32a..1510b29e9 100644
--- a/src/log.c
+++ b/src/log.c
@@ -33,12 +33,12 @@
#include <pthread.h>
#include <glib.h>
-#define LOG_LEVEL_SECURE G_LOG_LEVEL_MESSAGE
+#define LOG_LEVEL_SECURE G_LOG_LEVEL_INFO
#define LOG_DATE_BUF_SIZE 16
#define LOG_DATE_LEN (LOG_DATE_BUF_SIZE - 1)
-static unsigned int log_threshold = G_LOG_LEVEL_INFO;
+static unsigned int log_threshold = G_LOG_LEVEL_MESSAGE;
static const char *log_charset;
@@ -116,7 +116,7 @@ void initLog(bool verbose)
if (!(param = getConfigParam(CONF_LOG_LEVEL)))
return;
if (0 == strcmp(param->value, "default")) {
- log_threshold = G_LOG_LEVEL_INFO;
+ log_threshold = G_LOG_LEVEL_MESSAGE;
} else if (0 == strcmp(param->value, "secure")) {
log_threshold = LOG_LEVEL_SECURE;
} else if (0 == strcmp(param->value, "verbose")) {
diff --git a/src/ls.c b/src/ls.c
index b5cb5cfeb..f0f403f44 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -32,7 +32,7 @@ static const char *remoteUrlPrefixes[] = {
NULL
};
-int printRemoteUrlHandlers(struct client *client)
+void printRemoteUrlHandlers(struct client *client)
{
const char **prefixes = remoteUrlPrefixes;
@@ -40,77 +40,32 @@ int printRemoteUrlHandlers(struct client *client)
client_printf(client, "handler: %s\n", *prefixes);
prefixes++;
}
-
- return 0;
}
-int isValidRemoteUtf8Url(const char *utf8url)
+bool uri_has_scheme(const char *uri)
{
- int ret = 0;
- const char *temp;
-
- switch (isRemoteUrl(utf8url)) {
- case 1:
- ret = 1;
- temp = utf8url;
- while (*temp) {
- if ((*temp >= 'a' && *temp <= 'z') ||
- (*temp >= 'A' && *temp <= 'Z') ||
- (*temp >= '0' && *temp <= '9') ||
- *temp == '$' ||
- *temp == '-' ||
- *temp == '.' ||
- *temp == '+' ||
- *temp == '!' ||
- *temp == '*' ||
- *temp == '\'' ||
- *temp == '(' ||
- *temp == ')' ||
- *temp == ',' ||
- *temp == '%' ||
- *temp == '/' ||
- *temp == ':' ||
- *temp == '?' ||
- *temp == ';' || *temp == '&' || *temp == '=') {
- } else {
- ret = 1;
- break;
- }
- temp++;
- }
- break;
- }
-
- return ret;
+ return strstr(uri, "://") != NULL;
}
-int isRemoteUrl(const char *url)
+bool isRemoteUrl(const char *url)
{
- int count = 0;
const char **urlPrefixes = remoteUrlPrefixes;
while (*urlPrefixes) {
- count++;
if (g_str_has_prefix(url, *urlPrefixes))
- return count;
+ return true;
urlPrefixes++;
}
- return 0;
+ return false;
}
/* suffixes should be ascii only characters */
const char *getSuffix(const char *utf8file)
{
- const char *ret = NULL;
-
- while (*utf8file) {
- if (*utf8file == '.')
- ret = utf8file + 1;
- utf8file++;
- }
+ const char *dot = strrchr(g_basename(utf8file), '.');
- return ret;
+ return dot != NULL ? dot + 1 : NULL;
}
const struct decoder_plugin *
diff --git a/src/ls.h b/src/ls.h
index 92839e018..713b6ac20 100644
--- a/src/ls.h
+++ b/src/ls.h
@@ -22,16 +22,20 @@
#include "decoder_list.h"
#include "archive_list.h"
-#include <sys/time.h>
+#include <stdbool.h>
struct stat;
struct client;
const char *getSuffix(const char *utf8file);
-int isValidRemoteUtf8Url(const char *utf8url);
+/**
+ * Checks whether the specified URI has a schema in the form
+ * "scheme://".
+ */
+bool uri_has_scheme(const char *uri);
-int isRemoteUrl(const char *url);
+bool isRemoteUrl(const char *url);
const struct decoder_plugin *
hasMusicSuffix(const char *utf8file, unsigned int next);
@@ -39,6 +43,6 @@ hasMusicSuffix(const char *utf8file, unsigned int next);
const struct archive_plugin *
get_archive_by_suffix(const char *utf8file);
-int printRemoteUrlHandlers(struct client *client);
+void printRemoteUrlHandlers(struct client *client);
#endif
diff --git a/src/mapper.c b/src/mapper.c
index 6317c2f77..b3f86da00 100644
--- a/src/mapper.c
+++ b/src/mapper.c
@@ -84,13 +84,23 @@ rmp2amp_r(char *dst, const char *rel_path)
}
const char *
+map_uri_fs(const char *uri, char *buffer)
+{
+ assert(uri != NULL);
+ assert(*uri != '/');
+ assert(buffer != NULL);
+
+ return rmp2amp_r(buffer, utf8_to_fs_charset(buffer, uri));
+}
+
+const char *
map_directory_fs(const struct directory *directory, char *buffer)
{
const char *dirname = directory_get_path(directory);
if (isRootDirectory(dirname))
return music_dir;
- return rmp2amp_r(buffer, utf8_to_fs_charset(buffer, dirname));
+ return map_uri_fs(dirname, buffer);
}
const char *
diff --git a/src/mapper.h b/src/mapper.h
index e8249b27d..2aecd9a52 100644
--- a/src/mapper.h
+++ b/src/mapper.h
@@ -33,6 +33,14 @@ void mapper_init(void);
void mapper_finish(void);
/**
+ * Determines the absolute file system path of a relative URI. This
+ * is basically done by converting the URI to the file system charset
+ * and prepending the music directory.
+ */
+const char *
+map_uri_fs(const char *uri, char *buffer);
+
+/**
* Determines the file system path of a directory object.
*
* @param directory the directory object
diff --git a/src/output/ao_plugin.c b/src/output/ao_plugin.c
index 3907448ae..4c69592ff 100644
--- a/src/output/ao_plugin.c
+++ b/src/output/ao_plugin.c
@@ -201,6 +201,12 @@ audioOutputAo_openDevice(void *data, struct audio_format *audio_format)
audioOutputAo_closeDevice(ad);
}
+ /* support for 24 bit samples in libao is currently dubious,
+ and until we have sorted that out, resample everything to
+ 16 bit */
+ if (audio_format->bits > 16)
+ audio_format->bits = 16;
+
format.bits = audio_format->bits;
format.rate = audio_format->sample_rate;
format.byte_format = AO_FMT_NATIVE;
diff --git a/src/output/osx_plugin.c b/src/output/osx_plugin.c
index b368ed8a1..3a7c009ed 100644
--- a/src/output/osx_plugin.c
+++ b/src/output/osx_plugin.c
@@ -18,10 +18,14 @@
#include "../output_api.h"
#include "../utils.h"
-#include "../log.h"
+#include <glib.h>
+#include <pthread.h>
#include <AudioUnit/AudioUnit.h>
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "osx"
+
typedef struct _OsxData {
AudioUnit au;
pthread_mutex_t mutex;
@@ -35,7 +39,7 @@ typedef struct _OsxData {
static OsxData *newOsxData(void)
{
- OsxData *ret = xmalloc(sizeof(OsxData));
+ OsxData *ret = g_new(OsxData, 1);
pthread_mutex_init(&ret->mutex, NULL);
pthread_cond_init(&ret->condition, NULL);
@@ -124,8 +128,8 @@ static void osx_closeDevice(void *data)
od->started = 0;
}
- CloseComponent(od->au);
AudioUnitUninitialize(od->au);
+ CloseComponent(od->au);
}
static OSStatus
@@ -139,6 +143,7 @@ osx_render(void *vdata,
AudioBuffer *buffer = &bufferList->mBuffers[0];
size_t bufferSize = buffer->mDataByteSize;
size_t bytesToCopy;
+ size_t bytes;
int curpos = 0;
/*DEBUG("osx_render: enter : %i\n", (int)bufferList->mNumberBuffers);
@@ -177,21 +182,20 @@ osx_render(void *vdata,
}
*/
- bytesToCopy = od->len < bufferSize ? od->len : bufferSize;
+ bytesToCopy = MIN(od->len, bufferSize);
bufferSize = bytesToCopy;
od->len -= bytesToCopy;
- if (od->pos + bytesToCopy > od->bufferSize) {
- size_t bytes = od->bufferSize - od->pos;
- memcpy(buffer->mData + curpos, od->buffer + od->pos, bytes);
+ bytes = od->bufferSize - od->pos;
+ if (bytesToCopy > bytes) {
+ memcpy((unsigned char*)buffer->mData + curpos, od->buffer + od->pos, bytes);
od->pos = 0;
curpos += bytes;
bytesToCopy -= bytes;
}
- memcpy(buffer->mData + curpos, od->buffer + od->pos, bytesToCopy);
+ memcpy((unsigned char*)buffer->mData + curpos, od->buffer + od->pos, bytesToCopy);
od->pos += bytesToCopy;
- curpos += bytesToCopy;
if (od->pos >= od->bufferSize)
od->pos = 0;
@@ -219,6 +223,9 @@ osx_openDevice(void *data, struct audio_format *audioFormat)
AURenderCallbackStruct callback;
AudioStreamBasicDescription streamDesc;
+ if (audioFormat->bits > 16)
+ audioFormat->bits = 16;
+
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
@@ -227,18 +234,18 @@ osx_openDevice(void *data, struct audio_format *audioFormat)
comp = FindNextComponent(NULL, &desc);
if (comp == 0) {
- ERROR("Error finding OS X component\n");
+ g_warning("Error finding OS X component\n");
return false;
}
if (OpenAComponent(comp, &od->au) != noErr) {
- ERROR("Unable to open OS X component\n");
+ g_warning("Unable to open OS X component\n");
return false;
}
if (AudioUnitInitialize(od->au) != 0) {
CloseComponent(od->au);
- ERROR("Unable to initialize OS X audio unit\n");
+ g_warning("Unable to initialize OS X audio unit\n");
return false;
}
@@ -250,7 +257,7 @@ osx_openDevice(void *data, struct audio_format *audioFormat)
&callback, sizeof(callback)) != 0) {
AudioUnitUninitialize(od->au);
CloseComponent(od->au);
- ERROR("unable to set callback for OS X audio unit\n");
+ g_warning("unable to set callback for OS X audio unit\n");
return false;
}
@@ -272,14 +279,14 @@ osx_openDevice(void *data, struct audio_format *audioFormat)
&streamDesc, sizeof(streamDesc)) != 0) {
AudioUnitUninitialize(od->au);
CloseComponent(od->au);
- ERROR("Unable to set format on OS X device\n");
+ g_warning("Unable to set format on OS X device\n");
return false;
}
/* create a buffer of 1s */
od->bufferSize = (audioFormat->sample_rate) *
audio_format_frame_size(audioFormat);
- od->buffer = xrealloc(od->buffer, od->bufferSize);
+ od->buffer = g_realloc(od->buffer, od->bufferSize);
od->pos = 0;
od->len = 0;
@@ -292,6 +299,7 @@ osx_play(void *data, const char *playChunk, size_t size)
{
OsxData *od = data;
size_t bytesToCopy;
+ size_t bytes;
size_t curpos;
/* DEBUG("osx_play: enter\n"); */
@@ -301,7 +309,7 @@ osx_play(void *data, const char *playChunk, size_t size)
od->started = 1;
err = AudioOutputUnitStart(od->au);
if (err) {
- ERROR("unable to start audio output: %i\n", err);
+ g_warning("unable to start audio output: %i\n", err);
return false;
}
}
@@ -314,20 +322,18 @@ osx_play(void *data, const char *playChunk, size_t size)
if (curpos >= od->bufferSize)
curpos -= od->bufferSize;
- bytesToCopy = od->bufferSize < size ? od->bufferSize : size;
+ bytesToCopy = MIN(od->bufferSize, size);
while (od->len > od->bufferSize - bytesToCopy) {
/* DEBUG("osx_play: wait\n"); */
pthread_cond_wait(&od->condition, &od->mutex);
}
- bytesToCopy = od->bufferSize - od->len;
- bytesToCopy = bytesToCopy < size ? bytesToCopy : size;
size -= bytesToCopy;
od->len += bytesToCopy;
- if (curpos + bytesToCopy > od->bufferSize) {
- size_t bytes = od->bufferSize - curpos;
+ bytes = od->bufferSize - curpos;
+ if (bytesToCopy > bytes) {
memcpy(od->buffer + curpos, playChunk, bytes);
curpos = 0;
playChunk += bytes;
@@ -335,7 +341,6 @@ osx_play(void *data, const char *playChunk, size_t size)
}
memcpy(od->buffer + curpos, playChunk, bytesToCopy);
- curpos += bytesToCopy;
playChunk += bytesToCopy;
}
diff --git a/src/output/shout_plugin.c b/src/output/shout_plugin.c
index 7fdf4c1e0..9edaf63af 100644
--- a/src/output/shout_plugin.c
+++ b/src/output/shout_plugin.c
@@ -203,9 +203,9 @@ static void *my_shout_init_driver(struct audio_output *audio_output,
}
sd->encoder = shout_encoder_plugin_get(encoding);
- if (sd->encoder == NULL) {
- g_error("couldn't find shout encoder plugin for \"%s\"\n", encoding);
- }
+ if (sd->encoder == NULL)
+ g_error("couldn't find shout encoder plugin \"%s\"\n",
+ encoding);
block_param = getBlockParam(param, "protocol");
if (block_param) {
diff --git a/src/output_thread.c b/src/output_thread.c
index b65a601a3..c887828bb 100644
--- a/src/output_thread.c
+++ b/src/output_thread.c
@@ -69,9 +69,17 @@ static void ao_play(struct audio_output *ao)
assert(size > 0);
- if (!audio_format_equals(&ao->inAudioFormat, &ao->outAudioFormat))
+ if (!audio_format_equals(&ao->inAudioFormat, &ao->outAudioFormat)) {
convertAudioFormat(ao, &data, &size);
+ /* under certain circumstances, pcm_convert() may
+ return an empty buffer - this condition should be
+ investigated further, but for now, do this check as
+ a workaround: */
+ if (size == 0)
+ return;
+ }
+
ret = ao->plugin->play(ao->data, data, size);
if (!ret) {
ao->plugin->cancel(ao->data);
diff --git a/src/pcm_utils.c b/src/pcm_utils.c
index 4759c20ac..f73df8aef 100644
--- a/src/pcm_utils.c
+++ b/src/pcm_utils.c
@@ -379,8 +379,6 @@ pcm_convert_16(const struct audio_format *src_format,
dest_format->sample_rate,
dest_buffer, dest_size,
&state->resample);
- if (len == 0)
- exit(EXIT_FAILURE);
}
return len;
@@ -421,8 +419,6 @@ pcm_convert_24(const struct audio_format *src_format,
dest_format->sample_rate,
(int32_t*)dest_buffer, dest_size,
&state->resample);
- if (len == 0)
- exit(EXIT_FAILURE);
}
return len;
@@ -461,7 +457,7 @@ size_t pcm_convert_size(const struct audio_format *inFormat, size_t src_size,
assert((src_size % audio_format_frame_size(inFormat)) == 0);
dest_size /= audio_format_frame_size(inFormat);
- dest_size = floor(0.5 + (double)dest_size * ratio);
+ dest_size = ceil((double)dest_size * ratio);
dest_size *= audio_format_frame_size(outFormat);
return dest_size;
diff --git a/src/player_control.c b/src/player_control.c
index 1d5c76aa0..b8e9499f6 100644
--- a/src/player_control.c
+++ b/src/player_control.c
@@ -44,6 +44,13 @@ void pc_deinit(void)
notify_deinit(&pc.notify);
}
+void
+pc_song_deleted(const struct song *song)
+{
+ if (pc.errored_song == song)
+ pc.errored_song = NULL;
+}
+
static void player_command(enum player_command cmd)
{
pc.command = cmd;
@@ -141,12 +148,22 @@ enum player_error getPlayerError(void)
return pc.error;
}
+static const char *
+pc_errored_song_uri(void)
+{
+ char path_max_tmp[MPD_PATH_MAX];
+
+ if (pc.errored_song == NULL)
+ return "?";
+
+ return song_get_url(pc.errored_song, path_max_tmp);
+}
+
char *getPlayerErrorStr(void)
{
/* static OK here, only one user in main task */
static char error[MPD_PATH_MAX + 64]; /* still too much */
static const size_t errorlen = sizeof(error);
- char path_max_tmp[MPD_PATH_MAX];
*error = '\0'; /* likely */
switch (pc.error) {
@@ -156,11 +173,11 @@ char *getPlayerErrorStr(void)
case PLAYER_ERROR_FILENOTFOUND:
snprintf(error, errorlen,
"file \"%s\" does not exist or is inaccessible",
- song_get_url(pc.errored_song, path_max_tmp));
+ pc_errored_song_uri());
break;
case PLAYER_ERROR_FILE:
snprintf(error, errorlen, "problems decoding \"%s\"",
- song_get_url(pc.errored_song, path_max_tmp));
+ pc_errored_song_uri());
break;
case PLAYER_ERROR_AUDIO:
strcpy(error, "problems opening audio device");
@@ -170,7 +187,7 @@ char *getPlayerErrorStr(void)
break;
case PLAYER_ERROR_UNKTYPE:
snprintf(error, errorlen, "file type of \"%s\" is unknown",
- song_get_url(pc.errored_song, path_max_tmp));
+ pc_errored_song_uri());
}
return *error ? error : NULL;
}
diff --git a/src/player_control.h b/src/player_control.h
index 2ae1fb618..fa228d8b3 100644
--- a/src/player_control.h
+++ b/src/player_control.h
@@ -84,6 +84,14 @@ void pc_init(unsigned int buffered_before_play);
void pc_deinit(void);
+/**
+ * Call this function when the specified song pointer is about to be
+ * invalidated. This makes sure that player_control.errored_song does
+ * not point to an invalid pointer.
+ */
+void
+pc_song_deleted(const struct song *song);
+
void
playerPlay(struct song *song);
diff --git a/src/playlist.c b/src/playlist.c
index 8581755ca..ba69844de 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -200,8 +200,10 @@ void clearPlaylist(void)
stopPlaylist();
for (unsigned i = 0; i < playlist.length; i++) {
- if (!song_in_database(playlist.songs[i]))
+ if (!song_in_database(playlist.songs[i])) {
+ pc_song_deleted(playlist.songs[i]);
song_free(playlist.songs[i]);
+ }
playlist.idToPosition[playlist.positionToId[i]] = -1;
playlist.songs[i] = NULL;
@@ -537,7 +539,7 @@ song_by_url(const char *url)
if (song != NULL)
return song;
- if (isValidRemoteUtf8Url(url))
+ if (isRemoteUrl(url))
return song_remote_new(url);
return NULL;
@@ -670,8 +672,10 @@ enum playlist_result deleteFromPlaylist(unsigned song)
|| playlist.order[playlist.current] == song))
clearPlayerQueue();
- if (!song_in_database(playlist.songs[song]))
+ if (!song_in_database(playlist.songs[song])) {
+ pc_song_deleted(playlist.songs[song]);
song_free(playlist.songs[song]);
+ }
playlist.idToPosition[playlist.positionToId[song]] = -1;
@@ -738,6 +742,8 @@ deleteASongFromPlaylist(const struct song *song)
for (unsigned i = 0; i < playlist.length; i++)
if (song == playlist.songs[i])
deleteFromPlaylist(i);
+
+ pc_song_deleted(song);
}
void stopPlaylist(void)
diff --git a/src/playlist_save.c b/src/playlist_save.c
index 4ae965154..b07137d9e 100644
--- a/src/playlist_save.c
+++ b/src/playlist_save.c
@@ -46,9 +46,9 @@ playlist_print_uri(FILE *file, const char *uri)
char tmp[MPD_PATH_MAX];
const char *s;
- if (playlist_saveAbsolutePaths && !isValidRemoteUtf8Url(uri) &&
+ if (playlist_saveAbsolutePaths && !isRemoteUrl(uri) &&
uri[0] != '/')
- s = map_directory_child_fs(db_get_root(), uri, tmp);
+ s = map_uri_fs(uri, tmp);
else
s = utf8_to_fs_charset(tmp, uri);
diff --git a/src/stored_playlist.c b/src/stored_playlist.c
index cadd2ccdf..78977bf69 100644
--- a/src/stored_playlist.c
+++ b/src/stored_playlist.c
@@ -156,7 +156,7 @@ spl_load(const char *utf8path)
if (*s == PLAYLIST_COMMENT)
continue;
- if (!isValidRemoteUtf8Url(s)) {
+ if (!isRemoteUrl(s)) {
struct song *song;
path_utf8 = map_fs_to_utf8(s, path_max_tmp);
@@ -338,7 +338,7 @@ spl_append_song(const char *utf8path, struct song *song)
return PLAYLIST_RESULT_ERRNO;
}
- if (st.st_size >= ((MPD_PATH_MAX+1) * (off_t)playlist_max_length)) {
+ if (st.st_size / (MPD_PATH_MAX + 1) >= (off_t)playlist_max_length) {
while (fclose(file) != 0 && errno == EINTR);
return PLAYLIST_RESULT_TOO_LARGE;
}
@@ -360,7 +360,7 @@ spl_append_uri(const char *url, const char *utf8file)
if (song)
return spl_append_song(utf8file, song);
- if (!isValidRemoteUtf8Url(url))
+ if (!isRemoteUrl(url))
return PLAYLIST_RESULT_NO_SUCH_SONG;
song = song_remote_new(url);
diff --git a/src/stored_playlist.h b/src/stored_playlist.h
index 1ac5c33af..26dd163a1 100644
--- a/src/stored_playlist.h
+++ b/src/stored_playlist.h
@@ -22,6 +22,7 @@
#include "playlist.h"
#include <glib.h>
+#include <time.h>
struct song;
diff --git a/src/update.c b/src/update.c
index 5d85ffff4..c7ad71c7b 100644
--- a/src/update.c
+++ b/src/update.c
@@ -59,7 +59,7 @@ static struct condition delete_cond;
enum {
DEFAULT_FOLLOW_INSIDE_SYMLINKS = true,
- DEFAULT_FOLLOW_OUTSIDE_SYMLINKS = false,
+ DEFAULT_FOLLOW_OUTSIDE_SYMLINKS = true,
};
static bool follow_inside_symlinks;