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 ...@@ -59,3 +59,4 @@ test/dump_playlist
test/run_normalize test/run_normalize
test/tmp test/tmp
test/run_inotify test/run_inotify
test/test_queue_priority
...@@ -119,6 +119,9 @@ WAVE, AIFF, and many others. ...@@ -119,6 +119,9 @@ WAVE, AIFF, and many others.
libwavpack - http://www.wavpack.com/ libwavpack - http://www.wavpack.com/
For WavPack playback. For WavPack playback.
despotify - https://github.com/SimonKagstrom/despotify
For Spotify playback.
Optional Miscellaneous Dependencies Optional Miscellaneous Dependencies
----------------------------------- -----------------------------------
...@@ -141,6 +144,9 @@ For the sticker database. ...@@ -141,6 +144,9 @@ For the sticker database.
libcue - http://libcue.sourceforge.net/ libcue - http://libcue.sourceforge.net/
For CUE sheet support. For CUE sheet support.
libcdio - http://www.gnu.org/software/libcdio/
For playing audio CDs.
pkg-config pkg-config
---------- ----------
......
...@@ -99,6 +99,7 @@ mpd_headers = \ ...@@ -99,6 +99,7 @@ mpd_headers = \
src/decoder/flac_pcm.h \ src/decoder/flac_pcm.h \
src/decoder/_flac_common.h \ src/decoder/_flac_common.h \
src/decoder/_ogg_common.h \ src/decoder/_ogg_common.h \
src/decoder/pcm_decoder_plugin.h \
src/input_init.h \ src/input_init.h \
src/input_plugin.h \ src/input_plugin.h \
src/input_registry.h \ src/input_registry.h \
...@@ -108,6 +109,9 @@ mpd_headers = \ ...@@ -108,6 +109,9 @@ mpd_headers = \
src/input/curl_input_plugin.h \ src/input/curl_input_plugin.h \
src/input/rewind_input_plugin.h \ src/input/rewind_input_plugin.h \
src/input/mms_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_file.h \
src/text_input_stream.h \ src/text_input_stream.h \
src/icy_server.h \ src/icy_server.h \
...@@ -140,6 +144,7 @@ mpd_headers = \ ...@@ -140,6 +144,7 @@ mpd_headers = \
src/output/httpd_client.h \ src/output/httpd_client.h \
src/output/httpd_internal.h \ src/output/httpd_internal.h \
src/output/pulse_output_plugin.h \ src/output/pulse_output_plugin.h \
src/output/roar_output_plugin.h \
src/output/winmm_output_plugin.h \ src/output/winmm_output_plugin.h \
src/page.h \ src/page.h \
src/pcm_buffer.h \ src/pcm_buffer.h \
...@@ -178,6 +183,7 @@ mpd_headers = \ ...@@ -178,6 +183,7 @@ mpd_headers = \
src/playlist/asx_playlist_plugin.h \ src/playlist/asx_playlist_plugin.h \
src/playlist/rss_playlist_plugin.h \ src/playlist/rss_playlist_plugin.h \
src/playlist/lastfm_playlist_plugin.h \ src/playlist/lastfm_playlist_plugin.h \
src/playlist/despotify_playlist_plugin.h \
src/playlist/cue_playlist_plugin.h \ src/playlist/cue_playlist_plugin.h \
src/playlist/flac_playlist_plugin.h \ src/playlist/flac_playlist_plugin.h \
src/poison.h \ src/poison.h \
...@@ -214,6 +220,7 @@ mpd_headers = \ ...@@ -214,6 +220,7 @@ mpd_headers = \
src/strset.h \ src/strset.h \
src/uri.h \ src/uri.h \
src/utils.h \ src/utils.h \
src/string_util.h \
src/volume.h \ src/volume.h \
src/zeroconf.h src/zeroconf-internal.h \ src/zeroconf.h src/zeroconf-internal.h \
src/locate.h \ src/locate.h \
...@@ -276,12 +283,17 @@ src_mpd_SOURCES = \ ...@@ -276,12 +283,17 @@ src_mpd_SOURCES = \
src/client_event.c \ src/client_event.c \
src/client_expire.c \ src/client_expire.c \
src/client_global.c \ src/client_global.c \
src/client_idle.h \
src/client_idle.c \ src/client_idle.c \
src/client_list.c \ src/client_list.c \
src/client_new.c \ src/client_new.c \
src/client_process.c \ src/client_process.c \
src/client_read.c \ src/client_read.c \
src/client_write.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/server_socket.c \
src/listen.c \ src/listen.c \
src/log.c \ src/log.c \
...@@ -347,11 +359,17 @@ src_mpd_SOURCES = \ ...@@ -347,11 +359,17 @@ src_mpd_SOURCES = \
src/strset.c \ src/strset.c \
src/uri.c \ src/uri.c \
src/utils.c \ src/utils.c \
src/string_util.c \
src/volume.c \ src/volume.c \
src/locate.c \ src/locate.c \
src/stored_playlist.c \ src/stored_playlist.c \
src/timer.c src/timer.c
if ENABLE_DESPOTIFY
src_mpd_SOURCES += \
src/despotify_utils.c
endif
if ENABLE_INOTIFY if ENABLE_INOTIFY
src_mpd_SOURCES += \ src_mpd_SOURCES += \
src/inotify_source.c \ src/inotify_source.c \
...@@ -461,6 +479,7 @@ DECODER_LIBS = \ ...@@ -461,6 +479,7 @@ DECODER_LIBS = \
$(CUE_LIBS) $(CUE_LIBS)
DECODER_SRC = \ DECODER_SRC = \
src/decoder/pcm_decoder_plugin.c \
src/decoder_buffer.c \ src/decoder_buffer.c \
src/decoder_plugin.c \ src/decoder_plugin.c \
src/decoder_list.c src/decoder_list.c
...@@ -616,11 +635,13 @@ endif ...@@ -616,11 +635,13 @@ endif
INPUT_CFLAGS = \ INPUT_CFLAGS = \
$(CURL_CFLAGS) \ $(CURL_CFLAGS) \
$(CDIO_PARANOIA_CFLAGS) \
$(FFMPEG_CFLAGS) \ $(FFMPEG_CFLAGS) \
$(MMS_CFLAGS) $(MMS_CFLAGS)
INPUT_LIBS = \ INPUT_LIBS = \
$(CURL_LIBS) \ $(CURL_LIBS) \
$(CDIO_PARANOIA_LIBS) \
$(FFMPEG_LIBS) \ $(FFMPEG_LIBS) \
$(MMS_LIBS) $(MMS_LIBS)
...@@ -636,6 +657,10 @@ INPUT_SRC += src/input/curl_input_plugin.c \ ...@@ -636,6 +657,10 @@ INPUT_SRC += src/input/curl_input_plugin.c \
src/icy_metadata.c src/icy_metadata.c
endif endif
if ENABLE_CDIO_PARANOIA
INPUT_SRC += src/input/cdio_paranoia_input_plugin.c
endif
if HAVE_FFMPEG if HAVE_FFMPEG
INPUT_SRC += src/input/ffmpeg_input_plugin.c INPUT_SRC += src/input/ffmpeg_input_plugin.c
endif endif
...@@ -644,6 +669,10 @@ if ENABLE_MMS ...@@ -644,6 +669,10 @@ if ENABLE_MMS
INPUT_SRC += src/input/mms_input_plugin.c INPUT_SRC += src/input/mms_input_plugin.c
endif endif
if ENABLE_DESPOTIFY
INPUT_SRC += src/input/despotify_input_plugin.c
endif
OUTPUT_CFLAGS = \ OUTPUT_CFLAGS = \
$(AO_CFLAGS) \ $(AO_CFLAGS) \
...@@ -658,6 +687,7 @@ OUTPUT_LIBS = \ ...@@ -658,6 +687,7 @@ OUTPUT_LIBS = \
$(LIBWRAP_LDFLAGS) \ $(LIBWRAP_LDFLAGS) \
$(AO_LIBS) \ $(AO_LIBS) \
$(ALSA_LIBS) \ $(ALSA_LIBS) \
$(ROAR_LIBS) \
$(FFADO_LIBS) \ $(FFADO_LIBS) \
$(JACK_LIBS) \ $(JACK_LIBS) \
$(OPENAL_LIBS) \ $(OPENAL_LIBS) \
...@@ -691,6 +721,11 @@ OUTPUT_SRC += src/output/alsa_plugin.c ...@@ -691,6 +721,11 @@ OUTPUT_SRC += src/output/alsa_plugin.c
MIXER_SRC += src/mixer/alsa_mixer_plugin.c MIXER_SRC += src/mixer/alsa_mixer_plugin.c
endif endif
if HAVE_ROAR
OUTPUT_SRC += src/output/roar_plugin.c
MIXER_SRC += src/mixer/roar_mixer_plugin.c
endif
if ENABLE_FFADO_OUTPUT if ENABLE_FFADO_OUTPUT
OUTPUT_SRC += src/output/ffado_output_plugin.c OUTPUT_SRC += src/output/ffado_output_plugin.c
endif endif
...@@ -728,6 +763,11 @@ if HAVE_OSX ...@@ -728,6 +763,11 @@ if HAVE_OSX
OUTPUT_SRC += src/output/osx_plugin.c OUTPUT_SRC += src/output/osx_plugin.c
endif 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 if HAVE_PULSE
OUTPUT_SRC += src/output/pulse_output_plugin.c OUTPUT_SRC += src/output/pulse_output_plugin.c
MIXER_SRC += src/mixer/pulse_mixer_plugin.c MIXER_SRC += src/mixer/pulse_mixer_plugin.c
...@@ -775,6 +815,10 @@ if ENABLE_LASTFM ...@@ -775,6 +815,10 @@ if ENABLE_LASTFM
PLAYLIST_SRC += src/playlist/lastfm_playlist_plugin.c PLAYLIST_SRC += src/playlist/lastfm_playlist_plugin.c
endif endif
if ENABLE_DESPOTIFY
PLAYLIST_SRC += src/playlist/despotify_playlist_plugin.c
endif
if HAVE_CUE if HAVE_CUE
PLAYLIST_SRC += src/playlist/cue_playlist_plugin.c PLAYLIST_SRC += src/playlist/cue_playlist_plugin.c
endif endif
...@@ -825,9 +869,13 @@ sparse-check: ...@@ -825,9 +869,13 @@ sparse-check:
if ENABLE_TEST if ENABLE_TEST
TESTS = C_TESTS = \
test/test_queue_priority
TESTS = $(C_TESTS)
noinst_PROGRAMS = \ noinst_PROGRAMS = \
$(C_TESTS) \
test/read_conf \ test/read_conf \
test/run_input \ test/run_input \
test/dump_playlist \ test/dump_playlist \
...@@ -849,7 +897,7 @@ test_read_conf_CPPFLAGS = $(AM_CPPFLAGS) \ ...@@ -849,7 +897,7 @@ test_read_conf_CPPFLAGS = $(AM_CPPFLAGS) \
test_read_conf_LDADD = $(MPD_LIBS) \ test_read_conf_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_read_conf_SOURCES = test/read_conf.c \ 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) \ test_run_input_CPPFLAGS = $(AM_CPPFLAGS) \
$(ARCHIVE_CFLAGS) \ $(ARCHIVE_CFLAGS) \
...@@ -860,7 +908,7 @@ test_run_input_LDADD = $(MPD_LIBS) \ ...@@ -860,7 +908,7 @@ test_run_input_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_run_input_SOURCES = test/run_input.c \ test_run_input_SOURCES = test/run_input.c \
test/stdbin.h \ 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/tag.c src/tag_pool.c src/tag_save.c \
src/fd_util.c \ src/fd_util.c \
$(ARCHIVE_SRC) \ $(ARCHIVE_SRC) \
...@@ -878,7 +926,7 @@ test_dump_playlist_LDADD = $(MPD_LIBS) \ ...@@ -878,7 +926,7 @@ test_dump_playlist_LDADD = $(MPD_LIBS) \
$(INPUT_LIBS) \ $(INPUT_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_dump_playlist_SOURCES = test/dump_playlist.c \ 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/uri.c \
src/song.c src/tag.c src/tag_pool.c src/tag_save.c \ src/song.c src/tag.c src/tag_pool.c src/tag_save.c \
src/text_input_stream.c src/fifo_buffer.c \ src/text_input_stream.c src/fifo_buffer.c \
...@@ -908,7 +956,7 @@ test_run_decoder_LDADD = $(MPD_LIBS) \ ...@@ -908,7 +956,7 @@ test_run_decoder_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_run_decoder_SOURCES = test/run_decoder.c \ test_run_decoder_SOURCES = test/run_decoder.c \
test/stdbin.h \ 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/tag.c src/tag_pool.c \
src/replay_gain_info.c \ src/replay_gain_info.c \
src/uri.c \ src/uri.c \
...@@ -931,7 +979,7 @@ test_read_tags_LDADD = $(MPD_LIBS) \ ...@@ -931,7 +979,7 @@ test_read_tags_LDADD = $(MPD_LIBS) \
$(INPUT_LIBS) $(DECODER_LIBS) \ $(INPUT_LIBS) $(DECODER_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_read_tags_SOURCES = test/read_tags.c \ 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/tag.c src/tag_pool.c \
src/replay_gain_info.c \ src/replay_gain_info.c \
src/uri.c \ src/uri.c \
...@@ -951,7 +999,7 @@ test_run_filter_SOURCES = test/run_filter.c \ ...@@ -951,7 +999,7 @@ test_run_filter_SOURCES = test/run_filter.c \
test/stdbin.h \ test/stdbin.h \
src/filter_plugin.c \ src/filter_plugin.c \
src/filter_registry.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_volume.c src/pcm_convert.c src/pcm_byteswap.c \
src/pcm_format.c src/pcm_channels.c src/pcm_dither.c \ src/pcm_format.c src/pcm_channels.c src/pcm_dither.c \
src/pcm_pack.c \ src/pcm_pack.c \
...@@ -968,12 +1016,23 @@ if HAVE_LIBSAMPLERATE ...@@ -968,12 +1016,23 @@ if HAVE_LIBSAMPLERATE
test_run_filter_SOURCES += src/pcm_resample_libsamplerate.c test_run_filter_SOURCES += src/pcm_resample_libsamplerate.c
endif 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 if ENABLE_ENCODER
noinst_PROGRAMS += test/run_encoder noinst_PROGRAMS += test/run_encoder
test_run_encoder_SOURCES = test/run_encoder.c \ test_run_encoder_SOURCES = test/run_encoder.c \
test/stdbin.h \ test/stdbin.h \
src/conf.c src/tokenizer.c \ src/conf.c src/tokenizer.c \
src/utils.c \ src/utils.c src/string_util.c \
src/tag.c src/tag_pool.c \ src/tag.c src/tag_pool.c \
src/audio_check.c \ src/audio_check.c \
src/audio_format.c \ src/audio_format.c \
...@@ -1034,7 +1093,7 @@ test_run_output_LDADD = $(MPD_LIBS) \ ...@@ -1034,7 +1093,7 @@ test_run_output_LDADD = $(MPD_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_run_output_SOURCES = test/run_output.c \ test_run_output_SOURCES = test/run_output.c \
test/stdbin.h \ 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_check.c \
src/audio_format.c \ src/audio_format.c \
src/audio_parser.c \ src/audio_parser.c \
...@@ -1070,7 +1129,7 @@ test_read_mixer_LDADD = $(MPD_LIBS) \ ...@@ -1070,7 +1129,7 @@ test_read_mixer_LDADD = $(MPD_LIBS) \
$(OUTPUT_LIBS) \ $(OUTPUT_LIBS) \
$(GLIB_LIBS) $(GLIB_LIBS)
test_read_mixer_SOURCES = test/read_mixer.c \ 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/mixer_control.c src/mixer_api.c \
src/filter_plugin.c \ src/filter_plugin.c \
src/filter/volume_filter_plugin.c \ src/filter/volume_filter_plugin.c \
...@@ -1098,6 +1157,12 @@ test_run_inotify_SOURCES = test/run_inotify.c \ ...@@ -1098,6 +1157,12 @@ test_run_inotify_SOURCES = test/run_inotify.c \
test_run_inotify_LDADD = $(GLIB_LIBS) test_run_inotify_LDADD = $(GLIB_LIBS)
endif endif
test_test_queue_priority_SOURCES = \
src/queue.c \
test/test_queue_priority.c
test_test_queue_priority_LDADD = \
$(GLIB_LIBS)
endif endif
...@@ -1135,8 +1200,7 @@ endif ...@@ -1135,8 +1200,7 @@ endif
doc/api/html/index.html: doc/doxygen.conf doc/api/html/index.html: doc/doxygen.conf
@mkdir -p $(@D) @mkdir -p $(@D)
[ "$(srcdir)" = "." ] || sed '/INPUT *=/ s/\([^ ]\+\/\)/$(subst /,\/,$(srcdir))\/\1/g' $(srcdir)/doc/doxygen.conf >doc/doxygen.conf $(DOXYGEN) $<
$(DOXYGEN) doc/doxygen.conf
all-local: $(DOCBOOK_HTML) doc/api/html/index.html 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: * decoder:
- tremor: fix configure test - tremor: fix configure test
- gme: detect end of song - gme: detect end of song
* encoder:
- vorbis: reset the Ogg stream after flush
* output: * output:
- httpd: fix uninitialized variable - httpd: fix uninitialized variable
- httpd: include sys/socket.h
- oss: AFMT_S24_PACKED is little-endian - oss: AFMT_S24_PACKED is little-endian
- oss: disable 24 bit playback on FreeBSD - oss: disable 24 bit playback on FreeBSD
...@@ -138,9 +187,20 @@ ver 0.16 (2010/12/11) ...@@ -138,9 +187,20 @@ ver 0.16 (2010/12/11)
* make single mode 'sticky' * 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: * encoders:
- lame: explicitly configure the output sample rate - lame: explicitly configure the output sample rate
* update: log all file permission problems
ver 0.15.15 (2010/11/08) ver 0.15.15 (2010/11/08)
......
AC_PREREQ(2.60) 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]) AC_CONFIG_SRCDIR([src/main.c])
AM_INIT_AUTOMAKE([foreign 1.10 dist-bzip2 subdir-objects]) AM_INIT_AUTOMAKE([foreign 1.10 dist-bzip2 subdir-objects])
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
AC_CONFIG_MACRO_DIR([m4]) 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 --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
...@@ -121,6 +121,11 @@ AC_ARG_ENABLE(alsa, ...@@ -121,6 +121,11 @@ AC_ARG_ENABLE(alsa,
AS_HELP_STRING([--enable-alsa], [enable ALSA support]),, AS_HELP_STRING([--enable-alsa], [enable ALSA support]),,
[enable_alsa=auto]) [enable_alsa=auto])
AC_ARG_ENABLE(roar,
AS_HELP_STRING([--enable-roar],
[enable support for RoarAudio]),,
[enable_roar=auto])
AC_ARG_ENABLE(ao, AC_ARG_ENABLE(ao,
AS_HELP_STRING([--enable-ao], AS_HELP_STRING([--enable-ao],
[enable support for libao]),, [enable support for libao]),,
...@@ -136,6 +141,11 @@ AC_ARG_ENABLE(bzip2, ...@@ -136,6 +141,11 @@ AC_ARG_ENABLE(bzip2,
[enable bzip2 archive support (default: disabled)]),, [enable bzip2 archive support (default: disabled)]),,
enable_bzip2=no) 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, AC_ARG_ENABLE(cue,
AS_HELP_STRING([--enable-cue], AS_HELP_STRING([--enable-cue],
[enable support for libcue support]),, [enable support for libcue support]),,
...@@ -195,6 +205,11 @@ AC_ARG_ENABLE(httpd-output, ...@@ -195,6 +205,11 @@ AC_ARG_ENABLE(httpd-output,
[enables the HTTP server output]),, [enables the HTTP server output]),,
[enable_httpd_output=auto]) [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, AC_ARG_ENABLE(id3,
AS_HELP_STRING([--disable-id3], AS_HELP_STRING([--disable-id3],
[disable id3 support (default: enable)]),, [disable id3 support (default: enable)]),,
...@@ -227,6 +242,11 @@ AC_ARG_ENABLE(lastfm, ...@@ -227,6 +242,11 @@ AC_ARG_ENABLE(lastfm,
[enable support for last.fm radio (default: disable)]),, [enable support for last.fm radio (default: disable)]),,
[enable_lastfm=no]) [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, AC_ARG_ENABLE(lame-encoder,
AS_HELP_STRING([--enable-lame-encoder], AS_HELP_STRING([--enable-lame-encoder],
[enable the LAME mp3 encoder]),, [enable the LAME mp3 encoder]),,
...@@ -537,15 +557,16 @@ no|avahi|bonjour) ...@@ -537,15 +557,16 @@ no|avahi|bonjour)
;; ;;
esac esac
enable_avahi=no
enable_bounjour=no
if test x$with_zeroconf != xno; then if test x$with_zeroconf != xno; then
if test x$with_zeroconf = xavahi || test x$with_zeroconf = xauto; then if test x$with_zeroconf = xavahi || test x$with_zeroconf = xauto; then
PKG_CHECK_MODULES([AVAHI], [avahi-client avahi-glib], PKG_CHECK_MODULES([AVAHI], [avahi-client avahi-glib],
[found_avahi=1;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])] [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", MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS")
[found_avahi=0])
fi fi
if test x$found_avahi = x1; then if test x$enable_avahi = xyes; then
with_zeroconf=avahi with_zeroconf=avahi
elif test x$with_zeroconf = xavahi; then elif test x$with_zeroconf = xavahi; then
AC_MSG_ERROR([Avahi support requested but not found]) AC_MSG_ERROR([Avahi support requested but not found])
...@@ -553,13 +574,12 @@ if test x$with_zeroconf != xno; then ...@@ -553,13 +574,12 @@ if test x$with_zeroconf != xno; then
if test x$with_zeroconf = xbonjour || test x$with_zeroconf = xauto; then if test x$with_zeroconf = xbonjour || test x$with_zeroconf = xauto; then
AC_CHECK_HEADER(dns_sd.h, AC_CHECK_HEADER(dns_sd.h,
[found_bonjour=1;AC_DEFINE([HAVE_BONJOUR], 1, [Define to enable Bonjour Zeroconf support])], [enable_bonjour=yes;AC_DEFINE([HAVE_BONJOUR], 1, [Define to enable Bonjour Zeroconf support])])
[found_bonjour=0])
AC_CHECK_LIB(dns_sd, DNSServiceRegister, AC_CHECK_LIB(dns_sd, DNSServiceRegister,
MPD_LIBS="$MPD_LIBS -ldns_sd") MPD_LIBS="$MPD_LIBS -ldns_sd")
fi fi
if test x$found_bonjour = x1; then if test x$enable_bonjour = xyes; then
with_zeroconf=bonjour with_zeroconf=bonjour
elif test x$with_zeroconf = xbonjour; then elif test x$with_zeroconf = xbonjour; then
AC_MSG_ERROR([Bonjour support requested but not found]) AC_MSG_ERROR([Bonjour support requested but not found])
...@@ -634,8 +654,27 @@ if test x$enable_lastfm = xyes; then ...@@ -634,8 +654,27 @@ if test x$enable_lastfm = xyes; then
fi fi
AM_CONDITIONAL(ENABLE_LASTFM, test x$enable_lastfm = xyes) 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 --------------------------------- 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) PKG_CHECK_MODULES(OGG, [ogg], enable_ogg=yes, enable_ogg=no)
fi fi
...@@ -732,21 +771,10 @@ AM_CONDITIONAL(HAVE_FAAD, test x$enable_aac = xyes) ...@@ -732,21 +771,10 @@ AM_CONDITIONAL(HAVE_FAAD, test x$enable_aac = xyes)
AM_CONDITIONAL(HAVE_MP4, test x$enable_mp4 = xyes) AM_CONDITIONAL(HAVE_MP4, test x$enable_mp4 = xyes)
dnl ---------------------------------- ffmpeg --------------------------------- 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]) [ffmpeg decoder library], [libavformat+libavcodec+libavutil not found])
if test x$enable_ffmpeg = xyes; then 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]) AC_DEFINE(HAVE_FFMPEG, 1, [Define for FFMPEG support])
fi fi
...@@ -1081,7 +1109,7 @@ if ...@@ -1081,7 +1109,7 @@ if
fi fi
AM_CONDITIONAL(HAVE_OGG_COMMON, 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, AM_CONDITIONAL(HAVE_FLAC_COMMON,
test x$enable_flac = xyes || test x$enable_oggflac = xyes) test x$enable_flac = xyes || test x$enable_oggflac = xyes)
...@@ -1207,6 +1235,16 @@ fi ...@@ -1207,6 +1235,16 @@ fi
AM_CONDITIONAL(HAVE_ALSA, test x$enable_alsa = xyes) 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 --------------------------------- dnl ----------------------------------- FFADO ---------------------------------
MPD_AUTO_PKG(ffado, FFADO, [libffado], MPD_AUTO_PKG(ffado, FFADO, [libffado],
...@@ -1317,7 +1355,7 @@ enable_osx=no ...@@ -1317,7 +1355,7 @@ enable_osx=no
case "$host_os" in case "$host_os" in
darwin*) darwin*)
AC_DEFINE(HAVE_OSX, 1, [Define for compiling OS X support]) 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 ;; enable_osx=yes ;;
esac esac
...@@ -1388,6 +1426,15 @@ esac ...@@ -1388,6 +1426,15 @@ esac
AM_CONDITIONAL(ENABLE_SOLARIS_OUTPUT, test x$enable_solaris_output = xyes) 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 --------------------------------- dnl --------------------------------- WinMM ---------------------------------
case "$host_os" in case "$host_os" in
...@@ -1407,6 +1454,7 @@ AM_CONDITIONAL(ENABLE_WINMM_OUTPUT, test x$enable_winmm_output = xyes) ...@@ -1407,6 +1454,7 @@ AM_CONDITIONAL(ENABLE_WINMM_OUTPUT, test x$enable_winmm_output = xyes)
dnl --------------------- Post Audio Output Plugins Tests --------------------- dnl --------------------- Post Audio Output Plugins Tests ---------------------
if if
test x$enable_alsa = xno && test x$enable_alsa = xno &&
test x$enable_roar = xno &&
test x$enable_ao = xno && test x$enable_ao = xno &&
test x$enable_ffado = xno && test x$enable_ffado = xno &&
test x$enable_fifo = xno && test x$enable_fifo = xno &&
...@@ -1416,6 +1464,7 @@ if ...@@ -1416,6 +1464,7 @@ if
test x$enable_openal = xno && test x$enable_openal = xno &&
test x$enable_oss = xno && test x$enable_oss = xno &&
test x$enable_osx = xno && test x$enable_osx = xno &&
test x$enable_raop_output = xno &&
test x$enable_pipe_output = xno && test x$enable_pipe_output = xno &&
test x$enable_pulse = xno && test x$enable_pulse = xno &&
test x$enable_recorder_output = xno && test x$enable_recorder_output = xno &&
...@@ -1466,7 +1515,6 @@ if test x$GCC = xyes ...@@ -1466,7 +1515,6 @@ if test x$GCC = xyes
then then
MPD_CHECK_FLAG([-Wall]) MPD_CHECK_FLAG([-Wall])
MPD_CHECK_FLAG([-Wextra]) MPD_CHECK_FLAG([-Wextra])
MPD_CHECK_FLAG([-Wno-deprecated-declarations])
MPD_CHECK_FLAG([-Wmissing-prototypes]) MPD_CHECK_FLAG([-Wmissing-prototypes])
MPD_CHECK_FLAG([-Wshadow]) MPD_CHECK_FLAG([-Wshadow])
MPD_CHECK_FLAG([-Wpointer-arith]) MPD_CHECK_FLAG([-Wpointer-arith])
...@@ -1543,10 +1591,12 @@ results(id3,[ID3]) ...@@ -1543,10 +1591,12 @@ results(id3,[ID3])
printf '\nPlayback support:\n\t' printf '\nPlayback support:\n\t'
results(alsa,ALSA) results(alsa,ALSA)
results(roar,ROAR)
results(ffado,FFADO) results(ffado,FFADO)
results(fifo,FIFO) results(fifo,FIFO)
results(recorder_output,[File Recorder]) results(recorder_output,[File Recorder])
results(httpd_output,[HTTP Daemon]) results(httpd_output,[HTTP Daemon])
results(raop_output, [RAOP])
results(jack,[JACK]) results(jack,[JACK])
results(ao,[libao]) results(ao,[libao])
results(oss,[OSS]) results(oss,[OSS])
...@@ -1577,6 +1627,8 @@ printf '\nStreaming support:\n\t' ...@@ -1577,6 +1627,8 @@ printf '\nStreaming support:\n\t'
results(curl,[CURL]) results(curl,[CURL])
results(lastfm,[Last.FM]) results(lastfm,[Last.FM])
results(mms,[MMS]) results(mms,[MMS])
results(cdio_paranoia, [CDIO_PARANOIA])
results(despotify,[Despotify])
printf '\n\n##########################################\n\n' printf '\n\n##########################################\n\n'
...@@ -1586,5 +1638,6 @@ dnl --------------------------------------------------------------------------- ...@@ -1586,5 +1638,6 @@ dnl ---------------------------------------------------------------------------
dnl Generate files dnl Generate files
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
AC_OUTPUT(Makefile) AC_OUTPUT(Makefile)
AC_OUTPUT(doc/doxygen.conf)
echo 'MPD is ready for compilation, type "make" to begin.' echo 'MPD is ready for compilation, type "make" to begin.'
...@@ -31,7 +31,7 @@ PROJECT_NAME = MPD ...@@ -31,7 +31,7 @@ PROJECT_NAME = MPD
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = PROJECT_NUMBER = @VERSION@
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.
...@@ -534,7 +534,7 @@ WARN_LOGFILE = ...@@ -534,7 +534,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = src/ INPUT = @top_srcdir@/src/
# This tag can be used to specify the character encoding of the source files # 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 # 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 ...@@ -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 the "kill" command. When mpd is restarted, it will read the state file and
restore the state of mpd (including the playlist). restore the state of mpd (including the playlist).
.TP .TP
.B restore_paused <yes or no>
Put MPD into pause mode instead of starting playback after startup.
.TP
.B user <username> .B user <username>
This specifies the user that MPD will run as, if set. MPD should 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 never run as root, and you may use this option to make MPD change its
...@@ -259,6 +262,17 @@ of database. ...@@ -259,6 +262,17 @@ of database.
.B auto_update_depth <N> .B auto_update_depth <N>
Limit the depth of the directories being watched, 0 means only watch Limit the depth of the directories being watched, 0 means only watch
the music directory itself. There is no limit by default. 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 .SH REQUIRED AUDIO OUTPUT PARAMETERS
.TP .TP
.B type <type> .B type <type>
...@@ -464,6 +478,9 @@ connect to the icecast server. The default is 2 seconds. ...@@ -464,6 +478,9 @@ connect to the icecast server. The default is 2 seconds.
.B description <description> .B description <description>
This specifies a description of the stream. This specifies a description of the stream.
.TP .TP
.B url <url>
This specifies a URL associated with the stream.
.TP
.B genre <genre> .B genre <genre>
This specifies the genre(s) of the stream. This specifies the genre(s) of the stream.
.SH FILES .SH FILES
......
...@@ -103,6 +103,11 @@ ...@@ -103,6 +103,11 @@
# #
#gapless_mp3_playback "yes" #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 # This setting enables MPD to create playlists in a format usable by other
# music players. # music players.
# #
...@@ -235,6 +240,7 @@ input { ...@@ -235,6 +240,7 @@ input {
## protocol "icecast2" # optional ## protocol "icecast2" # optional
## user "source" # optional ## user "source" # optional
## description "My Stream Description" # optional ## description "My Stream Description" # optional
## url "http://example.com" # optional
## genre "jazz" # optional ## genre "jazz" # optional
## public "no" # optional ## public "no" # optional
## timeout "2" # optional ## timeout "2" # optional
......
...@@ -236,6 +236,16 @@ cd mpd-version</programlisting> ...@@ -236,6 +236,16 @@ cd mpd-version</programlisting>
</section> </section>
<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> <title>Configuring audio outputs</title>
<para> <para>
...@@ -346,7 +356,7 @@ cd mpd-version</programlisting> ...@@ -346,7 +356,7 @@ cd mpd-version</programlisting>
If set to "yes", then MPD attempts to keep this audio If set to "yes", then MPD attempts to keep this audio
output always open. This may be useful for streaming output always open. This may be useful for streaming
servers, when you don't want to disconnect all servers, when you don't want to disconnect all
listeners even when playback is accidently stopped. listeners even when playback is accidentally stopped.
</entry> </entry>
</row> </row>
<row> <row>
...@@ -446,7 +456,7 @@ cd mpd-version</programlisting> ...@@ -446,7 +456,7 @@ cd mpd-version</programlisting>
</para> </para>
<para> <para>
To configure a filter, add a To configure a playlist plugin, add a
<varname>playlist_plugin</varname> block to <varname>playlist_plugin</varname> block to
<filename>mpd.conf</filename>: <filename>mpd.conf</filename>:
</para> </para>
...@@ -621,6 +631,78 @@ cd mpd-version</programlisting> ...@@ -621,6 +631,78 @@ cd mpd-version</programlisting>
Plays streams with the MMS protocol. Plays streams with the MMS protocol.
</para> </para>
</section> </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>
<section> <section>
...@@ -658,6 +740,178 @@ cd mpd-version</programlisting> ...@@ -658,6 +740,178 @@ cd mpd-version</programlisting>
</section> </section>
<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> <title>Output plugins</title>
<section> <section>
...@@ -1366,6 +1620,15 @@ cd mpd-version</programlisting> ...@@ -1366,6 +1620,15 @@ cd mpd-version</programlisting>
</row> </row>
<row> <row>
<entry> <entry>
<varname>url</varname>
<parameter>URL</parameter>
</entry>
<entry>
Sets a URL associated with the stream (optional).
</entry>
</row>
<row>
<entry>
<varname>public</varname> <varname>public</varname>
<parameter>yes|no</parameter> <parameter>yes|no</parameter>
</entry> </entry>
...@@ -1498,6 +1761,27 @@ cd mpd-version</programlisting> ...@@ -1498,6 +1761,27 @@ cd mpd-version</programlisting>
playlist files. playlist files.
</para> </para>
</section> </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> </section>
</chapter> </chapter>
</book> </book>
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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) ...@@ -60,8 +60,10 @@ ape_scan_internal(FILE *fp, tag_ape_callback_t callback, void *ctx)
assert(remaining > 10); assert(remaining > 10);
char *buffer = g_malloc(remaining); char *buffer = g_malloc(remaining);
if (fread(buffer, 1, remaining, fp) != remaining) if (fread(buffer, 1, remaining, fp) != remaining) {
g_free(buffer);
return false; return false;
}
/* read tags */ /* read tags */
unsigned n = GUINT32_FROM_LE(footer.count); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "config.h" #include "config.h"
#include "archive_list.h" #include "archive_list.h"
#include "archive_plugin.h" #include "archive_plugin.h"
#include "utils.h" #include "string_util.h"
#include "archive/bz2_archive_plugin.h" #include "archive/bz2_archive_plugin.h"
#include "archive/iso9660_archive_plugin.h" #include "archive/iso9660_archive_plugin.h"
#include "archive/zzip_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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -68,7 +68,7 @@ struct archive_plugin { ...@@ -68,7 +68,7 @@ struct archive_plugin {
* Opens an input_stream of a file within the archive. * Opens an input_stream of a file within the archive.
* *
* @param path the path 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 * NULL to ignore errors
*/ */
struct input_stream *(*open_stream)(struct archive_file *af, 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
enum sample_format { enum sample_format {
SAMPLE_FORMAT_UNDEFINED = 0, SAMPLE_FORMAT_UNDEFINED = 0,
...@@ -219,6 +220,9 @@ static inline void ...@@ -219,6 +220,9 @@ static inline void
audio_format_mask_apply(struct audio_format *af, audio_format_mask_apply(struct audio_format *af,
const struct audio_format *mask) const struct audio_format *mask)
{ {
assert(audio_format_valid(af));
assert(audio_format_mask_valid(mask));
if (mask->sample_rate != 0) if (mask->sample_rate != 0)
af->sample_rate = mask->sample_rate; af->sample_rate = mask->sample_rate;
...@@ -227,6 +231,8 @@ audio_format_mask_apply(struct audio_format *af, ...@@ -227,6 +231,8 @@ audio_format_mask_apply(struct audio_format *af,
if (mask->channels != 0) if (mask->channels != 0)
af->channels = mask->channels; 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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, ...@@ -192,6 +192,8 @@ audio_format_parse(struct audio_format *dest, const char *src,
} }
audio_format_init(dest, rate, sample_format, channels); audio_format_init(dest, rate, sample_format, channels);
assert(mask ? audio_format_mask_valid(dest)
: audio_format_valid(dest));
return true; return true;
} }
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -38,7 +38,7 @@ struct audio_format; ...@@ -38,7 +38,7 @@ struct audio_format;
* @param dest the destination #audio_format struct * @param dest the destination #audio_format struct
* @param src the input string * @param src the input string
* @param mask if true, then "*" is allowed for any number of items * @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 * ignore errors
* @return true on success * @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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -27,11 +27,13 @@ ...@@ -27,11 +27,13 @@
struct client; struct client;
struct sockaddr; struct sockaddr;
struct player_control;
void client_manager_init(void); void client_manager_init(void);
void client_manager_deinit(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); bool client_is_expired(const struct client *client);
...@@ -60,17 +62,4 @@ void client_vprintf(struct client *client, const char *fmt, va_list args); ...@@ -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, ...); 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 #endif
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include "config.h" #include "config.h"
#include "client_idle.h"
#include "client_internal.h" #include "client_internal.h"
#include "idle.h" #include "idle.h"
...@@ -50,12 +51,9 @@ client_idle_notify(struct client *client) ...@@ -50,12 +51,9 @@ client_idle_notify(struct client *client)
g_timer_start(client->last_activity); g_timer_start(client->last_activity);
} }
static void void
client_idle_callback(gpointer data, gpointer user_data) client_idle_add(struct client *client, unsigned flags)
{ {
struct client *client = data;
unsigned flags = GPOINTER_TO_UINT(user_data);
if (client_is_expired(client)) if (client_is_expired(client))
return; return;
...@@ -67,6 +65,15 @@ client_idle_callback(gpointer data, gpointer user_data) ...@@ -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) void client_manager_idle_add(unsigned flags)
{ {
assert(flags != 0); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -21,17 +21,25 @@ ...@@ -21,17 +21,25 @@
#define MPD_CLIENT_INTERNAL_H #define MPD_CLIENT_INTERNAL_H
#include "client.h" #include "client.h"
#include "client_message.h"
#include "command.h" #include "command.h"
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "client" #define G_LOG_DOMAIN "client"
enum {
CLIENT_MAX_SUBSCRIPTIONS = 16,
CLIENT_MAX_MESSAGES = 64,
};
struct deferred_buffer { struct deferred_buffer {
size_t size; size_t size;
char data[sizeof(long)]; char data[sizeof(long)];
}; };
struct client { struct client {
struct player_control *player_control;
GIOChannel *channel; GIOChannel *channel;
guint source_id; guint source_id;
...@@ -67,6 +75,28 @@ struct client { ...@@ -67,6 +75,28 @@ struct client {
/** idle flags that the client wants to receive */ /** idle flags that the client wants to receive */
unsigned idle_subscriptions; 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; 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -41,12 +41,15 @@ ...@@ -41,12 +41,15 @@
static const char GREETING[] = "OK MPD " PROTOCOL_VERSION "\n"; 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; static unsigned int next_client_num;
struct client *client; struct client *client;
char *remote; char *remote;
assert(player_control != NULL);
assert(fd >= 0); assert(fd >= 0);
#ifdef HAVE_LIBWRAP #ifdef HAVE_LIBWRAP
...@@ -81,6 +84,7 @@ void client_new(int fd, const struct sockaddr *sa, size_t sa_length, int uid) ...@@ -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 = g_new0(struct client, 1);
client->player_control = player_control;
#ifndef G_OS_WIN32 #ifndef G_OS_WIN32
client->channel = g_io_channel_unix_new(fd); 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) ...@@ -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->send_buf_used = 0;
client->subscriptions = NULL;
client->messages = NULL;
client->num_messages = 0;
(void)send(fd, GREETING, sizeof(GREETING) - 1, 0); (void)send(fd, GREETING, sizeof(GREETING) - 1, 0);
client_list_add(client); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -79,7 +79,7 @@ static void version(void) ...@@ -79,7 +79,7 @@ static void version(void)
puts(PACKAGE " (MPD: Music Player Daemon) " VERSION " \n" puts(PACKAGE " (MPD: Music Player Daemon) " VERSION " \n"
"\n" "\n"
"Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>\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" "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" "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n" "\n"
......
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "conf.h" #include "conf.h"
#include "utils.h" #include "utils.h"
#include "string_util.h"
#include "tokenizer.h" #include "tokenizer.h"
#include "path.h" #include "path.h"
#include "glib_compat.h" #include "glib_compat.h"
...@@ -58,6 +59,7 @@ static struct config_entry config_entries[] = { ...@@ -58,6 +59,7 @@ static struct config_entry config_entries[] = {
{ .name = CONF_LOG_FILE, false, false }, { .name = CONF_LOG_FILE, false, false },
{ .name = CONF_PID_FILE, false, false }, { .name = CONF_PID_FILE, false, false },
{ .name = CONF_STATE_FILE, false, false }, { .name = CONF_STATE_FILE, false, false },
{ .name = "restore_paused", false, false },
{ .name = CONF_USER, false, false }, { .name = CONF_USER, false, false },
{ .name = CONF_GROUP, false, false }, { .name = CONF_GROUP, false, false },
{ .name = CONF_BIND_TO_ADDRESS, true, false }, { .name = CONF_BIND_TO_ADDRESS, true, false },
...@@ -97,6 +99,9 @@ static struct config_entry config_entries[] = { ...@@ -97,6 +99,9 @@ static struct config_entry config_entries[] = {
{ .name = CONF_PLAYLIST_PLUGIN, true, true }, { .name = CONF_PLAYLIST_PLUGIN, true, true },
{ .name = CONF_AUTO_UPDATE, false, false }, { .name = CONF_AUTO_UPDATE, false, false },
{ .name = CONF_AUTO_UPDATE_DEPTH, 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 }, { .name = "filter", true, true },
}; };
...@@ -269,7 +274,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r) ...@@ -269,7 +274,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
} }
(*count)++; (*count)++;
line = g_strchug(line); line = strchug_fast(line);
if (*line == 0 || *line == CONF_COMMENT) if (*line == 0 || *line == CONF_COMMENT)
continue; continue;
...@@ -277,7 +282,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r) ...@@ -277,7 +282,7 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r)
/* end of this block; return from the function /* end of this block; return from the function
(and from this "while" loop) */ (and from this "while" loop) */
line = g_strchug(line + 1); line = strchug_fast(line + 1);
if (*line != 0 && *line != CONF_COMMENT) { if (*line != 0 && *line != CONF_COMMENT) {
config_param_free(ret); config_param_free(ret);
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
...@@ -355,7 +360,7 @@ config_read_file(const char *file, GError **error_r) ...@@ -355,7 +360,7 @@ config_read_file(const char *file, GError **error_r)
count++; count++;
line = g_strchug(string); line = strchug_fast(string);
if (*line == 0 || *line == CONF_COMMENT) if (*line == 0 || *line == CONF_COMMENT)
continue; continue;
...@@ -367,6 +372,7 @@ config_read_file(const char *file, GError **error_r) ...@@ -367,6 +372,7 @@ config_read_file(const char *file, GError **error_r)
assert(*line != 0); assert(*line != 0);
g_propagate_prefixed_error(error_r, error, g_propagate_prefixed_error(error_r, error,
"line %i: ", count); "line %i: ", count);
fclose(fp);
return false; return false;
} }
...@@ -378,6 +384,7 @@ config_read_file(const char *file, GError **error_r) ...@@ -378,6 +384,7 @@ config_read_file(const char *file, GError **error_r)
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
"unrecognized parameter in config file at " "unrecognized parameter in config file at "
"line %i: %s\n", count, name); "line %i: %s\n", count, name);
fclose(fp);
return false; return false;
} }
...@@ -387,6 +394,7 @@ config_read_file(const char *file, GError **error_r) ...@@ -387,6 +394,7 @@ config_read_file(const char *file, GError **error_r)
"config parameter \"%s\" is first defined " "config parameter \"%s\" is first defined "
"on line %i and redefined on line %i\n", "on line %i and redefined on line %i\n",
name, param->line, count); name, param->line, count);
fclose(fp);
return false; return false;
} }
...@@ -398,20 +406,24 @@ config_read_file(const char *file, GError **error_r) ...@@ -398,20 +406,24 @@ config_read_file(const char *file, GError **error_r)
if (*line != '{') { if (*line != '{') {
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
"line %i: '{' expected", count); "line %i: '{' expected", count);
fclose(fp);
return false; return false;
} }
line = g_strchug(line + 1); line = strchug_fast(line + 1);
if (*line != 0 && *line != CONF_COMMENT) { if (*line != 0 && *line != CONF_COMMENT) {
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
"line %i: Unknown tokens after '{'", "line %i: Unknown tokens after '{'",
count); count);
fclose(fp);
return false; return false;
} }
param = config_read_block(fp, &count, string, error_r); param = config_read_block(fp, &count, string, error_r);
if (param == NULL) if (param == NULL) {
fclose(fp);
return false; return false;
}
} else { } else {
/* a string value */ /* a string value */
...@@ -428,6 +440,7 @@ config_read_file(const char *file, GError **error_r) ...@@ -428,6 +440,7 @@ config_read_file(const char *file, GError **error_r)
g_error_free(error); g_error_free(error);
} }
fclose(fp);
return false; return false;
} }
...@@ -435,6 +448,7 @@ config_read_file(const char *file, GError **error_r) ...@@ -435,6 +448,7 @@ config_read_file(const char *file, GError **error_r)
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
"line %i: Unknown tokens after value", "line %i: Unknown tokens after value",
count); count);
fclose(fp);
return false; return false;
} }
......
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -72,6 +72,9 @@ ...@@ -72,6 +72,9 @@
#define CONF_PLAYLIST_PLUGIN "playlist_plugin" #define CONF_PLAYLIST_PLUGIN "playlist_plugin"
#define CONF_AUTO_UPDATE "auto_update" #define CONF_AUTO_UPDATE "auto_update"
#define CONF_AUTO_UPDATE_DEPTH "auto_update_depth" #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_MAX_LENGTH (1024*16)
#define DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS false #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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
......
...@@ -178,6 +178,15 @@ cue_tag(struct Cd *cd, unsigned tnum) ...@@ -178,6 +178,15 @@ cue_tag(struct Cd *cd, unsigned tnum)
if (tag == NULL) if (tag == NULL)
return 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) tag->time = track_get_length(track)
- track_get_index(track, 1) - track_get_index(track, 1)
+ track_get_zero_pre(track); + 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -80,7 +80,7 @@ daemonize_kill(void) ...@@ -80,7 +80,7 @@ daemonize_kill(void)
ret = kill(pid, SIGTERM); ret = kill(pid, SIGTERM);
if (ret < 0) if (ret < 0)
MPD_ERROR("unable to kill proccess %i: %s", MPD_ERROR("unable to kill process %i: %s",
pid, g_strerror(errno)); pid, g_strerror(errno));
exit(EXIT_SUCCESS); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -180,7 +180,7 @@ db_check(void) ...@@ -180,7 +180,7 @@ db_check(void)
} }
/* Check if we can write to the directory */ /* 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", g_warning("Can't create db file in \"%s\": %s",
dirPath, strerror(errno)); dirPath, strerror(errno));
g_free(dirPath); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "tag.h" #include "tag.h"
#include "strset.h" #include "strset.h"
#include "stored_playlist.h" #include "stored_playlist.h"
#include "client_internal.h"
#include <glib.h> #include <glib.h>
...@@ -166,9 +167,11 @@ int printAllIn(struct client *client, const char *name) ...@@ -166,9 +167,11 @@ int printAllIn(struct client *client, const char *name)
} }
static int 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 { struct add_data {
...@@ -185,9 +188,10 @@ directoryAddSongToStoredPlaylist(struct song *song, void *_data) ...@@ -185,9 +188,10 @@ directoryAddSongToStoredPlaylist(struct song *song, void *_data)
return 0; 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) int addAllInToStoredPlaylist(const char *name, const char *utf8file)
...@@ -205,7 +209,9 @@ findAddInDirectory(struct song *song, void *_data) ...@@ -205,7 +209,9 @@ findAddInDirectory(struct song *song, void *_data)
struct search_data *data = _data; struct search_data *data = _data;
if (locate_song_match(song, data->criteria)) 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; return 0;
} }
......
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -22,10 +22,12 @@ ...@@ -22,10 +22,12 @@
struct client; struct client;
struct locate_item_list; struct locate_item_list;
struct player_control;
int printAllIn(struct client *client, const char *name); 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); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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, ...@@ -81,7 +81,7 @@ flac_tell_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd,
struct flac_data *data = (struct flac_data *) fdata; struct flac_data *data = (struct flac_data *) fdata;
if (!data->input_stream->seekable) 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); *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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -224,7 +224,8 @@ flac_tag_apply_metadata(struct tag *tag, const char *track, ...@@ -224,7 +224,8 @@ flac_tag_apply_metadata(struct tag *tag, const char *track,
break; break;
case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_STREAMINFO:
tag->time = flac_duration(&block->data.stream_info); if (block->data.stream_info.sample_rate > 0)
tag->time = flac_duration(&block->data.stream_info);
break; break;
default: default:
......
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#ifndef MPD_FLAC_METADATA_H #ifndef MPD_FLAC_METADATA_H
#define MPD_FLAC_METADATA_H #define MPD_FLAC_METADATA_H
#include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <FLAC/metadata.h> #include <FLAC/metadata.h>
...@@ -29,6 +30,8 @@ struct replay_gain_info; ...@@ -29,6 +30,8 @@ struct replay_gain_info;
static inline unsigned static inline unsigned
flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info) flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
{ {
assert(stream_info->sample_rate > 0);
return (stream_info->total_samples + stream_info->sample_rate - 1) / return (stream_info->total_samples + stream_info->sample_rate - 1) /
stream_info->sample_rate; 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <glib.h> #include <glib.h>
#include <mpg123.h> #include <mpg123.h>
#include <stdio.h>
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "mpg123" #define G_LOG_DOMAIN "mpg123"
...@@ -105,6 +106,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -105,6 +106,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
int error; int error;
off_t num_samples; off_t num_samples;
enum decoder_command cmd; enum decoder_command cmd;
struct mpg123_frameinfo info;
/* open the file */ /* open the file */
...@@ -124,10 +126,25 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -124,10 +126,25 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
/* tell MPD core we're ready */ /* tell MPD core we're ready */
decoder_initialized(decoder, &audio_format, false, decoder_initialized(decoder, &audio_format, true,
(float)num_samples / (float)num_samples /
(float)audio_format.sample_rate); (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 */ /* the decoder main loop */
do { do {
...@@ -144,11 +161,30 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -144,11 +161,30 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
break; 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 */ /* 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); } while (cmd == DECODE_COMMAND_NONE);
/* cleanup */ /* cleanup */
......
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -34,9 +34,6 @@ ...@@ -34,9 +34,6 @@
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "wavpack" #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 #define ERRORLEN 80
static struct { static struct {
...@@ -162,8 +159,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek) ...@@ -162,8 +159,6 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
enum sample_format sample_format; enum sample_format sample_format;
struct audio_format audio_format; struct audio_format audio_format;
format_samples_t format_samples; format_samples_t format_samples;
char chunk[CHUNK_SIZE];
int samples_requested, samples_got;
float total_time; float total_time;
int bytes_per_sample, output_sample_size; int bytes_per_sample, output_sample_size;
...@@ -193,12 +188,15 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek) ...@@ -193,12 +188,15 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
output_sample_size = audio_format_frame_size(&audio_format); output_sample_size = audio_format_frame_size(&audio_format);
/* wavpack gives us all kind of samples in a 32-bit space */ /* 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); decoder_initialized(decoder, &audio_format, can_seek, total_time);
do { enum decoder_command cmd = decoder_get_command(decoder);
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) { while (cmd != DECODE_COMMAND_STOP) {
if (cmd == DECODE_COMMAND_SEEK) {
if (can_seek) { if (can_seek) {
unsigned where = decoder_seek_where(decoder) * unsigned where = decoder_seek_where(decoder) *
audio_format.sample_rate; audio_format.sample_rate;
...@@ -213,29 +211,20 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek) ...@@ -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; break;
}
samples_got = WavpackUnpackSamples( int bitrate = (int)(WavpackGetInstantBitrate(wpc) / 1000 +
wpc, (int32_t *)chunk, samples_requested 0.5);
); format_samples(bytes_per_sample, chunk,
if (samples_got > 0) { samples_got * audio_format.channels);
int bitrate = (int)(WavpackGetInstantBitrate(wpc) /
1000 + 0.5); cmd = decoder_data(decoder, NULL, chunk,
samples_got * output_sample_size,
format_samples( bitrate);
bytes_per_sample, chunk, }
samples_got * audio_format.channels
);
decoder_data(
decoder, NULL, chunk,
samples_got * output_sample_size,
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