Commit cb802aa8 authored by Alexey Morsov's avatar Alexey Morsov

Merge commit 'v0.17.0-git200711' into alt

parents 2ccb1f5d 0ea4c970
......@@ -59,3 +59,4 @@ test/dump_playlist
test/run_normalize
test/tmp
test/run_inotify
test/test_queue_priority
......@@ -119,6 +119,9 @@ WAVE, AIFF, and many others.
libwavpack - http://www.wavpack.com/
For WavPack playback.
despotify - https://github.com/SimonKagstrom/despotify
For Spotify playback.
Optional Miscellaneous Dependencies
-----------------------------------
......@@ -141,6 +144,9 @@ For the sticker database.
libcue - http://libcue.sourceforge.net/
For CUE sheet support.
libcdio - http://www.gnu.org/software/libcdio/
For playing audio CDs.
pkg-config
----------
......
......@@ -99,6 +99,7 @@ mpd_headers = \
src/decoder/flac_pcm.h \
src/decoder/_flac_common.h \
src/decoder/_ogg_common.h \
src/decoder/pcm_decoder_plugin.h \
src/input_init.h \
src/input_plugin.h \
src/input_registry.h \
......@@ -108,6 +109,9 @@ mpd_headers = \
src/input/curl_input_plugin.h \
src/input/rewind_input_plugin.h \
src/input/mms_input_plugin.h \
src/input/despotify_input_plugin.h \
src/input/cdio_paranoia_input_plugin.h \
src/despotify_utils.h \
src/text_file.h \
src/text_input_stream.h \
src/icy_server.h \
......@@ -140,6 +144,7 @@ mpd_headers = \
src/output/httpd_client.h \
src/output/httpd_internal.h \
src/output/pulse_output_plugin.h \
src/output/roar_output_plugin.h \
src/output/winmm_output_plugin.h \
src/page.h \
src/pcm_buffer.h \
......@@ -178,6 +183,7 @@ mpd_headers = \
src/playlist/asx_playlist_plugin.h \
src/playlist/rss_playlist_plugin.h \
src/playlist/lastfm_playlist_plugin.h \
src/playlist/despotify_playlist_plugin.h \
src/playlist/cue_playlist_plugin.h \
src/playlist/flac_playlist_plugin.h \
src/poison.h \
......@@ -214,6 +220,7 @@ mpd_headers = \
src/strset.h \
src/uri.h \
src/utils.h \
src/string_util.h \
src/volume.h \
src/zeroconf.h src/zeroconf-internal.h \
src/locate.h \
......@@ -276,12 +283,17 @@ src_mpd_SOURCES = \
src/client_event.c \
src/client_expire.c \
src/client_global.c \
src/client_idle.h \
src/client_idle.c \
src/client_list.c \
src/client_new.c \
src/client_process.c \
src/client_read.c \
src/client_write.c \
src/client_message.h \
src/client_message.c \
src/client_subscribe.h \
src/client_subscribe.c \
src/server_socket.c \
src/listen.c \
src/log.c \
......@@ -347,11 +359,17 @@ src_mpd_SOURCES = \
src/strset.c \
src/uri.c \
src/utils.c \
src/string_util.c \
src/volume.c \
src/locate.c \
src/stored_playlist.c \
src/timer.c
if ENABLE_DESPOTIFY
src_mpd_SOURCES += \
src/despotify_utils.c
endif
if ENABLE_INOTIFY
src_mpd_SOURCES += \
src/inotify_source.c \
......@@ -461,6 +479,7 @@ DECODER_LIBS = \
$(CUE_LIBS)
DECODER_SRC = \
src/decoder/pcm_decoder_plugin.c \
src/decoder_buffer.c \
src/decoder_plugin.c \
src/decoder_list.c
......@@ -616,11 +635,13 @@ endif
INPUT_CFLAGS = \
$(CURL_CFLAGS) \
$(CDIO_PARANOIA_CFLAGS) \
$(FFMPEG_CFLAGS) \
$(MMS_CFLAGS)
INPUT_LIBS = \
$(CURL_LIBS) \
$(CDIO_PARANOIA_LIBS) \
$(FFMPEG_LIBS) \
$(MMS_LIBS)
......@@ -636,6 +657,10 @@ INPUT_SRC += src/input/curl_input_plugin.c \
src/icy_metadata.c
endif
if ENABLE_CDIO_PARANOIA
INPUT_SRC += src/input/cdio_paranoia_input_plugin.c
endif
if HAVE_FFMPEG
INPUT_SRC += src/input/ffmpeg_input_plugin.c
endif
......@@ -644,6 +669,10 @@ if ENABLE_MMS
INPUT_SRC += src/input/mms_input_plugin.c
endif
if ENABLE_DESPOTIFY
INPUT_SRC += src/input/despotify_input_plugin.c
endif
OUTPUT_CFLAGS = \
$(AO_CFLAGS) \
......@@ -658,6 +687,7 @@ OUTPUT_LIBS = \
$(LIBWRAP_LDFLAGS) \
$(AO_LIBS) \
$(ALSA_LIBS) \
$(ROAR_LIBS) \
$(FFADO_LIBS) \
$(JACK_LIBS) \
$(OPENAL_LIBS) \
......@@ -691,6 +721,11 @@ OUTPUT_SRC += src/output/alsa_plugin.c
MIXER_SRC += src/mixer/alsa_mixer_plugin.c
endif
if HAVE_ROAR
OUTPUT_SRC += src/output/roar_plugin.c
MIXER_SRC += src/mixer/roar_mixer_plugin.c
endif
if ENABLE_FFADO_OUTPUT
OUTPUT_SRC += src/output/ffado_output_plugin.c
endif
......@@ -728,6 +763,11 @@ if HAVE_OSX
OUTPUT_SRC += src/output/osx_plugin.c
endif
if ENABLE_RAOP_OUTPUT
OUTPUT_SRC += src/output/raop_output_plugin.c
MIXER_SRC += src/mixer/raop_mixer_plugin.c
endif
if HAVE_PULSE
OUTPUT_SRC += src/output/pulse_output_plugin.c
MIXER_SRC += src/mixer/pulse_mixer_plugin.c
......@@ -775,6 +815,10 @@ if ENABLE_LASTFM
PLAYLIST_SRC += src/playlist/lastfm_playlist_plugin.c
endif
if ENABLE_DESPOTIFY
PLAYLIST_SRC += src/playlist/despotify_playlist_plugin.c
endif
if HAVE_CUE
PLAYLIST_SRC += src/playlist/cue_playlist_plugin.c
endif
......@@ -825,9 +869,13 @@ sparse-check:
if ENABLE_TEST
TESTS =
C_TESTS = \
test/test_queue_priority
TESTS = $(C_TESTS)
noinst_PROGRAMS = \
$(C_TESTS) \
test/read_conf \
test/run_input \
test/dump_playlist \
......@@ -849,7 +897,7 @@ test_read_conf_CPPFLAGS = $(AM_CPPFLAGS) \
test_read_conf_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS)
test_read_conf_SOURCES = test/read_conf.c \
src/conf.c src/tokenizer.c src/utils.c
src/conf.c src/tokenizer.c src/utils.c src/string_util.c
test_run_input_CPPFLAGS = $(AM_CPPFLAGS) \
$(ARCHIVE_CFLAGS) \
......@@ -860,7 +908,7 @@ test_run_input_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS)
test_run_input_SOURCES = test/run_input.c \
test/stdbin.h \
src/conf.c src/tokenizer.c src/utils.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c\
src/tag.c src/tag_pool.c src/tag_save.c \
src/fd_util.c \
$(ARCHIVE_SRC) \
......@@ -878,7 +926,7 @@ test_dump_playlist_LDADD = $(MPD_LIBS) \
$(INPUT_LIBS) \
$(GLIB_LIBS)
test_dump_playlist_SOURCES = test/dump_playlist.c \
src/conf.c src/tokenizer.c src/utils.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c\
src/uri.c \
src/song.c src/tag.c src/tag_pool.c src/tag_save.c \
src/text_input_stream.c src/fifo_buffer.c \
......@@ -908,7 +956,7 @@ test_run_decoder_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS)
test_run_decoder_SOURCES = test/run_decoder.c \
test/stdbin.h \
src/conf.c src/tokenizer.c src/utils.c src/log.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c src/log.c \
src/tag.c src/tag_pool.c \
src/replay_gain_info.c \
src/uri.c \
......@@ -931,7 +979,7 @@ test_read_tags_LDADD = $(MPD_LIBS) \
$(INPUT_LIBS) $(DECODER_LIBS) \
$(GLIB_LIBS)
test_read_tags_SOURCES = test/read_tags.c \
src/conf.c src/tokenizer.c src/utils.c src/log.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c src/log.c \
src/tag.c src/tag_pool.c \
src/replay_gain_info.c \
src/uri.c \
......@@ -951,7 +999,7 @@ test_run_filter_SOURCES = test/run_filter.c \
test/stdbin.h \
src/filter_plugin.c \
src/filter_registry.c \
src/conf.c src/tokenizer.c src/utils.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c \
src/pcm_volume.c src/pcm_convert.c src/pcm_byteswap.c \
src/pcm_format.c src/pcm_channels.c src/pcm_dither.c \
src/pcm_pack.c \
......@@ -968,12 +1016,23 @@ if HAVE_LIBSAMPLERATE
test_run_filter_SOURCES += src/pcm_resample_libsamplerate.c
endif
if ENABLE_DESPOTIFY
test_read_tags_SOURCES += \
src/despotify_utils.c
test_run_input_SOURCES += \
src/despotify_utils.c
test_dump_playlist_SOURCES += \
src/despotify_utils.c
test_run_decoder_SOURCES += \
src/despotify_utils.c
endif
if ENABLE_ENCODER
noinst_PROGRAMS += test/run_encoder
test_run_encoder_SOURCES = test/run_encoder.c \
test/stdbin.h \
src/conf.c src/tokenizer.c \
src/utils.c \
src/utils.c src/string_util.c \
src/tag.c src/tag_pool.c \
src/audio_check.c \
src/audio_format.c \
......@@ -1034,7 +1093,7 @@ test_run_output_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS)
test_run_output_SOURCES = test/run_output.c \
test/stdbin.h \
src/conf.c src/tokenizer.c src/utils.c src/log.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c src/log.c \
src/audio_check.c \
src/audio_format.c \
src/audio_parser.c \
......@@ -1070,7 +1129,7 @@ test_read_mixer_LDADD = $(MPD_LIBS) \
$(OUTPUT_LIBS) \
$(GLIB_LIBS)
test_read_mixer_SOURCES = test/read_mixer.c \
src/conf.c src/tokenizer.c src/utils.c src/log.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c src/log.c \
src/mixer_control.c src/mixer_api.c \
src/filter_plugin.c \
src/filter/volume_filter_plugin.c \
......@@ -1098,6 +1157,12 @@ test_run_inotify_SOURCES = test/run_inotify.c \
test_run_inotify_LDADD = $(GLIB_LIBS)
endif
test_test_queue_priority_SOURCES = \
src/queue.c \
test/test_queue_priority.c
test_test_queue_priority_LDADD = \
$(GLIB_LIBS)
endif
......@@ -1135,8 +1200,7 @@ endif
doc/api/html/index.html: doc/doxygen.conf
@mkdir -p $(@D)
[ "$(srcdir)" = "." ] || sed '/INPUT *=/ s/\([^ ]\+\/\)/$(subst /,\/,$(srcdir))\/\1/g' $(srcdir)/doc/doxygen.conf >doc/doxygen.conf
$(DOXYGEN) doc/doxygen.conf
$(DOXYGEN) $<
all-local: $(DOCBOOK_HTML) doc/api/html/index.html
......
ver 0.16.2 (2011/??/??)
ver 0.17 (2011/??/??)
* protocol:
- support client-to-client communication
- "update" and "rescan" need only "CONTROL" permission
* input:
- cdio_paranoia: new input plugin to play audio CDs
- curl: enable CURLOPT_NETRC
- ffmpeg: support libavformat 0.7
* decoder:
- mpg123: implement seeking
- ffmpeg: drop support for pre-0.5 ffmpeg
- ffmpeg: support libavformat 0.7
* output:
- osx: allow user to specify other audio devices
- raop: new output plugin
- shout: add possibility to set url
- roar: new output plugin for RoarAudio
* state_file: add option "restore_paused"
* cue: show CUE track numbers
ver 0.16.4 (2011/??/??)
* fix memory leaks
* don't resume playback when seeking to another song while paused
* apply follow_inside_symlinks to absolute symlinks
* decoder:
- ffmpeg: workaround for semantic API change in recent ffmpeg versions
- flac: validate the sample rate when scanning the tag
- wavpack: obey all decoder commands, stop at CUE track border
* encoder:
- vorbis: don't send end-of-stream on flush
* output:
- alsa: fix SIGFPE when alsa announces a period size of 0
ver 0.16.3 (2011/06/04)
* fix assertion failure in audio format mask parser
* fix NULL pointer dereference in playlist parser
* fix playlist files in base music directory
* database: allow directories with just playlists
* decoder:
- ffmpeg: support libavcodec 0.7
ver 0.16.2 (2011/03/18)
* configure.ac:
- fix bashism in tremor test
* decoder:
- tremor: fix configure test
- gme: detect end of song
* encoder:
- vorbis: reset the Ogg stream after flush
* output:
- httpd: fix uninitialized variable
- httpd: include sys/socket.h
- oss: AFMT_S24_PACKED is little-endian
- oss: disable 24 bit playback on FreeBSD
......@@ -138,9 +187,20 @@ ver 0.16 (2010/12/11)
* make single mode 'sticky'
ver 0.15.16 (2010/??/??)
ver 0.15.17 (2011/??/??)
* encoder:
- vorbis: reset the Ogg stream after flush
* decoders:
- vorbis: fix tremor support
ver 0.15.16 (2011/03/13)
* output:
- ao: initialize the ao_sample_format struct
- jack: fix crash with mono playback
* encoders:
- lame: explicitly configure the output sample rate
* update: log all file permission problems
ver 0.15.15 (2010/11/08)
......
AC_PREREQ(2.60)
AC_INIT(mpd, 0.16.2~git, musicpd-dev-team@lists.sourceforge.net)
AC_INIT(mpd, 0.17~git, musicpd-dev-team@lists.sourceforge.net)
AC_CONFIG_SRCDIR([src/main.c])
AM_INIT_AUTOMAKE([foreign 1.10 dist-bzip2 subdir-objects])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_MACRO_DIR([m4])
AC_DEFINE(PROTOCOL_VERSION, "0.16.0", [The MPD protocol version])
AC_DEFINE(PROTOCOL_VERSION, "0.17.0", [The MPD protocol version])
dnl ---------------------------------------------------------------------------
......@@ -121,6 +121,11 @@ AC_ARG_ENABLE(alsa,
AS_HELP_STRING([--enable-alsa], [enable ALSA support]),,
[enable_alsa=auto])
AC_ARG_ENABLE(roar,
AS_HELP_STRING([--enable-roar],
[enable support for RoarAudio]),,
[enable_roar=auto])
AC_ARG_ENABLE(ao,
AS_HELP_STRING([--enable-ao],
[enable support for libao]),,
......@@ -136,6 +141,11 @@ AC_ARG_ENABLE(bzip2,
[enable bzip2 archive support (default: disabled)]),,
enable_bzip2=no)
AC_ARG_ENABLE(cdio-paranoia,
AS_HELP_STRING([--enable-cdio-paranoia],
[enable support for audio CD support]),,
enable_cdio_paranoia=auto)
AC_ARG_ENABLE(cue,
AS_HELP_STRING([--enable-cue],
[enable support for libcue support]),,
......@@ -195,6 +205,11 @@ AC_ARG_ENABLE(httpd-output,
[enables the HTTP server output]),,
[enable_httpd_output=auto])
AC_ARG_ENABLE(raop-output,
AS_HELP_STRING([--enable-raop-output],
[enables the RAOP output]),,
[enable_raop_output=no])
AC_ARG_ENABLE(id3,
AS_HELP_STRING([--disable-id3],
[disable id3 support (default: enable)]),,
......@@ -227,6 +242,11 @@ AC_ARG_ENABLE(lastfm,
[enable support for last.fm radio (default: disable)]),,
[enable_lastfm=no])
AC_ARG_ENABLE(despotify,
AS_HELP_STRING([--enable-despotify],
[enable support for despotify (default: disable)]),,
[enable_despotify=no])
AC_ARG_ENABLE(lame-encoder,
AS_HELP_STRING([--enable-lame-encoder],
[enable the LAME mp3 encoder]),,
......@@ -537,15 +557,16 @@ no|avahi|bonjour)
;;
esac
enable_avahi=no
enable_bounjour=no
if test x$with_zeroconf != xno; then
if test x$with_zeroconf = xavahi || test x$with_zeroconf = xauto; then
PKG_CHECK_MODULES([AVAHI], [avahi-client avahi-glib],
[found_avahi=1;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])]
MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS",
[found_avahi=0])
[enable_avahi=yes;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])]
MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS")
fi
if test x$found_avahi = x1; then
if test x$enable_avahi = xyes; then
with_zeroconf=avahi
elif test x$with_zeroconf = xavahi; then
AC_MSG_ERROR([Avahi support requested but not found])
......@@ -553,13 +574,12 @@ if test x$with_zeroconf != xno; then
if test x$with_zeroconf = xbonjour || test x$with_zeroconf = xauto; then
AC_CHECK_HEADER(dns_sd.h,
[found_bonjour=1;AC_DEFINE([HAVE_BONJOUR], 1, [Define to enable Bonjour Zeroconf support])],
[found_bonjour=0])
[enable_bonjour=yes;AC_DEFINE([HAVE_BONJOUR], 1, [Define to enable Bonjour Zeroconf support])])
AC_CHECK_LIB(dns_sd, DNSServiceRegister,
MPD_LIBS="$MPD_LIBS -ldns_sd")
fi
if test x$found_bonjour = x1; then
if test x$enable_bonjour = xyes; then
with_zeroconf=bonjour
elif test x$with_zeroconf = xbonjour; then
AC_MSG_ERROR([Bonjour support requested but not found])
......@@ -634,8 +654,27 @@ if test x$enable_lastfm = xyes; then
fi
AM_CONDITIONAL(ENABLE_LASTFM, test x$enable_lastfm = xyes)
dnl --------------------------------- Despotify ---------------------------------
MPD_AUTO_PKG(despotify, DESPOTIFY, [despotify],
[Despotify support], [despotify not found])
if test x$enable_despotify = xyes; then
AC_DEFINE(ENABLE_DESPOTIFY, 1, [Define when despotify is enabled])
MPD_LIBS="$MPD_LIBS $DESPOTIFY_LIBS"
fi
AM_CONDITIONAL(ENABLE_DESPOTIFY, test x$enable_despotify = xyes)
dnl ---------------------------------- libcue ---------------------------------
MPD_AUTO_PKG(cdio_paranoia, CDIO_PARANOIA, [libcdio_paranoia],
[libcdio_paranoia audio CD library], [libcdio_paranoia not found])
if test x$enable_cdio_paranoia = xyes; then
AC_DEFINE([ENABLE_CDIO_PARANOIA], 1,
[Define to enable libcdio_paranoia support])
fi
AM_CONDITIONAL(ENABLE_CDIO_PARANOIA, test x$enable_cdio_paranoia = xyes)
dnl ---------------------------------- libogg ---------------------------------
if test x$with_tremor == xno || test -z $with_tremor; then
if test x$with_tremor = xno || test -z $with_tremor; then
PKG_CHECK_MODULES(OGG, [ogg], enable_ogg=yes, enable_ogg=no)
fi
......@@ -732,21 +771,10 @@ AM_CONDITIONAL(HAVE_FAAD, test x$enable_aac = xyes)
AM_CONDITIONAL(HAVE_MP4, test x$enable_mp4 = xyes)
dnl ---------------------------------- ffmpeg ---------------------------------
MPD_AUTO_PKG(ffmpeg, FFMPEG, [libavformat >= 52 libavcodec >= 51 libavutil >= 49],
MPD_AUTO_PKG(ffmpeg, FFMPEG, [libavformat >= 52.31 libavcodec >= 52.20 libavutil >= 49.15],
[ffmpeg decoder library], [libavformat+libavcodec+libavutil not found])
if test x$enable_ffmpeg = xyes; then
# prior to ffmpeg svn12865, you had to specify include files
# without path prefix
old_CPPCFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $FFMPEG_CFLAGS"
AC_CHECK_HEADER(libavcodec/avcodec.h,,
AC_DEFINE(OLD_FFMPEG_INCLUDES, 1,
[Define if avcodec.h instead of libavcodec/avcodec.h should be included]))
CPPCFLAGS=$old_CPPFLAGS
fi
if test x$enable_ffmpeg = xyes; then
AC_DEFINE(HAVE_FFMPEG, 1, [Define for FFMPEG support])
fi
......@@ -1081,7 +1109,7 @@ if
fi
AM_CONDITIONAL(HAVE_OGG_COMMON,
test x$enable_vorbis = xyes || test x$enable_oggflac = xyes || test x$enable_flac = xyes)
test x$enable_vorbis = xyes || test x$enable_tremor = xyes || test x$enable_oggflac = xyes || test x$enable_flac = xyes)
AM_CONDITIONAL(HAVE_FLAC_COMMON,
test x$enable_flac = xyes || test x$enable_oggflac = xyes)
......@@ -1207,6 +1235,16 @@ fi
AM_CONDITIONAL(HAVE_ALSA, test x$enable_alsa = xyes)
dnl ----------------------------------- ROAR ----------------------------------
MPD_AUTO_PKG(roar, ROAR, [libroar >= 0.4.0],
[ROAR output plugin], [libroar not found])
if test x$enable_roar = xyes; then
AC_DEFINE(HAVE_ROAR, 1, [Define to enable ROAR support])
fi
AM_CONDITIONAL(HAVE_ROAR, test x$enable_roar = xyes)
dnl ----------------------------------- FFADO ---------------------------------
MPD_AUTO_PKG(ffado, FFADO, [libffado],
......@@ -1317,7 +1355,7 @@ enable_osx=no
case "$host_os" in
darwin*)
AC_DEFINE(HAVE_OSX, 1, [Define for compiling OS X support])
MPD_LIBS="$MPD_LIBS -framework AudioUnit -framework CoreServices"
MPD_LIBS="$MPD_LIBS -framework AudioUnit -framework CoreAudio -framework CoreServices"
enable_osx=yes ;;
esac
......@@ -1388,6 +1426,15 @@ esac
AM_CONDITIONAL(ENABLE_SOLARIS_OUTPUT, test x$enable_solaris_output = xyes)
dnl --------------------------------- RAOP ------------------------------------
if test x$enable_raop_output = xyes; then
AC_DEFINE(ENABLE_RAOP_OUTPUT, 1, [Define for compiling RAOP support])
MPD_LIBS="$MPD_LIBS -lssl -lcrypto"
fi
AM_CONDITIONAL(ENABLE_RAOP_OUTPUT, test x$enable_raop_output = xyes)
dnl --------------------------------- WinMM ---------------------------------
case "$host_os" in
......@@ -1407,6 +1454,7 @@ AM_CONDITIONAL(ENABLE_WINMM_OUTPUT, test x$enable_winmm_output = xyes)
dnl --------------------- Post Audio Output Plugins Tests ---------------------
if
test x$enable_alsa = xno &&
test x$enable_roar = xno &&
test x$enable_ao = xno &&
test x$enable_ffado = xno &&
test x$enable_fifo = xno &&
......@@ -1416,6 +1464,7 @@ if
test x$enable_openal = xno &&
test x$enable_oss = xno &&
test x$enable_osx = xno &&
test x$enable_raop_output = xno &&
test x$enable_pipe_output = xno &&
test x$enable_pulse = xno &&
test x$enable_recorder_output = xno &&
......@@ -1466,7 +1515,6 @@ if test x$GCC = xyes
then
MPD_CHECK_FLAG([-Wall])
MPD_CHECK_FLAG([-Wextra])
MPD_CHECK_FLAG([-Wno-deprecated-declarations])
MPD_CHECK_FLAG([-Wmissing-prototypes])
MPD_CHECK_FLAG([-Wshadow])
MPD_CHECK_FLAG([-Wpointer-arith])
......@@ -1543,10 +1591,12 @@ results(id3,[ID3])
printf '\nPlayback support:\n\t'
results(alsa,ALSA)
results(roar,ROAR)
results(ffado,FFADO)
results(fifo,FIFO)
results(recorder_output,[File Recorder])
results(httpd_output,[HTTP Daemon])
results(raop_output, [RAOP])
results(jack,[JACK])
results(ao,[libao])
results(oss,[OSS])
......@@ -1577,6 +1627,8 @@ printf '\nStreaming support:\n\t'
results(curl,[CURL])
results(lastfm,[Last.FM])
results(mms,[MMS])
results(cdio_paranoia, [CDIO_PARANOIA])
results(despotify,[Despotify])
printf '\n\n##########################################\n\n'
......@@ -1586,5 +1638,6 @@ dnl ---------------------------------------------------------------------------
dnl Generate files
dnl ---------------------------------------------------------------------------
AC_OUTPUT(Makefile)
AC_OUTPUT(doc/doxygen.conf)
echo 'MPD is ready for compilation, type "make" to begin.'
......@@ -31,7 +31,7 @@ PROJECT_NAME = MPD
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER = @VERSION@
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
......@@ -534,7 +534,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = src/
INPUT = @top_srcdir@/src/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -69,6 +69,9 @@ mpd will be saved to this file when mpd is terminated by a TERM signal or by
the "kill" command. When mpd is restarted, it will read the state file and
restore the state of mpd (including the playlist).
.TP
.B restore_paused <yes or no>
Put MPD into pause mode instead of starting playback after startup.
.TP
.B user <username>
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
......@@ -259,6 +262,17 @@ 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
.B despotify_user <name>
This specifies the user to use when logging in to Spotify using the despotify plugins.
.TP
.B despotify_password <name>
This specifies the password to use when logging in to Spotify using the despotify plugins.
.TP
.B despotify_high_bitrate <yes or no>
This specifies if the requested bitrate for Spotify should be high or not. Higher sounds
better but requires more processing and higher bandwidth. Default is yes.
.TP
.SH REQUIRED AUDIO OUTPUT PARAMETERS
.TP
.B type <type>
......@@ -464,6 +478,9 @@ connect to the icecast server. The default is 2 seconds.
.B description <description>
This specifies a description of the stream.
.TP
.B url <url>
This specifies a URL associated with the stream.
.TP
.B genre <genre>
This specifies the genre(s) of the stream.
.SH FILES
......
......@@ -103,6 +103,11 @@
#
#gapless_mp3_playback "yes"
#
# Setting "restore_paused" to "yes" puts MPD into pause mode instead
# of starting playback after startup.
#
#restore_paused "no"
#
# This setting enables MPD to create playlists in a format usable by other
# music players.
#
......@@ -235,6 +240,7 @@ input {
## protocol "icecast2" # optional
## user "source" # optional
## description "My Stream Description" # optional
## url "http://example.com" # optional
## genre "jazz" # optional
## public "no" # optional
## timeout "2" # optional
......
......@@ -236,6 +236,16 @@ cd mpd-version</programlisting>
</section>
<section>
<title>Configuring encoder plugins</title>
<para>
Encoders are used by some of the output plugins (such as
<varname>shout</varname>). The encoder settings are included
in the <varname>audio_output</varname> section.
</para>
</section>
<section>
<title>Configuring audio outputs</title>
<para>
......@@ -346,7 +356,7 @@ cd mpd-version</programlisting>
If set to "yes", then MPD attempts to keep this audio
output always open. This may be useful for streaming
servers, when you don't want to disconnect all
listeners even when playback is accidently stopped.
listeners even when playback is accidentally stopped.
</entry>
</row>
<row>
......@@ -446,7 +456,7 @@ cd mpd-version</programlisting>
</para>
<para>
To configure a filter, add a
To configure a playlist plugin, add a
<varname>playlist_plugin</varname> block to
<filename>mpd.conf</filename>:
</para>
......@@ -621,6 +631,78 @@ cd mpd-version</programlisting>
Plays streams with the MMS protocol.
</para>
</section>
<section>
<title><varname>cdio_paranoia</varname></title>
<para>
Plays audio CDs. The URI has the form:
"<filename>cdda://[DEVICE][/TRACK]</filename>". The
simplest form <filename>cdda://</filename> plays the whole
disc in the default drive.
</para>
</section>
<section>
<title><varname>despotify</varname></title>
<para>
Plays <ulink url="http://www.spotify.com">Spotify</ulink> tracks using the despotify
library. The despotify plugin uses a <filename>spt://</filename> URI and a Spotify
URL. So for example, you can add a song with:
</para>
<para>
<filename>mpc add spt://spotify:track:5qENVY0YEdZ7fiuOax70x1</filename>
</para>
<para>
You need a Spotify premium account to use this plugin, and you need
to setup username and password in the configuration file. The
configuration settings are global since the despotify playlist plugin
use the same settings.
</para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Setting</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>despotify_user</varname>
</entry>
<entry>
Sets up the Spotify username (required)
</entry>
</row>
<row>
<entry>
<varname>despotify_password</varname>
</entry>
<entry>
Sets up the Spotify password (required)
</entry>
</row>
<row>
<entry>
<varname>despotify_high_bitrate</varname>
</entry>
<entry>
Set up if high bitrate should be used for Spotify tunes.
High bitrate sounds better but slow systems can have problems
with playback (default yes).
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</section>
<section>
......@@ -658,6 +740,178 @@ cd mpd-version</programlisting>
</section>
<section>
<title>Encoder plugins</title>
<section>
<title><varname>flac</varname></title>
<para>
Encodes into FLAC (lossless).
</para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Setting</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>compression</varname>
</entry>
<entry>
Sets the <filename>libFLAC</filename> compression
level. The levels range from 0 (fastest, least
compression) to 8 (slowest, most compression).
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title><varname>lame</varname></title>
<para>
Encodes into MP3 using the LAME library.
</para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Setting</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>quality</varname>
</entry>
<entry>
Sets the quality for VBR. 0 is the highest quality,
9 is the lowest quality. Cannot be used with
<varname>bitrate</varname>.
</entry>
</row>
<row>
<entry>
<varname>bitrate</varname>
</entry>
<entry>
Sets the bit rate in kilobit per second. Cannot be
used with <varname>quality</varname>.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title><varname>null</varname></title>
<para>
Does not encode anything, passes the input PCM data as-is.
</para>
</section>
<section>
<title><varname>twolame</varname></title>
<para>
Encodes into MP2 using the <filename>twolame</filename>
library.
</para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Setting</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>quality</varname>
</entry>
<entry>
Sets the quality for VBR. 0 is the highest quality,
9 is the lowest quality. Cannot be used with
<varname>bitrate</varname>.
</entry>
</row>
<row>
<entry>
<varname>bitrate</varname>
</entry>
<entry>
Sets the bit rate in kilobit per second. Cannot be
used with <varname>quality</varname>.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title><varname>vorbis</varname></title>
<para>
Encodes into Ogg Vorbis.
</para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Setting</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>quality</varname>
</entry>
<entry>
Sets the quality for VBR. -1 is the lowest quality,
10 is the highest quality. Cannot be used with
<varname>bitrate</varname>.
</entry>
</row>
<row>
<entry>
<varname>bitrate</varname>
</entry>
<entry>
Sets the bit rate in kilobit per second. Cannot be
used with <varname>quality</varname>.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title><varname>wave</varname></title>
<para>
Encodes into WAV (lossless).
</para>
</section>
</section>
<section>
<title>Output plugins</title>
<section>
......@@ -1366,6 +1620,15 @@ cd mpd-version</programlisting>
</row>
<row>
<entry>
<varname>url</varname>
<parameter>URL</parameter>
</entry>
<entry>
Sets a URL associated with the stream (optional).
</entry>
</row>
<row>
<entry>
<varname>public</varname>
<parameter>yes|no</parameter>
</entry>
......@@ -1498,6 +1761,27 @@ cd mpd-version</programlisting>
playlist files.
</para>
</section>
<section>
<title><varname>despotify</varname></title>
<para>
Adds <ulink url="http://www.spotify.com/">Spotify</ulink>
playlists. Spotify playlists use the <filename>spt://</filename> URI,
and a Spotify playlist URL. So for example, you can load a playlist
with
</para>
<para>
<filename>mpc load spt://spotify:user:simon.kagstrom:playlist:3SUwkOe5VbVHysZcidEZtH</filename>
</para>
<para>
See the despotify input plugin for configuration options (username
and password needs to be setup)
</para>
</section>
</section>
</chapter>
</book>
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -60,8 +60,10 @@ ape_scan_internal(FILE *fp, tag_ape_callback_t callback, void *ctx)
assert(remaining > 10);
char *buffer = g_malloc(remaining);
if (fread(buffer, 1, remaining, fp) != remaining)
if (fread(buffer, 1, remaining, fp) != remaining) {
g_free(buffer);
return false;
}
/* read tags */
unsigned n = GUINT32_FROM_LE(footer.count);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -20,7 +20,7 @@
#include "config.h"
#include "archive_list.h"
#include "archive_plugin.h"
#include "utils.h"
#include "string_util.h"
#include "archive/bz2_archive_plugin.h"
#include "archive/iso9660_archive_plugin.h"
#include "archive/zzip_archive_plugin.h"
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -68,7 +68,7 @@ struct archive_plugin {
* Opens an input_stream of a file within the archive.
*
* @param path the path within the archive
* @param error_r location to store the error occuring, or
* @param error_r location to store the error occurring, or
* NULL to ignore errors
*/
struct input_stream *(*open_stream)(struct archive_file *af,
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -22,6 +22,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
enum sample_format {
SAMPLE_FORMAT_UNDEFINED = 0,
......@@ -219,6 +220,9 @@ static inline void
audio_format_mask_apply(struct audio_format *af,
const struct audio_format *mask)
{
assert(audio_format_valid(af));
assert(audio_format_mask_valid(mask));
if (mask->sample_rate != 0)
af->sample_rate = mask->sample_rate;
......@@ -227,6 +231,8 @@ audio_format_mask_apply(struct audio_format *af,
if (mask->channels != 0)
af->channels = mask->channels;
assert(audio_format_valid(af));
}
/**
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -192,6 +192,8 @@ audio_format_parse(struct audio_format *dest, const char *src,
}
audio_format_init(dest, rate, sample_format, channels);
assert(mask ? audio_format_mask_valid(dest)
: audio_format_valid(dest));
return true;
}
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -38,7 +38,7 @@ struct audio_format;
* @param dest the destination #audio_format struct
* @param src the input string
* @param mask if true, then "*" is allowed for any number of items
* @param error_r location to store the error occuring, or NULL to
* @param error_r location to store the error occurring, or NULL to
* ignore errors
* @return true on success
*/
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -27,11 +27,13 @@
struct client;
struct sockaddr;
struct player_control;
void client_manager_init(void);
void client_manager_deinit(void);
void client_new(int fd, const struct sockaddr *sa, size_t sa_length, int uid);
void client_new(struct player_control *player_control,
int fd, const struct sockaddr *sa, size_t sa_length, int uid);
bool client_is_expired(const struct client *client);
......@@ -60,17 +62,4 @@ void client_vprintf(struct client *client, const char *fmt, va_list args);
*/
G_GNUC_PRINTF(2, 3) void client_printf(struct client *client, const char *fmt, ...);
/**
* Adds the specified idle flags to all clients and immediately sends
* notifications to all waiting clients.
*/
void client_manager_idle_add(unsigned flags);
/**
* Checks whether the client has pending idle flags. If yes, they are
* sent immediately and "true" is returned". If no, it puts the
* client into waiting mode and returns false.
*/
bool client_idle_wait(struct client *client, unsigned flags);
#endif
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -18,6 +18,7 @@
*/
#include "config.h"
#include "client_idle.h"
#include "client_internal.h"
#include "idle.h"
......@@ -50,12 +51,9 @@ client_idle_notify(struct client *client)
g_timer_start(client->last_activity);
}
static void
client_idle_callback(gpointer data, gpointer user_data)
void
client_idle_add(struct client *client, unsigned flags)
{
struct client *client = data;
unsigned flags = GPOINTER_TO_UINT(user_data);
if (client_is_expired(client))
return;
......@@ -67,6 +65,15 @@ client_idle_callback(gpointer data, gpointer user_data)
}
}
static void
client_idle_callback(gpointer data, gpointer user_data)
{
struct client *client = data;
unsigned flags = GPOINTER_TO_UINT(user_data);
client_idle_add(client, flags);
}
void client_manager_idle_add(unsigned flags)
{
assert(flags != 0);
......
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CLIENT_IDLE_H
#define MPD_CLIENT_IDLE_H
#include <stdbool.h>
struct client;
void
client_idle_add(struct client *client, unsigned flags);
/**
* Adds the specified idle flags to all clients and immediately sends
* notifications to all waiting clients.
*/
void
client_manager_idle_add(unsigned flags);
/**
* Checks whether the client has pending idle flags. If yes, they are
* sent immediately and "true" is returned". If no, it puts the
* client into waiting mode and returns false.
*/
bool
client_idle_wait(struct client *client, unsigned flags);
#endif
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -21,17 +21,25 @@
#define MPD_CLIENT_INTERNAL_H
#include "client.h"
#include "client_message.h"
#include "command.h"
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "client"
enum {
CLIENT_MAX_SUBSCRIPTIONS = 16,
CLIENT_MAX_MESSAGES = 64,
};
struct deferred_buffer {
size_t size;
char data[sizeof(long)];
};
struct client {
struct player_control *player_control;
GIOChannel *channel;
guint source_id;
......@@ -67,6 +75,28 @@ struct client {
/** idle flags that the client wants to receive */
unsigned idle_subscriptions;
/**
* A list of channel names this client is subscribed to.
*/
GSList *subscriptions;
/**
* The number of subscriptions in #subscriptions. Used to
* limit the number of subscriptions.
*/
unsigned num_subscriptions;
/**
* A list of messages this client has received in reverse
* order (latest first).
*/
GSList *messages;
/**
* The number of messages in #messages.
*/
unsigned num_messages;
};
extern unsigned int client_max_connections;
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "client_message.h"
#include <assert.h>
#include <glib.h>
G_GNUC_PURE
static bool
valid_channel_char(const char ch)
{
return g_ascii_isalnum(ch) ||
ch == '_' || ch == '-' || ch == '.' || ch == ':';
}
bool
client_message_valid_channel_name(const char *name)
{
do {
if (!valid_channel_char(*name))
return false;
} while (*++name != 0);
return true;
}
void
client_message_init_null(struct client_message *msg)
{
assert(msg != NULL);
msg->channel = NULL;
msg->message = NULL;
}
void
client_message_init(struct client_message *msg,
const char *channel, const char *message)
{
assert(msg != NULL);
msg->channel = g_strdup(channel);
msg->message = g_strdup(message);
}
void
client_message_copy(struct client_message *dest,
const struct client_message *src)
{
assert(dest != NULL);
assert(src != NULL);
assert(client_message_defined(src));
client_message_init(dest, src->channel, src->message);
}
struct client_message *
client_message_dup(const struct client_message *src)
{
struct client_message *dest = g_slice_new(struct client_message);
client_message_copy(dest, src);
return dest;
}
void
client_message_deinit(struct client_message *msg)
{
assert(msg != NULL);
g_free(msg->channel);
g_free(msg->message);
}
void
client_message_free(struct client_message *msg)
{
client_message_deinit(msg);
g_slice_free(struct client_message, msg);
}
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CLIENT_MESSAGE_H
#define MPD_CLIENT_MESSAGE_H
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <glib.h>
/**
* A client-to-client message.
*/
struct client_message {
char *channel;
char *message;
};
G_GNUC_PURE
bool
client_message_valid_channel_name(const char *name);
G_GNUC_PURE
static inline bool
client_message_defined(const struct client_message *msg)
{
assert(msg != NULL);
assert((msg->channel == NULL) == (msg->message == NULL));
return msg->channel != NULL;
}
void
client_message_init_null(struct client_message *msg);
void
client_message_init(struct client_message *msg,
const char *channel, const char *message);
void
client_message_copy(struct client_message *dest,
const struct client_message *src);
G_GNUC_MALLOC G_GNUC_PURE
struct client_message *
client_message_dup(const struct client_message *src);
void
client_message_deinit(struct client_message *msg);
void
client_message_free(struct client_message *msg);
#endif
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -41,12 +41,15 @@
static const char GREETING[] = "OK MPD " PROTOCOL_VERSION "\n";
void client_new(int fd, const struct sockaddr *sa, size_t sa_length, int uid)
void
client_new(struct player_control *player_control,
int fd, const struct sockaddr *sa, size_t sa_length, int uid)
{
static unsigned int next_client_num;
struct client *client;
char *remote;
assert(player_control != NULL);
assert(fd >= 0);
#ifdef HAVE_LIBWRAP
......@@ -81,6 +84,7 @@ void client_new(int fd, const struct sockaddr *sa, size_t sa_length, int uid)
}
client = g_new0(struct client, 1);
client->player_control = player_control;
#ifndef G_OS_WIN32
client->channel = g_io_channel_unix_new(fd);
......@@ -117,6 +121,10 @@ void client_new(int fd, const struct sockaddr *sa, size_t sa_length, int uid)
client->send_buf_used = 0;
client->subscriptions = NULL;
client->messages = NULL;
client->num_messages = 0;
(void)send(fd, GREETING, sizeof(GREETING) - 1, 0);
client_list_add(client);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "client_subscribe.h"
#include "client_internal.h"
#include "client_idle.h"
#include "idle.h"
#include <string.h>
G_GNUC_PURE
static GSList *
client_find_subscription(const struct client *client, const char *channel)
{
for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i))
if (strcmp((const char *)i->data, channel) == 0)
return i;
return NULL;
}
enum client_subscribe_result
client_subscribe(struct client *client, const char *channel)
{
assert(client != NULL);
assert(channel != NULL);
if (!client_message_valid_channel_name(channel))
return CLIENT_SUBSCRIBE_INVALID;
if (client_find_subscription(client, channel) != NULL)
return CLIENT_SUBSCRIBE_ALREADY;
if (client->num_subscriptions >= CLIENT_MAX_SUBSCRIPTIONS)
return CLIENT_SUBSCRIBE_FULL;
client->subscriptions = g_slist_prepend(client->subscriptions,
g_strdup(channel));
++client->num_subscriptions;
idle_add(IDLE_SUBSCRIPTION);
return CLIENT_SUBSCRIBE_OK;
}
bool
client_unsubscribe(struct client *client, const char *channel)
{
GSList *i = client_find_subscription(client, channel);
if (i == NULL)
return false;
assert(client->num_subscriptions > 0);
client->subscriptions = g_slist_remove(client->subscriptions, i->data);
--client->num_subscriptions;
idle_add(IDLE_SUBSCRIPTION);
assert((client->num_subscriptions == 0) ==
(client->subscriptions == NULL));
return true;
}
void
client_unsubscribe_all(struct client *client)
{
for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i))
g_free(i->data);
g_slist_free(client->subscriptions);
client->subscriptions = NULL;
client->num_subscriptions = 0;
}
bool
client_push_message(struct client *client, const struct client_message *msg)
{
assert(client != NULL);
assert(msg != NULL);
assert(client_message_defined(msg));
if (client->num_messages >= CLIENT_MAX_MESSAGES ||
client_find_subscription(client, msg->channel) == NULL)
return false;
if (client->messages == NULL)
client_idle_add(client, IDLE_MESSAGE);
client->messages = g_slist_prepend(client->messages,
client_message_dup(msg));
++client->num_messages;
return true;
}
GSList *
client_read_messages(struct client *client)
{
GSList *messages = g_slist_reverse(client->messages);
client->messages = NULL;
client->num_messages = 0;
return messages;
}
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CLIENT_SUBSCRIBE_H
#define MPD_CLIENT_SUBSCRIBE_H
#include <stdbool.h>
#include <glib.h>
struct client;
struct client_message;
enum client_subscribe_result {
/** success */
CLIENT_SUBSCRIBE_OK,
/** invalid channel name */
CLIENT_SUBSCRIBE_INVALID,
/** already subscribed to this channel */
CLIENT_SUBSCRIBE_ALREADY,
/** too many subscriptions */
CLIENT_SUBSCRIBE_FULL,
};
enum client_subscribe_result
client_subscribe(struct client *client, const char *channel);
bool
client_unsubscribe(struct client *client, const char *channel);
void
client_unsubscribe_all(struct client *client);
bool
client_push_message(struct client *client, const struct client_message *msg);
G_GNUC_MALLOC
GSList *
client_read_messages(struct client *client);
#endif
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -79,7 +79,7 @@ static void version(void)
puts(PACKAGE " (MPD: Music Player Daemon) " VERSION " \n"
"\n"
"Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n"
"Copyright (C) 2008-2010 Max Kellermann <max@duempel.org>\n"
"Copyright (C) 2008-2011 Max Kellermann <max@duempel.org>\n"
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n"
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -20,6 +20,7 @@
#include "config.h"
#include "conf.h"
#include "utils.h"
#include "string_util.h"
#include "tokenizer.h"
#include "path.h"
#include "glib_compat.h"
......@@ -58,6 +59,7 @@ static struct config_entry config_entries[] = {
{ .name = CONF_LOG_FILE, false, false },
{ .name = CONF_PID_FILE, false, false },
{ .name = CONF_STATE_FILE, false, false },
{ .name = "restore_paused", false, false },
{ .name = CONF_USER, false, false },
{ .name = CONF_GROUP, false, false },
{ .name = CONF_BIND_TO_ADDRESS, true, false },
......@@ -97,6 +99,9 @@ static struct config_entry config_entries[] = {
{ .name = CONF_PLAYLIST_PLUGIN, true, true },
{ .name = CONF_AUTO_UPDATE, false, false },
{ .name = CONF_AUTO_UPDATE_DEPTH, false, false },
{ .name = CONF_DESPOTIFY_USER, false, false },
{ .name = CONF_DESPOTIFY_PASSWORD, false, false},
{ .name = CONF_DESPOTIFY_HIGH_BITRATE, false, false },
{ .name = "filter", true, true },
};
......@@ -269,7 +274,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
}
(*count)++;
line = g_strchug(line);
line = strchug_fast(line);
if (*line == 0 || *line == CONF_COMMENT)
continue;
......@@ -277,7 +282,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
/* end of this block; return from the function
(and from this "while" loop) */
line = g_strchug(line + 1);
line = strchug_fast(line + 1);
if (*line != 0 && *line != CONF_COMMENT) {
config_param_free(ret);
g_set_error(error_r, config_quark(), 0,
......@@ -355,7 +360,7 @@ config_read_file(const char *file, GError **error_r)
count++;
line = g_strchug(string);
line = strchug_fast(string);
if (*line == 0 || *line == CONF_COMMENT)
continue;
......@@ -367,6 +372,7 @@ config_read_file(const char *file, GError **error_r)
assert(*line != 0);
g_propagate_prefixed_error(error_r, error,
"line %i: ", count);
fclose(fp);
return false;
}
......@@ -378,6 +384,7 @@ config_read_file(const char *file, GError **error_r)
g_set_error(error_r, config_quark(), 0,
"unrecognized parameter in config file at "
"line %i: %s\n", count, name);
fclose(fp);
return false;
}
......@@ -387,6 +394,7 @@ config_read_file(const char *file, GError **error_r)
"config parameter \"%s\" is first defined "
"on line %i and redefined on line %i\n",
name, param->line, count);
fclose(fp);
return false;
}
......@@ -398,20 +406,24 @@ config_read_file(const char *file, GError **error_r)
if (*line != '{') {
g_set_error(error_r, config_quark(), 0,
"line %i: '{' expected", count);
fclose(fp);
return false;
}
line = g_strchug(line + 1);
line = strchug_fast(line + 1);
if (*line != 0 && *line != CONF_COMMENT) {
g_set_error(error_r, config_quark(), 0,
"line %i: Unknown tokens after '{'",
count);
fclose(fp);
return false;
}
param = config_read_block(fp, &count, string, error_r);
if (param == NULL)
if (param == NULL) {
fclose(fp);
return false;
}
} else {
/* a string value */
......@@ -428,6 +440,7 @@ config_read_file(const char *file, GError **error_r)
g_error_free(error);
}
fclose(fp);
return false;
}
......@@ -435,6 +448,7 @@ config_read_file(const char *file, GError **error_r)
g_set_error(error_r, config_quark(), 0,
"line %i: Unknown tokens after value",
count);
fclose(fp);
return false;
}
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -72,6 +72,9 @@
#define CONF_PLAYLIST_PLUGIN "playlist_plugin"
#define CONF_AUTO_UPDATE "auto_update"
#define CONF_AUTO_UPDATE_DEPTH "auto_update_depth"
#define CONF_DESPOTIFY_USER "despotify_user"
#define CONF_DESPOTIFY_PASSWORD "despotify_password"
#define CONF_DESPOTIFY_HIGH_BITRATE "despotify_high_bitrate"
#define DEFAULT_PLAYLIST_MAX_LENGTH (1024*16)
#define DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS false
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
......@@ -178,6 +178,15 @@ cue_tag(struct Cd *cd, unsigned tnum)
if (tag == NULL)
return NULL;
/* Create a tag number */
tag_clear_items_by_type(tag, TAG_TRACK);
char convert_uinttostring[8];
snprintf(convert_uinttostring, sizeof(convert_uinttostring),
"%02d/%02d", tnum, cd_get_ntrack(cd));
tag_add_item(tag, TAG_TRACK, convert_uinttostring);
tag->time = track_get_length(track)
- track_get_index(track, 1)
+ track_get_zero_pre(track);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -80,7 +80,7 @@ daemonize_kill(void)
ret = kill(pid, SIGTERM);
if (ret < 0)
MPD_ERROR("unable to kill proccess %i: %s",
MPD_ERROR("unable to kill process %i: %s",
pid, g_strerror(errno));
exit(EXIT_SUCCESS);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -180,7 +180,7 @@ db_check(void)
}
/* Check if we can write to the directory */
if (access(dirPath, R_OK | W_OK)) {
if (access(dirPath, X_OK | W_OK)) {
g_warning("Can't create db file in \"%s\": %s",
dirPath, strerror(errno));
g_free(dirPath);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -29,6 +29,7 @@
#include "tag.h"
#include "strset.h"
#include "stored_playlist.h"
#include "client_internal.h"
#include <glib.h>
......@@ -166,9 +167,11 @@ int printAllIn(struct client *client, const char *name)
}
static int
directoryAddSongToPlaylist(struct song *song, G_GNUC_UNUSED void *data)
directoryAddSongToPlaylist(struct song *song, void *data)
{
return playlist_append_song(&g_playlist, song, NULL);
struct player_control *pc = data;
return playlist_append_song(&g_playlist, pc, song, NULL);
}
struct add_data {
......@@ -185,9 +188,10 @@ directoryAddSongToStoredPlaylist(struct song *song, void *_data)
return 0;
}
int addAllIn(const char *name)
int
addAllIn(struct player_control *pc, const char *name)
{
return db_walk(name, directoryAddSongToPlaylist, NULL, NULL);
return db_walk(name, directoryAddSongToPlaylist, NULL, pc);
}
int addAllInToStoredPlaylist(const char *name, const char *utf8file)
......@@ -205,7 +209,9 @@ findAddInDirectory(struct song *song, void *_data)
struct search_data *data = _data;
if (locate_song_match(song, data->criteria))
return directoryAddSongToPlaylist(song, data);
return playlist_append_song(&g_playlist,
data->client->player_control,
song, NULL);
return 0;
}
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -22,10 +22,12 @@
struct client;
struct locate_item_list;
struct player_control;
int printAllIn(struct client *client, const char *name);
int addAllIn(const char *name);
int
addAllIn(struct player_control *pc, const char *name);
int addAllInToStoredPlaylist(const char *name, const char *utf8file);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -81,7 +81,7 @@ flac_tell_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd,
struct flac_data *data = (struct flac_data *) fdata;
if (!data->input_stream->seekable)
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
*offset = (long)(data->input_stream->offset);
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -224,6 +224,7 @@ flac_tag_apply_metadata(struct tag *tag, const char *track,
break;
case FLAC__METADATA_TYPE_STREAMINFO:
if (block->data.stream_info.sample_rate > 0)
tag->time = flac_duration(&block->data.stream_info);
break;
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -20,6 +20,7 @@
#ifndef MPD_FLAC_METADATA_H
#define MPD_FLAC_METADATA_H
#include <assert.h>
#include <stdbool.h>
#include <FLAC/metadata.h>
......@@ -29,6 +30,8 @@ struct replay_gain_info;
static inline unsigned
flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
{
assert(stream_info->sample_rate > 0);
return (stream_info->total_samples + stream_info->sample_rate - 1) /
stream_info->sample_rate;
}
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -24,6 +24,7 @@
#include <glib.h>
#include <mpg123.h>
#include <stdio.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "mpg123"
......@@ -105,6 +106,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
int error;
off_t num_samples;
enum decoder_command cmd;
struct mpg123_frameinfo info;
/* open the file */
......@@ -124,10 +126,25 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
/* tell MPD core we're ready */
decoder_initialized(decoder, &audio_format, false,
decoder_initialized(decoder, &audio_format, true,
(float)num_samples /
(float)audio_format.sample_rate);
if (mpg123_info(handle, &info) != MPG123_OK) {
info.vbr = MPG123_CBR;
info.bitrate = 0;
}
switch (info.vbr) {
case MPG123_ABR:
info.bitrate = info.abr_rate;
break;
case MPG123_CBR:
break;
default:
info.bitrate = 0;
}
/* the decoder main loop */
do {
......@@ -144,11 +161,30 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
break;
}
/* update bitrate for ABR/VBR */
if (info.vbr != MPG123_CBR) {
/* FIXME: maybe skip, as too expensive? */
/* FIXME: maybe, (info.vbr == MPG123_VBR) ? */
if (mpg123_info (handle, &info) != MPG123_OK)
info.bitrate = 0;
}
/* send to MPD */
cmd = decoder_data(decoder, NULL, buffer, nbytes, 0);
cmd = decoder_data(decoder, NULL, buffer, nbytes, info.bitrate);
/* seeking not yet implemented */
if (cmd == DECODE_COMMAND_SEEK) {
off_t c = decoder_seek_where(decoder)*audio_format.sample_rate;
c = mpg123_seek(handle, c, SEEK_SET);
if (c < 0)
decoder_seek_error(decoder);
else {
decoder_command_finished(decoder);
decoder_timestamp(decoder, c/(double)audio_format.sample_rate);
}
cmd = DECODE_COMMAND_NONE;
}
} while (cmd == DECODE_COMMAND_NONE);
/* cleanup */
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "decoder/pcm_decoder_plugin.h"
#include "decoder_api.h"
#include <glib.h>
#include <unistd.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "pcm"
static void
pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
{
static const struct audio_format audio_format = {
.sample_rate = 44100,
.format = SAMPLE_FORMAT_S16,
.channels = 2,
};
GError *error = NULL;
enum decoder_command cmd;
double time_to_size = audio_format_time_to_size(&audio_format);
float total_time = -1;
if (is->size >= 0)
total_time = is->size / time_to_size;
decoder_initialized(decoder, &audio_format, is->seekable, total_time);
do {
char buffer[4096];
size_t nbytes = decoder_read(decoder, is,
buffer, sizeof(buffer));
if (nbytes == 0 && input_stream_eof(is))
break;
cmd = nbytes > 0
? decoder_data(decoder, is,
buffer, nbytes, 0)
: decoder_get_command(decoder);
if (cmd == DECODE_COMMAND_SEEK) {
goffset offset = (goffset)(time_to_size *
decoder_seek_where(decoder));
if (input_stream_seek(is, offset, SEEK_SET, &error)) {
decoder_command_finished(decoder);
} else {
g_warning("seeking failed: %s", error->message);
g_error_free(error);
decoder_seek_error(decoder);
}
cmd = DECODE_COMMAND_NONE;
}
} while (cmd == DECODE_COMMAND_NONE);
}
static const char *const pcm_mime_types[] = {
/* for streams obtained by the cdio_paranoia input plugin */
"audio/x-mpd-cdda-pcm",
NULL
};
const struct decoder_plugin pcm_decoder_plugin = {
.name = "pcm",
.stream_decode = pcm_stream_decode,
.mime_types = pcm_mime_types,
};
/*
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/** \file
*
* Not really a decoder; this plugin forwards its input data "as-is".
*
* It was written only to support the "cdio_paranoia" input plugin,
* which does not need a decoder.
*/
#ifndef MPD_DECODER_PCM_H
#define MPD_DECODER_PCM_H
extern const struct decoder_plugin pcm_decoder_plugin;
#endif
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -34,9 +34,6 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "wavpack"
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
#define CHUNK_SIZE 1020
#define ERRORLEN 80
static struct {
......@@ -162,8 +159,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
enum sample_format sample_format;
struct audio_format audio_format;
format_samples_t format_samples;
char chunk[CHUNK_SIZE];
int samples_requested, samples_got;
float total_time;
int bytes_per_sample, output_sample_size;
......@@ -193,12 +188,15 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
output_sample_size = audio_format_frame_size(&audio_format);
/* wavpack gives us all kind of samples in a 32-bit space */
samples_requested = sizeof(chunk) / (4 * audio_format.channels);
int32_t chunk[1024];
const uint32_t samples_requested = G_N_ELEMENTS(chunk) /
audio_format.channels;
decoder_initialized(decoder, &audio_format, can_seek, total_time);
do {
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
enum decoder_command cmd = decoder_get_command(decoder);
while (cmd != DECODE_COMMAND_STOP) {
if (cmd == DECODE_COMMAND_SEEK) {
if (can_seek) {
unsigned where = decoder_seek_where(decoder) *
audio_format.sample_rate;
......@@ -213,29 +211,20 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
}
}
if (decoder_get_command(decoder) == DECODE_COMMAND_STOP) {
uint32_t samples_got = WavpackUnpackSamples(wpc, chunk,
samples_requested);
if (samples_got == 0)
break;
}
samples_got = WavpackUnpackSamples(
wpc, (int32_t *)chunk, samples_requested
);
if (samples_got > 0) {
int bitrate = (int)(WavpackGetInstantBitrate(wpc) /
1000 + 0.5);
format_samples(
bytes_per_sample, chunk,
samples_got * audio_format.channels
);
int bitrate = (int)(WavpackGetInstantBitrate(wpc) / 1000 +
0.5);
format_samples(bytes_per_sample, chunk,
samples_got * audio_format.channels);
decoder_data(
decoder, NULL, chunk,
cmd = decoder_data(decoder, NULL, chunk,
samples_got * output_sample_size,
bitrate
);
bitrate);
}
} while (samples_got > 0);
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment