Compare commits
112 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
49b9a90c3f | ||
![]() |
64d141f71e | ||
![]() |
c488d3123f | ||
![]() |
967af60327 | ||
![]() |
f1ef9f9d31 | ||
![]() |
dfaf08743c | ||
![]() |
d9552d8a6d | ||
![]() |
7586a8ab2c | ||
![]() |
e1a942250b | ||
![]() |
72be0185de | ||
![]() |
7e4cbce06b | ||
![]() |
177d62f431 | ||
![]() |
5a11e03725 | ||
![]() |
75d068b7cd | ||
![]() |
1208503888 | ||
![]() |
de90d401d2 | ||
![]() |
396defaea9 | ||
![]() |
18f350cd04 | ||
![]() |
478180ebe4 | ||
![]() |
4a3059f509 | ||
![]() |
78728138a0 | ||
![]() |
63fc98591d | ||
![]() |
53def9a682 | ||
![]() |
323231d1dd | ||
![]() |
714011c81e | ||
![]() |
952ff4207b | ||
![]() |
150b16ec2c | ||
![]() |
c98bc4a243 | ||
![]() |
014f8cd693 | ||
![]() |
aea37e46e3 | ||
![]() |
31ab78ae8e | ||
![]() |
f82e1453e4 | ||
![]() |
a2b77c8813 | ||
![]() |
18add29472 | ||
![]() |
b111a8fe8d | ||
![]() |
3b23cf0258 | ||
![]() |
28e864e096 | ||
![]() |
1de19b921a | ||
![]() |
ff162b5a03 | ||
![]() |
d8e4705dd4 | ||
![]() |
338e1f5926 | ||
![]() |
a7fdfa08e1 | ||
![]() |
9703a401c5 | ||
![]() |
753a2aa462 | ||
![]() |
10990a0684 | ||
![]() |
91254e9211 | ||
![]() |
0f79287b04 | ||
![]() |
f2fac77d8c | ||
![]() |
81b7373637 | ||
![]() |
fa67c2548a | ||
![]() |
ea80587ddb | ||
![]() |
828f5f8384 | ||
![]() |
1295a1272a | ||
![]() |
66646d9276 | ||
![]() |
d0497dba92 | ||
![]() |
42914e8227 | ||
![]() |
59b49b7881 | ||
![]() |
5620f16330 | ||
![]() |
be024d4ad7 | ||
![]() |
75c740fe2b | ||
![]() |
6c8d86bb90 | ||
![]() |
b253a6b71e | ||
![]() |
ca7b4df812 | ||
![]() |
bc8dd57236 | ||
![]() |
f4f461b8bb | ||
![]() |
cbb9b6957f | ||
![]() |
f6b56c9317 | ||
![]() |
3717fb6c8d | ||
![]() |
f6abbc01bd | ||
![]() |
57a71c157d | ||
![]() |
cc76aeb7bb | ||
![]() |
811cabf8a9 | ||
![]() |
bf8d2f93d2 | ||
![]() |
07d8259ad6 | ||
![]() |
a00d412008 | ||
![]() |
5fb39658f1 | ||
![]() |
b0703b92c3 | ||
![]() |
dd9fd3d8a7 | ||
![]() |
cf0c59864f | ||
![]() |
4c0404c70d | ||
![]() |
573a413ee1 | ||
![]() |
f633e6ca49 | ||
![]() |
07b06d76be | ||
![]() |
856fe2da15 | ||
![]() |
f82aae65cd | ||
![]() |
3fbd11a104 | ||
![]() |
58a99f1907 | ||
![]() |
cf86dfd317 | ||
![]() |
a057b4f6d8 | ||
![]() |
62b03cfddf | ||
![]() |
18b827b979 | ||
![]() |
0a379fc514 | ||
![]() |
445c11b8d9 | ||
![]() |
8d290ad509 | ||
![]() |
b90c48b50f | ||
![]() |
d19e7db09e | ||
![]() |
9939904b02 | ||
![]() |
ca23b15f5c | ||
![]() |
ffa676f577 | ||
![]() |
6d023c4df3 | ||
![]() |
b31bd37a30 | ||
![]() |
78faee8c7c | ||
![]() |
40e2a703d0 | ||
![]() |
b01edcb9bc | ||
![]() |
f7fffc9be8 | ||
![]() |
50e8634097 | ||
![]() |
e3994e517e | ||
![]() |
2bb7785189 | ||
![]() |
90c8408111 | ||
![]() |
64786ec12a | ||
![]() |
b3c82f8886 | ||
![]() |
063259dc52 |
.travis.ymlAUTHORSINSTALLMakefile.amNEWSREADME.md
android
configure.acdoc
python/build
src
AudioFormat.hxxCommandLine.cxxDetachedSong.hxxLocateUri.hxxLogBackend.cxxLogInit.cxxLogLevel.hxxMain.cxxMain.hxxMixRampInfo.hxxMusicBuffer.hxxMusicChunk.hxxMusicPipe.cxxMusicPipe.hxxPlaylistFile.cxxPlaylistSave.cxxSongFilter.cxxSongFilter.hxxStateFile.cxxStateFile.hxxStats.cxxTimePrint.cxx
client
command
config
db
Helpers.cxxInterface.hxxLightDirectory.hxxPlaylistInfo.hxxSelection.cxx
plugins
update
decoder
encoder
plugins
event
Loop.hxxMultiSocketMonitor.cxxMultiSocketMonitor.hxxServerSocket.cxxSignalMonitor.cxxSignalMonitor.hxxSocketMonitor.cxxSocketMonitor.hxx
fs
AllocatedPath.cxxAllocatedPath.hxxCharset.cxxCharset.hxxCheckFile.cxxDirectoryReader.cxxDirectoryReader.hxxFileInfo.hxxFileSystem.cxxFileSystem.hxxGlob.hxxLimits.hxxPath.hxxStandardDirectory.cxxStandardDirectory.hxxTraits.cxxTraits.hxx
io
input
lib
curl
icu
nfs
upnp
mixer
neighbor
net
AllocatedSocketAddress.hxxResolver.cxxSocketAddress.hxxSocketError.cxxSocketError.hxxStaticSocketAddress.hxxToString.cxx
output
pcm
player
playlist
queue
storage
system
ByteOrder.hxxClock.cxxClock.hxxEPollFD.cxxError.hxxEventPipe.cxxFatalError.cxxFatalError.hxxFileDescriptor.cxxFileDescriptor.hxxfd_util.cfd_util.h
tag
Aiff.cxxFormat.cxxId3MusicBrainz.cxxId3MusicBrainz.hxxMixRamp.cxxReplayGain.cxxSet.cxxSet.hxxTagBuilder.hxxTagId3.cxx
thread
unix
util
ConstBuffer.hxxFormatString.cxxHugeAllocator.cxxHugeAllocator.hxxStringAPI.hxxStringView.cxxStringView.hxxTimeParser.cxxWStringAPI.hxx
win32
test
FakeDecoderAPI.cxxFakeDecoderAPI.hxxShutdownHandler.cxxShutdownHandler.hxxrun_resolver.cxxtest_byte_reverse.cxxtest_protocol.cxx
win32
36
.travis.yml
Normal file
36
.travis.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
dist: trusty
|
||||
language: cpp
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcppunit-dev
|
||||
- libboost-dev
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS="-j2"
|
||||
|
||||
before_install:
|
||||
# C++14
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || sudo apt-get update -qq
|
||||
- test "$TRAVIS_OS_NAME" != "osx" || brew update
|
||||
|
||||
install:
|
||||
# C++14
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || sudo apt-get install -qq g++-5
|
||||
- test "$TRAVIS_OS_NAME" != "osx" || brew install cppunit
|
||||
|
||||
script:
|
||||
- OPTIONS="--enable-test"
|
||||
- test "$TRAVIS_OS_NAME" != "linux" || export CC=gcc-5 CXX=g++-5
|
||||
- test "$TRAVIS_OS_NAME" != "osx" || OPTIONS="$OPTIONS --enable-osx"
|
||||
- ./autogen.sh
|
||||
- ./configure --disable-silent-rules --disable-dependency-tracking $OPTIONS
|
||||
- make
|
||||
- make check
|
1
AUTHORS
1
AUTHORS
@@ -30,3 +30,4 @@ The following people have contributed code to MPD:
|
||||
Jurgen Kramer <gtmkramer@xs4all.nl>
|
||||
Jean-Francois Dockes <jf@dockes.org>
|
||||
Yue Wang <yuleopen@gmail.com>
|
||||
Matthew Leon Grinshpun <ml@matthewleon.com>
|
||||
|
206
INSTALL
206
INSTALL
@@ -1,206 +0,0 @@
|
||||
Music Player Daemon (MPD) - INSTALL
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This document is a very small amount of documentation about what is needed to
|
||||
install MPD. If more information is desired, read the user manual:
|
||||
|
||||
http://www.musicpd.org/doc/user/
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
gcc 4.7 or later - http://gcc.gnu.org/
|
||||
clang 3.2 or later - http://clang.llvm.org/
|
||||
Any other C++11 compliant compiler should also work.
|
||||
|
||||
Boost 1.46 - http://www.boost.org/
|
||||
|
||||
|
||||
Optional Output Dependencies
|
||||
----------------------------
|
||||
|
||||
You will need at least one of these to compile MPD.
|
||||
|
||||
Most of these are available as packages on major distributions. Be sure to
|
||||
install both the library package as well as the development package.
|
||||
|
||||
AO - http://www.xiph.org/ao/
|
||||
A portable library that abstracts many audio output types as one API. Should
|
||||
be used only if there is no native plugin available or if the native plugin
|
||||
doesn't work. You will need libao.
|
||||
|
||||
ALSA - http://www.alsa-project.org/
|
||||
The Advanced Linux Sound Architecture. Recommended audio output if you use
|
||||
Linux. You will need libasound.
|
||||
|
||||
FIFO
|
||||
This is a mostly undocumented, developer plugin to transmit raw data.
|
||||
|
||||
OSS - http://www.opensound.com
|
||||
Open Sound System.
|
||||
|
||||
PulseAudio - http://www.pulseaudio.org/
|
||||
An advanced sound daemon. You will need libpulse.
|
||||
|
||||
JACK - http://www.jackaudio.org/
|
||||
A low-latency sound daemon.
|
||||
|
||||
libshout - http://www.icecast.org/
|
||||
For streaming to an Icecast or Shoutcast server.
|
||||
You also need an encoder: either libvorbisenc (ogg), or liblame (mp3).
|
||||
|
||||
OpenAL - http://kcat.strangesoft.net/openal.html
|
||||
Open Audio Library
|
||||
|
||||
|
||||
Optional Input Dependencies
|
||||
---------------------------
|
||||
|
||||
You will need at least one of these to compile MPD.
|
||||
|
||||
Most of these are available as packages on major distributions. Be sure to
|
||||
install both the library package as well as the development package.
|
||||
|
||||
MAD - http://www.underbit.com/products/mad/
|
||||
For MP3 support. You will need libmad, and optionally libid3tag if you want
|
||||
ID3 tag support.
|
||||
|
||||
libmpg123 - http://www.mpg123.de/
|
||||
Alternative for MP3 support.
|
||||
|
||||
Ogg Vorbis - http://www.xiph.org/ogg/vorbis/
|
||||
For Ogg Vorbis support. You will need libogg and libvorbis.
|
||||
|
||||
libopus - http://www.opus-codec.org/
|
||||
Opus codec support
|
||||
|
||||
FLAC - http://flac.sourceforge.net/
|
||||
For FLAC support. You will need version 1.2 or higher of libFLAC.
|
||||
|
||||
Audio File - http://www.68k.org/~michael/audiofile/
|
||||
For WAVE, AIFF, and AU support. You will need libaudiofile.
|
||||
|
||||
FAAD2 - http://www.audiocoding.com/
|
||||
For MP4/AAC support.
|
||||
|
||||
libmpcdec - http://www.musepack.net/
|
||||
For Musepack support.
|
||||
|
||||
MikMod - http://mikmod.raphnet.net/
|
||||
For MOD support. You will need libmikmod.
|
||||
|
||||
libavcodec, libavformat (ffmpeg or libav) - http://ffmpeg.mplayerhq.hu/ http://libav.org/
|
||||
Multi-codec library.
|
||||
|
||||
libsidplay2 - http://sidplay2.sourceforge.net/
|
||||
For C64 SID support.
|
||||
|
||||
libfluidsynth - http://fluidsynth.resonance.org/
|
||||
For MIDI support.
|
||||
|
||||
libwildmidi 0.2.3 - http://wildmidi.sourceforge.net/
|
||||
For MIDI support.
|
||||
|
||||
libsndfile - http://www.mega-nerd.com/libsndfile/
|
||||
WAVE, AIFF, and many others.
|
||||
|
||||
libwavpack - http://www.wavpack.com/
|
||||
For WavPack playback.
|
||||
|
||||
libadplug - http://adplug.sourceforge.net/
|
||||
For AdLib playback.
|
||||
|
||||
|
||||
Optional Miscellaneous Dependencies
|
||||
-----------------------------------
|
||||
|
||||
Avahi - http://www.avahi.org/
|
||||
For Zeroconf support.
|
||||
|
||||
libsamplerate - http://www.mega-nerd.com/SRC/
|
||||
For advanced samplerate conversions.
|
||||
|
||||
libcurl - http://curl.haxx.se/
|
||||
For playing HTTP streams.
|
||||
|
||||
libmms - https://launchpad.net/libmms
|
||||
For playing MMS streams.
|
||||
|
||||
SQLite - http://www.sqlite.org/
|
||||
For the sticker database.
|
||||
|
||||
libcdio - http://www.gnu.org/software/libcdio/
|
||||
For playing audio CDs.
|
||||
|
||||
libsystemd-daemon - http://freedesktop.org/wiki/Software/systemd/
|
||||
For systemd activation.
|
||||
|
||||
|
||||
pkg-config
|
||||
----------
|
||||
|
||||
MPD uses pkg-config to locate most external libraries. If you do not
|
||||
have pkg-config, or if your version of the library does not ship the
|
||||
".pc" file, you have to provide the library's build options in
|
||||
environment variables. These variables are documented in "./configure
|
||||
--help". Example:
|
||||
|
||||
FLAC_CFLAGS=-I/usr/include/FLAC FLAC_LIBS=-lFLAC ./configure
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
Get the latest release from of MPD from <http://www.musicpd.org/>.
|
||||
|
||||
Compile
|
||||
-------
|
||||
|
||||
1) unpack the archive
|
||||
|
||||
$ tar xf mpd-x.x.x.tar.xz
|
||||
|
||||
2) change to directory created
|
||||
|
||||
$ cd mpd-x.x.x
|
||||
|
||||
3) Run configure script (this will determine what dependencies you have)
|
||||
|
||||
$ ./configure
|
||||
|
||||
4) Compile
|
||||
|
||||
$ make
|
||||
|
||||
Install (Optional)
|
||||
-------
|
||||
|
||||
(as root)
|
||||
$ make install
|
||||
|
||||
Run
|
||||
---
|
||||
|
||||
1) run mpd:
|
||||
|
||||
$ mpd <config file>
|
||||
|
||||
First default is $XDG_CONFIG_HOME/mpd/mpd.conf then ~/.mpdconf then
|
||||
~/.mpd/mpd.conf then /etc/mpd.conf. If neither of these exist a mpd
|
||||
configuration file must be specified at runtime.
|
||||
|
||||
A sample config file is included with the source of MPD, mpdconf.example.
|
||||
|
||||
The first time MPD is run it will attempt to discover all music in your
|
||||
music root, recursively. This can be affected by the symbolic link
|
||||
options specified in the example mpd.conf.
|
||||
|
||||
Using MPD
|
||||
---------
|
||||
|
||||
You can download many different interfaces for MPD at
|
||||
|
||||
http://www.musicpd.org/clients/
|
12
Makefile.am
12
Makefile.am
@@ -243,6 +243,7 @@ CURL_SOURCES = \
|
||||
src/lib/curl/Slist.hxx
|
||||
|
||||
UPNP_SOURCES = \
|
||||
src/lib/upnp/Compat.hxx \
|
||||
src/lib/upnp/Init.cxx src/lib/upnp/Init.hxx \
|
||||
src/lib/upnp/ClientInit.cxx src/lib/upnp/ClientInit.hxx \
|
||||
src/lib/upnp/Device.cxx src/lib/upnp/Device.hxx \
|
||||
@@ -518,6 +519,8 @@ libevent_a_SOURCES = \
|
||||
# UTF-8 library
|
||||
|
||||
libicu_a_SOURCES = \
|
||||
src/lib/icu/CaseFold.cxx src/lib/icu/CaseFold.hxx \
|
||||
src/lib/icu/Compare.cxx src/lib/icu/Compare.hxx \
|
||||
src/lib/icu/Collate.cxx src/lib/icu/Collate.hxx \
|
||||
src/lib/icu/Converter.cxx src/lib/icu/Converter.hxx
|
||||
|
||||
@@ -699,6 +702,7 @@ libstorage_a_SOURCES = \
|
||||
src/storage/MemoryDirectoryReader.cxx src/storage/MemoryDirectoryReader.hxx \
|
||||
src/storage/Configured.cxx src/storage/Configured.hxx \
|
||||
src/storage/plugins/LocalStorage.cxx src/storage/plugins/LocalStorage.hxx \
|
||||
src/storage/StorageState.cxx src/storage/StorageState.hxx \
|
||||
src/storage/FileInfo.hxx
|
||||
|
||||
libstorage_a_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
@@ -751,6 +755,7 @@ libneighbor_a_SOURCES = \
|
||||
src/neighbor/NeighborPlugin.hxx
|
||||
|
||||
libneighbor_a_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
$(UPNP_CFLAGS) \
|
||||
$(SMBCLIENT_CFLAGS)
|
||||
|
||||
if ENABLE_SMBCLIENT
|
||||
@@ -800,6 +805,8 @@ libdb_plugins_a_SOURCES = \
|
||||
src/db/plugins/simple/PrefixedLightSong.hxx \
|
||||
src/db/plugins/simple/SimpleDatabasePlugin.cxx \
|
||||
src/db/plugins/simple/SimpleDatabasePlugin.hxx
|
||||
libdb_plugins_a_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
$(UPNP_CFLAGS)
|
||||
|
||||
if ENABLE_LIBMPDCLIENT
|
||||
libdb_plugins_a_SOURCES += \
|
||||
@@ -923,6 +930,7 @@ libtag_a_SOURCES =\
|
||||
src/tag/ReplayGain.cxx src/tag/ReplayGain.hxx \
|
||||
src/tag/MixRamp.cxx src/tag/MixRamp.hxx \
|
||||
src/tag/Generic.cxx src/tag/Generic.hxx \
|
||||
src/tag/Id3MusicBrainz.cxx src/tag/Id3MusicBrainz.hxx \
|
||||
src/tag/ApeLoader.cxx src/tag/ApeLoader.hxx \
|
||||
src/tag/ApeReplayGain.cxx src/tag/ApeReplayGain.hxx \
|
||||
src/tag/ApeTag.cxx src/tag/ApeTag.hxx
|
||||
@@ -1489,6 +1497,8 @@ liboutput_plugins_a_SOURCES += \
|
||||
src/output/plugins/OSXOutputPlugin.cxx \
|
||||
src/output/plugins/OSXOutputPlugin.hxx
|
||||
endif
|
||||
libmixer_plugins_a_SOURCES += \
|
||||
src/mixer/plugins/OSXMixerPlugin.cxx
|
||||
|
||||
if ENABLE_PULSE
|
||||
liboutput_plugins_a_SOURCES += \
|
||||
@@ -2406,6 +2416,7 @@ EXTRA_DIST = $(doc_DATA) autogen.sh \
|
||||
$(man_MANS) $(DOCBOOK_FILES) doc/mpdconf.example doc/doxygen.conf \
|
||||
$(wildcard $(srcdir)/doc/include/*.xml) \
|
||||
systemd/system/mpd.socket \
|
||||
$(wildcard $(srcdir)/python/build/*.py) \
|
||||
android/AndroidManifest.xml \
|
||||
android/build.py \
|
||||
android/custom_rules.xml \
|
||||
@@ -2413,5 +2424,6 @@ EXTRA_DIST = $(doc_DATA) autogen.sh \
|
||||
android/src/Bridge.java \
|
||||
android/src/Loader.java \
|
||||
android/src/Main.java \
|
||||
win32/build.py \
|
||||
win32/res/mpd.rc.in win32/res/mpd.ico \
|
||||
src/haiku/App_MusicPD
|
||||
|
67
NEWS
67
NEWS
@@ -1,3 +1,70 @@
|
||||
ver 0.20.13 (2017/12/18)
|
||||
* output
|
||||
- osx: set up ring buffer to hold at least 100ms
|
||||
* mixer
|
||||
- alsa: fix rounding errors
|
||||
* database
|
||||
- simple: don't purge mount points on update/rescan
|
||||
- simple: fix "mount" bug caused by bad compiler optimization
|
||||
- simple: fix "lsinfo" into mount points
|
||||
- upnp: work around libupnp 1.6.24 API breakage
|
||||
* queue: fix spuriously misplaced prioritized songs
|
||||
* save and restore mountpoints within the state file
|
||||
* include Windows cross-build script in source tarball
|
||||
* fix Windows build failures
|
||||
|
||||
ver 0.20.12 (2017/11/25)
|
||||
* database
|
||||
- upnp: adapt to libupnp 1.8 API changes
|
||||
* input
|
||||
- cdio_paranoia, ffmpeg, file, smbclient: reduce lock contention,
|
||||
fixing lots of xrun problems
|
||||
- curl: fix seeking
|
||||
* decoder
|
||||
- ffmpeg: fix GCC 8 warning
|
||||
- vorbis: fix Tremor support
|
||||
* player
|
||||
- log message when decoder is too slow
|
||||
* encoder
|
||||
- vorbis: default to quality 3
|
||||
* output
|
||||
- fix hanging playback with soxr resampler
|
||||
- httpd: flush encoder after tag; fixes corrupt Vorbis stream
|
||||
|
||||
ver 0.20.11 (2017/10/18)
|
||||
* storage
|
||||
- curl: support Content-Type application/xml
|
||||
* decoder
|
||||
- ffmpeg: more reliable song duration
|
||||
- gme: fix track numbering
|
||||
* improve random song order when switching songs manually
|
||||
* fix case insensitive search without libicu
|
||||
* fix Unicode file names in playlists on Windows
|
||||
* fix endless loop when accessing malformed file names in ZIP files
|
||||
|
||||
ver 0.20.10 (2017/08/24)
|
||||
* decoder
|
||||
- ffmpeg: support MusicBrainz ID3v2 tags
|
||||
* tags
|
||||
- aiff: fix FORM chunk size endianess (is big-endian)
|
||||
* mixer
|
||||
- osx: add a mixer for OSX.
|
||||
* fix crash when resuming playback before decoder is ready
|
||||
* fix crash on Windows
|
||||
|
||||
ver 0.20.9 (2017/06/04)
|
||||
* decoder
|
||||
- ffmpeg: support *.adx
|
||||
* fix byte order detection on FreeBSD/aarch64
|
||||
* fix more random crashes when compiled with clang
|
||||
|
||||
ver 0.20.8 (2017/05/19)
|
||||
* output
|
||||
- osx: fix build failure due to missing "noexcept"
|
||||
* playlist
|
||||
- m3u: support MIME type `audio/mpegurl`
|
||||
* fix build failure with GCC 4.x
|
||||
|
||||
ver 0.20.7 (2017/05/15)
|
||||
* database
|
||||
- simple: fix false positive directory loop detection with NFS
|
||||
|
@@ -7,7 +7,8 @@ server's audio device. The daemon stores info about all available music,
|
||||
and this info can be easily searched and retrieved. Player control, info
|
||||
retrieval, and playlist management can all be managed remotely.
|
||||
|
||||
For basic installation information see the INSTALL file.
|
||||
For basic installation instructions
|
||||
[read the manual](https://www.musicpd.org/doc/user/install.html).
|
||||
|
||||
# Users
|
||||
|
||||
|
@@ -46,13 +46,14 @@ class AndroidNdkToolchain:
|
||||
|
||||
self.ndk_arch = 'arm'
|
||||
android_abi = 'armeabi-v7a'
|
||||
ndk_platform = 'android-14'
|
||||
ndk_platform = 'android-21'
|
||||
|
||||
# select the NDK compiler
|
||||
gcc_version = '4.9'
|
||||
|
||||
ndk_platform_path = os.path.join(ndk_path, 'platforms', ndk_platform)
|
||||
sysroot = os.path.join(ndk_platform_path, 'arch-' + self.ndk_arch)
|
||||
sysroot = os.path.join(ndk_path, 'sysroot')
|
||||
target_root = os.path.join(ndk_platform_path, 'arch-' + self.ndk_arch)
|
||||
|
||||
install_prefix = os.path.join(arch_path, 'root')
|
||||
|
||||
@@ -79,8 +80,15 @@ class AndroidNdkToolchain:
|
||||
|
||||
self.cflags = '-Os -g ' + common_flags
|
||||
self.cxxflags = '-Os -g ' + common_flags
|
||||
self.cppflags = '--sysroot=' + self.sysroot + ' -isystem ' + os.path.join(install_prefix, 'include')
|
||||
self.ldflags = '--sysroot=' + self.sysroot + ' ' + common_flags + ' -L' + os.path.join(install_prefix, 'lib')
|
||||
self.cppflags = '--sysroot=' + sysroot + \
|
||||
' -isystem ' + os.path.join(install_prefix, 'include') + \
|
||||
' -isystem ' + os.path.join(sysroot, 'usr', 'include', arch) + \
|
||||
' -D__ANDROID_API__=21'
|
||||
self.ldflags = '--sysroot=' + sysroot + \
|
||||
' -L' + os.path.join(install_prefix, 'lib') + \
|
||||
' -L' + os.path.join(target_root, 'usr', 'lib') + \
|
||||
' -B' + os.path.join(target_root, 'usr', 'lib') + \
|
||||
' ' + common_flags
|
||||
self.libs = ''
|
||||
|
||||
self.is_arm = self.ndk_arch == 'arm'
|
||||
@@ -154,5 +162,9 @@ configure = [
|
||||
|
||||
] + configure_args
|
||||
|
||||
from build.cmdline import concatenate_cmdline_variables
|
||||
configure = concatenate_cmdline_variables(configure,
|
||||
set(('CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS', 'LIBS')))
|
||||
|
||||
subprocess.check_call(configure, env=toolchain.env)
|
||||
subprocess.check_call(['/usr/bin/make', '--quiet', '-j12'], env=toolchain.env)
|
||||
|
12
configure.ac
12
configure.ac
@@ -1,10 +1,10 @@
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT(mpd, 0.20.7, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_INIT(mpd, 0.20.13, musicpd-dev-team@lists.sourceforge.net)
|
||||
|
||||
VERSION_MAJOR=0
|
||||
VERSION_MINOR=20
|
||||
VERSION_REVISION=7
|
||||
VERSION_REVISION=13
|
||||
VERSION_EXTRA=0
|
||||
|
||||
AC_CONFIG_SRCDIR([src/Main.cxx])
|
||||
@@ -241,6 +241,7 @@ AC_CHECK_FUNCS(getpwnam_r getpwuid_r)
|
||||
AC_CHECK_FUNCS(initgroups)
|
||||
AC_CHECK_FUNCS(fnmatch)
|
||||
AC_CHECK_FUNCS(strndup)
|
||||
AC_CHECK_FUNCS(strcasestr)
|
||||
|
||||
if test x$host_is_linux = xyes; then
|
||||
MPD_OPTIONAL_FUNC(eventfd, eventfd, USE_EVENTFD)
|
||||
@@ -491,7 +492,7 @@ if test x$enable_ipv6 = xyes; then
|
||||
AC_EGREP_CPP([AP_maGiC_VALUE],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
@@ -1384,6 +1385,11 @@ then
|
||||
AX_APPEND_COMPILE_FLAGS([-Wcast-qual])
|
||||
AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
|
||||
AX_APPEND_COMPILE_FLAGS([-Wsign-compare])
|
||||
|
||||
dnl This GCC8 warning for C++17 ABI compatibility is of no
|
||||
dnl interest for us, because we're not a shared library.
|
||||
AX_APPEND_COMPILE_FLAGS([-Wno-noexcept-type])
|
||||
|
||||
AC_LANG_POP
|
||||
fi
|
||||
|
||||
|
@@ -403,6 +403,15 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Change events accumulate, even while the connection is
|
||||
not in "idle" mode; no events gets lost while the client
|
||||
is doing something else with the connection. If an
|
||||
event had already occurred since the last call, the new
|
||||
<command>idle</command> command will return immediately.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While a client is waiting for <command>idle</command>
|
||||
results, the server disables timeouts, allowing a client
|
||||
@@ -436,7 +445,9 @@
|
||||
<listitem>
|
||||
<para>
|
||||
<varname>volume</varname>:
|
||||
<returnvalue>0-100</returnvalue>
|
||||
<returnvalue>0-100</returnvalue> or
|
||||
<returnvalue>-1</returnvalue> if the volume cannot
|
||||
be determined
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
247
doc/user.xml
247
doc/user.xml
@@ -80,13 +80,40 @@
|
||||
cd mpd-version</programlisting>
|
||||
|
||||
<para>
|
||||
Make sure that all the required libraries and build tools are
|
||||
installed. The <filename>INSTALL</filename> file has a list.
|
||||
In any case, you need:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
a C++14 compiler (e.g. <ulink
|
||||
url="http://gcc.gnu.org/">gcc 4.9</ulink> or <ulink
|
||||
url="http://clang.llvm.org/">clang 3.9</ulink>)
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="http://www.boost.org/">Boost 1.46</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<ulink url="https://www.freedesktop.org/wiki/Software/pkg-config/">pkg-config</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Each plugin usually needs a codec library, which you also need
|
||||
to install. Check the plugin reference for details about
|
||||
required libraries.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, the following installs a fairly complete list of
|
||||
build dependencies on Debian Wheezy:
|
||||
build dependencies on Debian Jessie:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
@@ -98,19 +125,20 @@ apt-get install g++ \
|
||||
libmpcdec-dev libwavpack-dev libwildmidi-dev \
|
||||
libsidplay2-dev libsidutils-dev libresid-builder-dev \
|
||||
libavcodec-dev libavformat-dev \
|
||||
libmp3lame-dev \
|
||||
libmp3lame-dev libtwolame-dev libshine-dev \
|
||||
libsamplerate0-dev libsoxr-dev \
|
||||
libbz2-dev libcdio-paranoia-dev libiso9660-dev libmms-dev \
|
||||
libzzip-dev \
|
||||
libcurl4-gnutls-dev libyajl-dev libexpat-dev \
|
||||
libasound2-dev libao-dev libjack-jackd2-dev libopenal-dev \
|
||||
libpulse-dev libroar-dev libshout3-dev \
|
||||
libsndio-dev \
|
||||
libmpdclient-dev \
|
||||
libnfs-dev libsmbclient-dev \
|
||||
libupnp-dev \
|
||||
libavahi-client-dev \
|
||||
libsqlite3-dev \
|
||||
libsystemd-daemon-dev libwrap0-dev \
|
||||
libsystemd-dev libwrap0-dev \
|
||||
libcppunit-dev xmlto \
|
||||
libboost-dev \
|
||||
libicu-dev
|
||||
@@ -1035,6 +1063,40 @@ systemctl start mpd.socket</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="stickers">
|
||||
<title>The Sticker Database</title>
|
||||
|
||||
<para>
|
||||
"Stickers" are pieces of information attached to songs.
|
||||
Some clients use them to store ratings and other volatile
|
||||
data. This feature requires <ulink
|
||||
url="http://www.sqlite.org/">SQLite</ulink>, compile-time
|
||||
configure option <parameter>--enable-sqlite</parameter>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>sticker_file</varname>
|
||||
<parameter>PATH</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
The location of the sticker database.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Resource Limitations</title>
|
||||
|
||||
@@ -1165,6 +1227,55 @@ systemctl start mpd.socket</programlisting>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="zeroconf">
|
||||
<title>Zeroconf</title>
|
||||
|
||||
<para>
|
||||
If Zeroconf support (<ulink
|
||||
url="http://avahi.org/">Avahi</ulink> or Apple's Bonjour)
|
||||
was enabled at compile time with
|
||||
<parameter>--with-zeroconf=...</parameter>, MPD can announce
|
||||
its presence on the network. The following settings control
|
||||
this feature:
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>zeroconf_enabled</varname>
|
||||
<parameter>yes|no</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
Enables or disables this feature. Default is
|
||||
<parameter>yes</parameter>.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>zeroconf_name</varname>
|
||||
<parameter>NAME</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
The service name to publish via Zeroconf. The
|
||||
default is "<parameter>Music Player</parameter>".
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -2078,7 +2189,9 @@ run</programlisting>
|
||||
<title><varname>cdio_paranoia</varname></title>
|
||||
|
||||
<para>
|
||||
Plays audio CDs. The URI has the form:
|
||||
Plays audio CDs using <ulink
|
||||
url="http://www.gnu.org/software/libcdio/"><filename>libcdio</filename></ulink>.
|
||||
The URI has the form:
|
||||
"<filename>cdda://[DEVICE][/TRACK]</filename>". The
|
||||
simplest form <filename>cdda://</filename> plays the whole
|
||||
disc in the default drive.
|
||||
@@ -2114,7 +2227,8 @@ run</programlisting>
|
||||
<title><varname>curl</varname></title>
|
||||
|
||||
<para>
|
||||
Opens remote files or streams over HTTP.
|
||||
Opens remote files or streams over HTTP using <ulink
|
||||
url="http://curl.haxx.se/"><filename>libcurl</filename></ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -2207,7 +2321,8 @@ run</programlisting>
|
||||
<title><varname>mms</varname></title>
|
||||
|
||||
<para>
|
||||
Plays streams with the MMS protocol.
|
||||
Plays streams with the MMS protocol using <ulink
|
||||
url="https://launchpad.net/libmms"><filename>libmms</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2263,7 +2378,8 @@ run</programlisting>
|
||||
<title><varname>adplug</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes AdLib files.
|
||||
Decodes AdLib files using <ulink
|
||||
url="http://adplug.sourceforge.net/">libadplug</ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -2294,8 +2410,8 @@ run</programlisting>
|
||||
<title><varname>audiofile</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes WAV and AIFF files using
|
||||
<filename>libaudiofile</filename>.
|
||||
Decodes WAV and AIFF files using <ulink
|
||||
url="http://audiofile.68k.org/"><filename>libaudiofile</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2303,7 +2419,8 @@ run</programlisting>
|
||||
<title><varname>faad</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes AAC files using <filename>libfaad</filename>.
|
||||
Decodes AAC files using <ulink
|
||||
url="http://www.audiocoding.com/"><filename>libfaad</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2311,8 +2428,8 @@ run</programlisting>
|
||||
<title><varname>ffmpeg</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes various codecs using
|
||||
<application>FFmpeg</application>.
|
||||
Decodes various codecs using <ulink
|
||||
url="https://ffmpeg.org/"><application>FFmpeg</application></ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -2363,7 +2480,7 @@ run</programlisting>
|
||||
|
||||
<para>
|
||||
Decodes FLAC files using
|
||||
<application>libFLAC</application>.
|
||||
<ulink url="https://xiph.org/flac/"><application>libFLAC</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2483,7 +2600,8 @@ run</programlisting>
|
||||
<title><varname>mad</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes MP3 files using <application>libmad</application>.
|
||||
Decodes MP3 files using <ulink
|
||||
url="http://www.underbit.com/products/mad/"><application>libmad</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2563,8 +2681,8 @@ run</programlisting>
|
||||
<title><varname>mpcdec</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes Musepack files using
|
||||
<application>libmpcdec</application>.
|
||||
Decodes Musepack files using <ulink
|
||||
url="http://www.musepack.net/"><application>libmpcdec</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2572,7 +2690,17 @@ run</programlisting>
|
||||
<title><varname>mpg123</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes MP3 files using <application>libmpg123</application>.
|
||||
Decodes MP3 files using <ulink
|
||||
url="http://www.mpg123.de/"><application>libmpg123</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="opus_decoder">
|
||||
<title><varname>opus</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes Opus files using <ulink
|
||||
url="http://www.opus-codec.org/"><application>libopus</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2592,8 +2720,8 @@ run</programlisting>
|
||||
<title><varname>sidplay</varname></title>
|
||||
|
||||
<para>
|
||||
C64 SID decoder based on
|
||||
<application>libsidplay</application>.
|
||||
C64 SID decoder based on <ulink
|
||||
url="http://sidplay2.sourceforge.net/"><application>libsidplay</application></ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -2649,8 +2777,8 @@ run</programlisting>
|
||||
<title><varname>sndfile</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes WAV and AIFF files using
|
||||
<filename>libsndfile</filename>.
|
||||
Decodes WAV and AIFF files using <ulink
|
||||
url="http://www.mega-nerd.com/libsndfile/"><filename>libsndfile</filename></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2658,8 +2786,8 @@ run</programlisting>
|
||||
<title><varname>vorbis</varname></title>
|
||||
|
||||
<para>
|
||||
Decodes Ogg-Vorbis files using
|
||||
<application>libvorbis</application>.
|
||||
Decodes Ogg-Vorbis files using <ulink
|
||||
url="http://www.xiph.org/ogg/vorbis/"><application>libvorbis</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2668,7 +2796,7 @@ run</programlisting>
|
||||
|
||||
<para>
|
||||
Decodes WavPack files using
|
||||
<application>libwavpack</application>.
|
||||
<ulink url="http://www.wavpack.com/"><application>libwavpack</application></ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2863,6 +2991,60 @@ run</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="opus_encoder">
|
||||
<title><varname>opus</varname></title>
|
||||
|
||||
<para>
|
||||
Encodes into <ulink
|
||||
url="http://www.opus-codec.org/">Ogg Opus</ulink>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>bitrate</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the data rate in bit per second. The special
|
||||
value "auto" lets <application>libopus</application>
|
||||
choose a rate (which is the default), and "max" uses
|
||||
the maximum possible data rate.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>complexity</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the <ulink
|
||||
url="https://wiki.xiph.org/OpusFAQ#What_is_the_complexity_of_Opus.3F">Opus
|
||||
complexity</ulink>.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>signal</varname>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the Opus signal type. Valid values are "auto"
|
||||
(the default), "voice" and "music".
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section id="vorbis_encoder">
|
||||
<title><varname>vorbis</varname></title>
|
||||
|
||||
@@ -2886,8 +3068,8 @@ run</programlisting>
|
||||
</entry>
|
||||
<entry>
|
||||
Sets the quality for VBR. -1 is the lowest quality,
|
||||
10 is the highest quality. Cannot be used with
|
||||
<varname>bitrate</varname>.
|
||||
10 is the highest quality. Defaults to 3. Cannot
|
||||
be used with <varname>bitrate</varname>.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -3492,7 +3674,7 @@ run</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section id="jack_output">
|
||||
<title><varname>jack</varname></title>
|
||||
|
||||
<para>
|
||||
@@ -3772,7 +3954,7 @@ run</programlisting>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section id="openal_output">
|
||||
<title><varname>openal</varname></title>
|
||||
|
||||
<para>
|
||||
@@ -3923,7 +4105,7 @@ run</programlisting>
|
||||
<para>
|
||||
The <varname>pulse</varname> plugin connects to a <ulink
|
||||
url="http://www.freedesktop.org/wiki/Software/PulseAudio/"><application>PulseAudio</application></ulink>
|
||||
server.
|
||||
server. Requires <filename>libpulse</filename>.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
@@ -4111,7 +4293,8 @@ run</programlisting>
|
||||
url="http://www.shoutcast.com/"><application>ShoutCast</application></ulink>
|
||||
or <ulink
|
||||
url="http://icecast.org/"><application>IceCast</application></ulink>
|
||||
server. It forwards tags to this server.
|
||||
server using <filename>libshout</filename>. It forwards
|
||||
tags to this server.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
29
python/build/cmdline.py
Normal file
29
python/build/cmdline.py
Normal file
@@ -0,0 +1,29 @@
|
||||
def concatenate_cmdline_variables(src, names):
|
||||
"""Find duplicate variable declarations on the given source list, and
|
||||
concatenate the values of those in the 'names' list."""
|
||||
|
||||
# the result list being constructed
|
||||
dest = []
|
||||
|
||||
# a map of variable name to destination list index
|
||||
positions = {}
|
||||
|
||||
for item in src:
|
||||
i = item.find('=')
|
||||
if i > 0:
|
||||
# it's a variable
|
||||
name = item[:i]
|
||||
if name in names:
|
||||
# it's a known variable
|
||||
if name in positions:
|
||||
# already specified: concatenate instead of
|
||||
# appending it
|
||||
dest[positions[name]] += ' ' + item[i + 1:]
|
||||
continue
|
||||
else:
|
||||
# not yet seen: append it and remember the list
|
||||
# index
|
||||
positions[name] = len(dest)
|
||||
dest.append(item)
|
||||
|
||||
return dest
|
@@ -19,8 +19,8 @@ libvorbis = AutotoolsProject(
|
||||
)
|
||||
|
||||
opus = AutotoolsProject(
|
||||
'http://downloads.xiph.org/releases/opus/opus-1.1.4.tar.gz',
|
||||
'9122b6b380081dd2665189f97bfd777f04f92dc3ab6698eea1dbb27ad59d8692',
|
||||
'https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz',
|
||||
'cfafd339ccd9c5ef8d6ab15d7e1a412c054bf4cb4ecbbbcc78c12ef2def70732',
|
||||
'lib/libopus.a',
|
||||
['--disable-shared', '--enable-static'],
|
||||
)
|
||||
@@ -57,9 +57,20 @@ libmad = AutotoolsProject(
|
||||
autogen=True,
|
||||
)
|
||||
|
||||
liblame = AutotoolsProject(
|
||||
'http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz',
|
||||
'24346b4158e4af3bd9f2e194bb23eb473c75fb7377011523353196b19b9a23ff',
|
||||
'lib/libmp3lame.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
'--disable-gtktest', '--disable-analyzer-hooks',
|
||||
'--disable-decoder', '--disable-frontend',
|
||||
],
|
||||
)
|
||||
|
||||
ffmpeg = FfmpegProject(
|
||||
'http://ffmpeg.org/releases/ffmpeg-3.3.tar.xz',
|
||||
'599e7f7c017221c22011c4037b88bdcd1c47cd40c1e466838bc3c465f3e9569d',
|
||||
'http://ffmpeg.org/releases/ffmpeg-3.4.1.tar.xz',
|
||||
'5a77278a63741efa74e26bf197b9bb09ac6381b9757391b922407210f0f991c0',
|
||||
'lib/libavcodec.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
@@ -73,17 +84,26 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-swscale',
|
||||
'--disable-postproc',
|
||||
'--disable-avfilter',
|
||||
'--disable-lzo',
|
||||
'--disable-faan',
|
||||
'--disable-pixelutils',
|
||||
'--disable-network',
|
||||
'--disable-encoders',
|
||||
'--disable-protocols',
|
||||
'--disable-outdevs',
|
||||
'--disable-devices',
|
||||
'--disable-filters',
|
||||
'--disable-v4l2_m2m',
|
||||
|
||||
# clang misinterprets the "B0" in hevc_mvs.c as binary
|
||||
# literal, which breaks the build; but we don't need that
|
||||
# video codec anyway
|
||||
'--disable-decoder=hevc',
|
||||
],
|
||||
)
|
||||
|
||||
curl = AutotoolsProject(
|
||||
'http://curl.haxx.se/download/curl-7.54.0.tar.lzma',
|
||||
'cd6aa6039f13e0b06e0a93e1b93754f6dc07f444812bb6c32be75a8f28c4070a',
|
||||
'http://curl.haxx.se/download/curl-7.57.0.tar.xz',
|
||||
'f5f6fd3c72b7b8389969f4fb671ed8532fa9b5bb7a5cae7ca89bc1cea45c7878',
|
||||
'lib/libcurl.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
@@ -103,7 +123,7 @@ curl = AutotoolsProject(
|
||||
)
|
||||
|
||||
boost = BoostProject(
|
||||
'http://downloads.sourceforge.net/project/boost/boost/1.64.0/boost_1_64_0.tar.bz2',
|
||||
'7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332',
|
||||
'http://downloads.sourceforge.net/project/boost/boost/1.65.1/boost_1_65_1.tar.bz2',
|
||||
'9807a5d16566c57fd74fb522764e0b134a8bbe6b6e8967b83afefd30dcd3be81',
|
||||
'include/boost/version.hpp',
|
||||
)
|
||||
|
@@ -127,7 +127,7 @@ struct AudioFormat {
|
||||
void ApplyMask(AudioFormat mask) noexcept;
|
||||
|
||||
gcc_pure
|
||||
AudioFormat WithMask(AudioFormat mask) const {
|
||||
AudioFormat WithMask(AudioFormat mask) const noexcept {
|
||||
AudioFormat result = *this;
|
||||
result.ApplyMask(mask);
|
||||
return result;
|
||||
|
@@ -67,7 +67,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define CONFIG_FILE_LOCATION PATH_LITERAL("mpd\\mpd.conf")
|
||||
#define APP_CONFIG_FILE_LOCATION PATH_LITERAL("conf\\mpd.conf")
|
||||
#else
|
||||
@@ -389,7 +389,7 @@ ParseCommandLine(int argc, char **argv, struct options *options)
|
||||
ConfigLoader loader;
|
||||
|
||||
bool found =
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
loader.TryFile(GetUserConfigDir(), CONFIG_FILE_LOCATION) ||
|
||||
loader.TryFile(GetSystemConfigDir(), CONFIG_FILE_LOCATION) ||
|
||||
loader.TryFile(GetAppBaseDir(), APP_CONFIG_FILE_LOCATION);
|
||||
|
@@ -152,7 +152,7 @@ public:
|
||||
bool IsRemote() const noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool IsFile() const {
|
||||
bool IsFile() const noexcept {
|
||||
return !IsRemote();
|
||||
}
|
||||
|
||||
@@ -162,11 +162,11 @@ public:
|
||||
gcc_pure
|
||||
bool IsInDatabase() const noexcept;
|
||||
|
||||
const Tag &GetTag() const {
|
||||
const Tag &GetTag() const noexcept {
|
||||
return tag;
|
||||
}
|
||||
|
||||
Tag &WritableTag() {
|
||||
Tag &WritableTag() noexcept {
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include "Compiler.h"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
/* damn you, windows.h! */
|
||||
#ifdef ABSOLUTE
|
||||
|
@@ -162,7 +162,7 @@ FileLog(const Domain &domain, const char *message)
|
||||
domain.GetName(),
|
||||
chomp_length(message), message);
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* force-flush the log file, because setvbuf() does not seem
|
||||
to have an effect on WIN32 */
|
||||
fflush(stderr);
|
||||
|
@@ -72,7 +72,7 @@ log_init_file(int line)
|
||||
|
||||
out_fd = open_log_file();
|
||||
if (out_fd < 0) {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
const std::string out_path_utf8 = out_path.ToUTF8();
|
||||
throw FormatRuntimeError("failed to open log file \"%s\" (config line %d)",
|
||||
out_path_utf8.c_str(), line);
|
||||
@@ -182,7 +182,7 @@ void setup_log_output()
|
||||
fflush(nullptr);
|
||||
|
||||
if (out_fd < 0) {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return;
|
||||
#else
|
||||
out_fd = open("/dev/null", O_WRONLY);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#ifndef MPD_LOG_LEVEL_HXX
|
||||
#define MPD_LOG_LEVEL_HXX
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
/* damn you, windows.h! */
|
||||
#ifdef ERROR
|
||||
|
24
src/Main.cxx
24
src/Main.cxx
@@ -106,7 +106,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
@@ -121,8 +121,16 @@ static constexpr size_t KILOBYTE = 1024;
|
||||
static constexpr size_t MEGABYTE = 1024 * KILOBYTE;
|
||||
|
||||
static constexpr size_t DEFAULT_BUFFER_SIZE = 4 * MEGABYTE;
|
||||
static constexpr size_t MIN_BUFFER_SIZE = std::max(CHUNK_SIZE * 32,
|
||||
64 * KILOBYTE);
|
||||
|
||||
static
|
||||
#if GCC_OLDER_THAN(5,0)
|
||||
/* gcc 4.x has no "constexpr" for std::max() */
|
||||
const
|
||||
#else
|
||||
constexpr
|
||||
#endif
|
||||
size_t MIN_BUFFER_SIZE = std::max(CHUNK_SIZE * 32,
|
||||
64 * KILOBYTE);
|
||||
|
||||
static constexpr unsigned DEFAULT_BUFFER_BEFORE_PLAY = 10;
|
||||
|
||||
@@ -281,7 +289,7 @@ glue_state_file_init()
|
||||
*/
|
||||
static void winsock_init(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
WSADATA sockinfo;
|
||||
|
||||
int retval = WSAStartup(MAKEWORD(2, 2), &sockinfo);
|
||||
@@ -410,7 +418,7 @@ Instance::OnIdle(unsigned flags)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return win32_main(argc, argv);
|
||||
#else
|
||||
return mpd_main(argc, argv);
|
||||
@@ -607,7 +615,7 @@ try {
|
||||
playlist_state_restore() */
|
||||
instance->partition->pc.LockUpdateAudio();
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
win32_app_started();
|
||||
#endif
|
||||
|
||||
@@ -622,7 +630,7 @@ try {
|
||||
/* run the main loop */
|
||||
instance->event_loop.Run();
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
win32_app_stopping();
|
||||
#endif
|
||||
|
||||
@@ -694,7 +702,7 @@ try {
|
||||
daemonize_finish();
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
|
@@ -42,7 +42,7 @@ int mpd_main(int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
* If program is run as windows service performs nessesary initialization
|
||||
|
@@ -31,45 +31,45 @@ class MixRampInfo {
|
||||
public:
|
||||
MixRampInfo() = default;
|
||||
|
||||
void Clear() {
|
||||
void Clear() noexcept {
|
||||
start.clear();
|
||||
end.clear();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsDefined() const {
|
||||
bool IsDefined() const noexcept {
|
||||
return !start.empty() || !end.empty();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetStart() const {
|
||||
const char *GetStart() const noexcept {
|
||||
return start.empty() ? nullptr : start.c_str();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetEnd() const {
|
||||
const char *GetEnd() const noexcept {
|
||||
return end.empty() ? nullptr : end.c_str();
|
||||
}
|
||||
|
||||
void SetStart(const char *new_value) {
|
||||
void SetStart(const char *new_value) noexcept {
|
||||
if (new_value == nullptr)
|
||||
start.clear();
|
||||
else
|
||||
start = new_value;
|
||||
}
|
||||
|
||||
void SetStart(std::string &&new_value) {
|
||||
void SetStart(std::string &&new_value) noexcept {
|
||||
start = std::move(new_value);
|
||||
}
|
||||
|
||||
void SetEnd(const char *new_value) {
|
||||
void SetEnd(const char *new_value) noexcept {
|
||||
if (new_value == nullptr)
|
||||
end.clear();
|
||||
else
|
||||
end = new_value;
|
||||
}
|
||||
|
||||
void SetEnd(std::string &&new_value) {
|
||||
void SetEnd(std::string &&new_value) noexcept {
|
||||
end = std::move(new_value);
|
||||
}
|
||||
};
|
||||
|
@@ -60,7 +60,7 @@ public:
|
||||
* music_buffer_new().
|
||||
*/
|
||||
gcc_pure
|
||||
unsigned GetSize() const {
|
||||
unsigned GetSize() const noexcept {
|
||||
return buffer.GetCapacity();
|
||||
}
|
||||
|
||||
|
@@ -79,12 +79,20 @@ struct MusicChunk {
|
||||
*/
|
||||
ReplayGainInfo replay_gain_info;
|
||||
|
||||
/**
|
||||
* A magic value for #replay_gain_serial which omits updating
|
||||
* the #ReplayGainFilter. This is used by "silence" chunks
|
||||
* (see PlayerThread::SendSilence()) so they don't affect the
|
||||
* replay gain.
|
||||
*/
|
||||
static constexpr unsigned IGNORE_REPLAY_GAIN = ~0u;
|
||||
|
||||
/**
|
||||
* A serial number for checking if replay gain info has
|
||||
* changed since the last chunk. The magic value 0 indicates
|
||||
* that there is no replay gain info available.
|
||||
*/
|
||||
unsigned replay_gain_serial = 0;
|
||||
unsigned replay_gain_serial;
|
||||
|
||||
/** the data (probably PCM) */
|
||||
uint8_t data[CHUNK_SIZE];
|
||||
|
@@ -39,7 +39,7 @@ MusicPipe::Contains(const MusicChunk *chunk) const noexcept
|
||||
#endif
|
||||
|
||||
MusicChunk *
|
||||
MusicPipe::Shift()
|
||||
MusicPipe::Shift() noexcept
|
||||
{
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
|
||||
@@ -73,7 +73,7 @@ MusicPipe::Shift()
|
||||
}
|
||||
|
||||
void
|
||||
MusicPipe::Clear(MusicBuffer &buffer)
|
||||
MusicPipe::Clear(MusicBuffer &buffer) noexcept
|
||||
{
|
||||
MusicChunk *chunk;
|
||||
|
||||
@@ -82,7 +82,7 @@ MusicPipe::Clear(MusicBuffer &buffer)
|
||||
}
|
||||
|
||||
void
|
||||
MusicPipe::Push(MusicChunk *chunk)
|
||||
MusicPipe::Push(MusicChunk *chunk) noexcept
|
||||
{
|
||||
assert(!chunk->IsEmpty());
|
||||
assert(chunk->length == 0 || chunk->audio_format.IsValid());
|
||||
|
@@ -77,7 +77,7 @@ public:
|
||||
* audio_format.
|
||||
*/
|
||||
gcc_pure
|
||||
bool CheckFormat(AudioFormat other) const {
|
||||
bool CheckFormat(AudioFormat other) const noexcept {
|
||||
return !audio_format.IsDefined() ||
|
||||
audio_format == other;
|
||||
}
|
||||
@@ -94,37 +94,37 @@ public:
|
||||
* nullptr if the pipe is empty.
|
||||
*/
|
||||
gcc_pure
|
||||
const MusicChunk *Peek() const {
|
||||
const MusicChunk *Peek() const noexcept {
|
||||
return head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first chunk from the head, and returns it.
|
||||
*/
|
||||
MusicChunk *Shift();
|
||||
MusicChunk *Shift() noexcept;
|
||||
|
||||
/**
|
||||
* Clears the whole pipe and returns the chunks to the buffer.
|
||||
*
|
||||
* @param buffer the buffer object to return the chunks to
|
||||
*/
|
||||
void Clear(MusicBuffer &buffer);
|
||||
void Clear(MusicBuffer &buffer) noexcept;
|
||||
|
||||
/**
|
||||
* Pushes a chunk to the tail of the pipe.
|
||||
*/
|
||||
void Push(MusicChunk *chunk);
|
||||
void Push(MusicChunk *chunk) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of chunks currently in this pipe.
|
||||
*/
|
||||
gcc_pure
|
||||
unsigned GetSize() const {
|
||||
unsigned GetSize() const noexcept {
|
||||
return size;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
return GetSize() == 0;
|
||||
}
|
||||
};
|
||||
|
@@ -207,13 +207,12 @@ try {
|
||||
continue;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t buffer[MAX_PATH];
|
||||
auto result = MultiByteToWideChar(CP_ACP, 0, s, -1,
|
||||
buffer, ARRAY_SIZE(buffer));
|
||||
if (result <= 0)
|
||||
/* on Windows, playlists always contain UTF-8, because
|
||||
its "narrow" charset (i.e. CP_ACP) is incapable of
|
||||
storing all Unicode paths */
|
||||
const auto path = AllocatedPath::FromUTF8(s);
|
||||
if (path.IsNull())
|
||||
continue;
|
||||
|
||||
const Path path = Path::FromFS(buffer);
|
||||
#else
|
||||
const Path path = Path::FromFS(s);
|
||||
#endif
|
||||
|
@@ -28,13 +28,25 @@
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "fs/NarrowPath.hxx"
|
||||
#include "fs/io/FileOutputStream.hxx"
|
||||
#include "fs/io/BufferedOutputStream.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
static void
|
||||
playlist_print_path(BufferedOutputStream &os, const Path path)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
/* on Windows, playlists always contain UTF-8, because its
|
||||
"narrow" charset (i.e. CP_ACP) is incapable of storing all
|
||||
Unicode paths */
|
||||
os.Format("%s\n", path.ToUTF8().c_str());
|
||||
#else
|
||||
os.Format("%s\n", path.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
playlist_print_song(BufferedOutputStream &os, const DetachedSong &song)
|
||||
{
|
||||
@@ -44,7 +56,7 @@ playlist_print_song(BufferedOutputStream &os, const DetachedSong &song)
|
||||
|
||||
try {
|
||||
const auto uri_fs = AllocatedPath::FromUTF8Throw(uri_utf8);
|
||||
os.Format("%s\n", NarrowPath(uri_fs).c_str());
|
||||
playlist_print_path(os, uri_fs);
|
||||
} catch (const std::runtime_error &) {
|
||||
}
|
||||
}
|
||||
@@ -63,7 +75,7 @@ playlist_print_uri(BufferedOutputStream &os, const char *uri)
|
||||
AllocatedPath::FromUTF8Throw(uri);
|
||||
|
||||
if (!path.IsNull())
|
||||
os.Format("%s\n", NarrowPath(path).c_str());
|
||||
playlist_print_path(os, path);
|
||||
} catch (const std::runtime_error &) {
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/TimeParser.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "lib/icu/Collate.hxx"
|
||||
#include "lib/icu/CaseFold.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -57,17 +57,10 @@ locate_parse_type(const char *str) noexcept
|
||||
return tag_name_parse_i(str);
|
||||
}
|
||||
|
||||
static AllocatedString<>
|
||||
ImportString(const char *p, bool fold_case)
|
||||
{
|
||||
return fold_case
|
||||
? IcuCaseFold(p)
|
||||
: AllocatedString<>::Duplicate(p);
|
||||
}
|
||||
|
||||
SongFilter::Item::Item(unsigned _tag, const char *_value, bool _fold_case)
|
||||
:tag(_tag), fold_case(_fold_case),
|
||||
value(ImportString(_value, _fold_case))
|
||||
:tag(_tag),
|
||||
value(AllocatedString<>::Duplicate(_value)),
|
||||
fold_case(_fold_case ? IcuCompare(value.c_str()) : IcuCompare())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -87,9 +80,7 @@ SongFilter::Item::StringMatch(const char *s) const noexcept
|
||||
assert(tag != LOCATE_TAG_MODIFIED_SINCE);
|
||||
|
||||
if (fold_case) {
|
||||
const auto folded = IcuCaseFold(s);
|
||||
assert(!folded.IsNull());
|
||||
return StringFind(folded.c_str(), value.c_str()) != nullptr;
|
||||
return fold_case.IsIn(s);
|
||||
} else {
|
||||
return StringIsEqual(s, value.c_str());
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#ifndef MPD_SONG_FILTER_HXX
|
||||
#define MPD_SONG_FILTER_HXX
|
||||
|
||||
#include "lib/icu/Compare.hxx"
|
||||
#include "util/AllocatedString.hxx"
|
||||
#include "Compiler.h"
|
||||
|
||||
@@ -48,10 +49,13 @@ public:
|
||||
class Item {
|
||||
uint8_t tag;
|
||||
|
||||
bool fold_case;
|
||||
|
||||
AllocatedString<> value;
|
||||
|
||||
/**
|
||||
* This value is only set if case folding is enabled.
|
||||
*/
|
||||
IcuCompare fold_case;
|
||||
|
||||
/**
|
||||
* For #LOCATE_TAG_MODIFIED_SINCE
|
||||
*/
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "fs/io/TextFile.hxx"
|
||||
#include "fs/io/FileOutputStream.hxx"
|
||||
#include "fs/io/BufferedOutputStream.hxx"
|
||||
#include "storage/StorageState.hxx"
|
||||
#include "Partition.hxx"
|
||||
#include "Instance.hxx"
|
||||
#include "mixer/Volume.hxx"
|
||||
@@ -56,6 +57,9 @@ StateFile::RememberVersions() noexcept
|
||||
prev_output_version = audio_output_state_get_version();
|
||||
prev_playlist_version = playlist_state_get_hash(partition.playlist,
|
||||
partition.pc);
|
||||
#ifdef ENABLE_DATABASE
|
||||
prev_storage_version = storage_state_get_hash(partition.instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -64,7 +68,11 @@ StateFile::IsModified() const noexcept
|
||||
return prev_volume_version != sw_volume_state_get_hash() ||
|
||||
prev_output_version != audio_output_state_get_version() ||
|
||||
prev_playlist_version != playlist_state_get_hash(partition.playlist,
|
||||
partition.pc);
|
||||
partition.pc)
|
||||
#ifdef ENABLE_DATABASE
|
||||
|| prev_storage_version != storage_state_get_hash(partition.instance)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
inline void
|
||||
@@ -72,6 +80,11 @@ StateFile::Write(BufferedOutputStream &os)
|
||||
{
|
||||
save_sw_volume_state(os);
|
||||
audio_output_state_save(os, partition.outputs);
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
storage_state_save(os, partition.instance);
|
||||
#endif
|
||||
|
||||
playlist_state_save(os, partition.playlist, partition.pc);
|
||||
}
|
||||
|
||||
@@ -123,6 +136,10 @@ try {
|
||||
playlist_state_restore(line, file, song_loader,
|
||||
partition.playlist,
|
||||
partition.pc);
|
||||
#ifdef ENABLE_DATABASE
|
||||
success = success || storage_state_restore(line, file, partition.instance);
|
||||
#endif
|
||||
|
||||
if (!success)
|
||||
FormatError(state_file_domain,
|
||||
"Unrecognized line in state file: %s",
|
||||
|
@@ -46,6 +46,10 @@ class StateFile final : private TimeoutMonitor {
|
||||
unsigned prev_volume_version = 0, prev_output_version = 0,
|
||||
prev_playlist_version = 0;
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
unsigned prev_storage_version = 0;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static constexpr std::chrono::steady_clock::duration DEFAULT_INTERVAL = std::chrono::minutes(2);
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
/**
|
||||
* The monotonic time stamp when MPD was started. It is used to
|
||||
* calculate the uptime.
|
||||
@@ -114,7 +114,7 @@ stats_print(Response &r, const Partition &partition)
|
||||
{
|
||||
r.Format("uptime: %u\n"
|
||||
"playtime: %lu\n",
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
GetProcessUptimeS(),
|
||||
#else
|
||||
(unsigned)std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - start_time).count(),
|
||||
|
@@ -24,7 +24,7 @@
|
||||
void
|
||||
time_print(Response &r, const char *name, time_t t)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
const struct tm *tm2 = gmtime(&t);
|
||||
#else
|
||||
struct tm tm;
|
||||
@@ -35,7 +35,7 @@ time_print(Response &r, const char *name, time_t t)
|
||||
|
||||
char buffer[32];
|
||||
strftime(buffer, sizeof(buffer),
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
"%Y-%m-%dT%H:%M:%SZ",
|
||||
#else
|
||||
"%FT%TZ",
|
||||
|
@@ -100,7 +100,7 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsExpired() const {
|
||||
bool IsExpired() const noexcept {
|
||||
return !FullyBufferedSocket::IsDefined();
|
||||
}
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
void
|
||||
Client::AllowFile(Path path_fs) const
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
(void)path_fs;
|
||||
|
||||
throw ProtocolError(ACK_ERROR_PERMISSION, "Access denied");
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* fuck WIN32! */
|
||||
#include <windows.h>
|
||||
#undef GetMessage
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#ifndef MPD_COMMAND_RESULT_HXX
|
||||
#define MPD_COMMAND_RESULT_HXX
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
/* damn you, windows.h! */
|
||||
#ifdef ERROR
|
||||
|
@@ -58,7 +58,7 @@ skip_path(Path name_fs) noexcept
|
||||
return name_fs.HasNewline();
|
||||
}
|
||||
|
||||
#if defined(WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
/* PRIu64 causes bogus compiler warning */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
@@ -101,7 +101,7 @@ handle_listfiles_local(Response &r, Path path_fs)
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
@@ -45,68 +45,57 @@ public:
|
||||
: default_value;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseInt(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgInt(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseInt(unsigned idx, int min_value, int max_value) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgInt(data[idx], min_value, max_value);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseUnsigned(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgUnsigned(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseUnsigned(unsigned idx, unsigned max_value) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgUnsigned(data[idx], max_value);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool ParseBool(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgBool(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
RangeArg ParseRange(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgRange(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
float ParseFloat(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgFloat(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
SongTime ParseSongTime(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgSongTime(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
SignedSongTime ParseSignedSongTime(unsigned idx) const {
|
||||
assert(idx < size);
|
||||
return ParseCommandArgSignedSongTime(data[idx]);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
int ParseOptional(unsigned idx, int default_value) const {
|
||||
return idx < size
|
||||
? ParseInt(idx)
|
||||
: default_value;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
RangeArg ParseOptional(unsigned idx, RangeArg default_value) const {
|
||||
return idx < size
|
||||
? ParseRange(idx)
|
||||
|
@@ -50,7 +50,7 @@ skip_path(const char *name_utf8) noexcept
|
||||
return strchr(name_utf8, '\n') != nullptr;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
/* PRIu64 causes bogus compiler warning */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
@@ -94,7 +94,7 @@ handle_listfiles_storage(Response &r, StorageDirectoryReader &reader)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
@@ -82,12 +82,12 @@ struct ConfigBlock {
|
||||
* object that was synthesized and not loaded from a
|
||||
* configuration file.
|
||||
*/
|
||||
bool IsNull() const {
|
||||
bool IsNull() const noexcept {
|
||||
return line < 0;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
return block_params.empty();
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
#if defined(WIN32) && CLANG_OR_GCC_VERSION(4,7)
|
||||
#if defined(_WIN32) && CLANG_OR_GCC_VERSION(4,7)
|
||||
/* "INPUT" is declared by winuser.h */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
@@ -93,7 +93,7 @@ enum class ConfigBlockOption {
|
||||
MAX
|
||||
};
|
||||
|
||||
#if defined(WIN32) && CLANG_OR_GCC_VERSION(4,7)
|
||||
#if defined(_WIN32) && CLANG_OR_GCC_VERSION(4,7)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <pwd.h>
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ ParsePath(const char *path)
|
||||
{
|
||||
assert(path != nullptr);
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
if (path[0] == '~') {
|
||||
++path;
|
||||
|
||||
@@ -119,7 +119,7 @@ ParsePath(const char *path)
|
||||
} else {
|
||||
#endif
|
||||
return AllocatedPath::FromUTF8Throw(path);
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
struct StringLess {
|
||||
gcc_pure
|
||||
bool operator()(const char *a, const char *b) const {
|
||||
bool operator()(const char *a, const char *b) const noexcept {
|
||||
return strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
@@ -106,7 +106,6 @@ public:
|
||||
TagType tag_type, tag_mask_t group_mask,
|
||||
VisitTag visit_tag) const = 0;
|
||||
|
||||
gcc_pure
|
||||
virtual DatabaseStats GetStats(const DatabaseSelection &selection) const = 0;
|
||||
|
||||
/**
|
||||
@@ -127,7 +126,7 @@ public:
|
||||
* Returns 0 if that is not not known/available.
|
||||
*/
|
||||
gcc_pure
|
||||
virtual time_t GetUpdateStamp() const = 0;
|
||||
virtual time_t GetUpdateStamp() const noexcept = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -44,16 +44,16 @@ struct LightDirectory {
|
||||
constexpr LightDirectory(const char *_uri, time_t _mtime)
|
||||
:uri(_uri), mtime(_mtime) {}
|
||||
|
||||
static constexpr LightDirectory Root() {
|
||||
static constexpr LightDirectory Root() noexcept {
|
||||
return LightDirectory("", 0);
|
||||
}
|
||||
|
||||
bool IsRoot() const {
|
||||
bool IsRoot() const noexcept {
|
||||
return *uri == 0;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetPath() const {
|
||||
const char *GetPath() const noexcept {
|
||||
return uri;
|
||||
}
|
||||
};
|
||||
|
@@ -45,7 +45,7 @@ struct PlaylistInfo {
|
||||
constexpr CompareName(const char *_name):name(_name) {}
|
||||
|
||||
gcc_pure
|
||||
bool operator()(const PlaylistInfo &pi) const {
|
||||
bool operator()(const PlaylistInfo &pi) const noexcept {
|
||||
return pi.name.compare(name) == 0;
|
||||
}
|
||||
};
|
||||
|
@@ -17,6 +17,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "Selection.hxx"
|
||||
#include "SongFilter.hxx"
|
||||
|
||||
|
@@ -127,7 +127,7 @@ public:
|
||||
|
||||
unsigned Update(const char *uri_utf8, bool discard) override;
|
||||
|
||||
time_t GetUpdateStamp() const override {
|
||||
time_t GetUpdateStamp() const noexcept override {
|
||||
return update_stamp;
|
||||
}
|
||||
|
||||
|
@@ -109,7 +109,7 @@ Directory::PruneEmpty() noexcept
|
||||
child != end;) {
|
||||
child->PruneEmpty();
|
||||
|
||||
if (child->IsEmpty())
|
||||
if (child->IsEmpty() && !child->IsMount())
|
||||
child = children.erase_and_dispose(child,
|
||||
DeleteDisposer());
|
||||
else
|
||||
@@ -230,7 +230,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
|
||||
call will lock it again */
|
||||
const ScopeDatabaseUnlock unlock;
|
||||
WalkMount(GetPath(), *mounted_database,
|
||||
recursive, filter,
|
||||
"", recursive, filter,
|
||||
visit_directory, visit_song,
|
||||
visit_playlist);
|
||||
return;
|
||||
|
@@ -127,7 +127,6 @@ public:
|
||||
*
|
||||
* @param name_utf8 the UTF-8 encoded name of the new sub directory
|
||||
*/
|
||||
gcc_malloc
|
||||
Directory *CreateChild(const char *name_utf8);
|
||||
|
||||
/**
|
||||
@@ -187,7 +186,7 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetPath() const {
|
||||
const char *GetPath() const noexcept {
|
||||
return path.c_str();
|
||||
}
|
||||
|
||||
|
@@ -72,7 +72,7 @@ PrefixVisitPlaylist(const char *base, const VisitPlaylist &visit_playlist,
|
||||
|
||||
void
|
||||
WalkMount(const char *base, const Database &db,
|
||||
bool recursive, const SongFilter *filter,
|
||||
const char* uri, bool recursive, const SongFilter *filter,
|
||||
const VisitDirectory &visit_directory, const VisitSong &visit_song,
|
||||
const VisitPlaylist &visit_playlist)
|
||||
{
|
||||
@@ -93,5 +93,5 @@ WalkMount(const char *base, const Database &db,
|
||||
vp = std::bind(PrefixVisitPlaylist,
|
||||
base, std::ref(visit_playlist), _1, _2);
|
||||
|
||||
db.Visit(DatabaseSelection("", recursive, filter), vd, vs, vp);
|
||||
db.Visit(DatabaseSelection(uri, recursive, filter), vd, vs, vp);
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ class SongFilter;
|
||||
|
||||
void
|
||||
WalkMount(const char *base, const Database &db,
|
||||
bool recursive, const SongFilter *filter,
|
||||
const char* uri, bool recursive, const SongFilter *filter,
|
||||
const VisitDirectory &visit_directory, const VisitSong &visit_song,
|
||||
const VisitPlaylist &visit_playlist);
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "SimpleDatabasePlugin.hxx"
|
||||
#include "PrefixedLightSong.hxx"
|
||||
#include "Mount.hxx"
|
||||
#include "db/DatabasePlugin.hxx"
|
||||
#include "db/Selection.hxx"
|
||||
#include "db/Helpers.hxx"
|
||||
@@ -115,7 +116,7 @@ SimpleDatabase::Check() const
|
||||
path_utf8 + "\" because the "
|
||||
"parent path is not a directory");
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
/* Check if we can write to the directory */
|
||||
if (!CheckAccess(dirPath, X_OK | W_OK)) {
|
||||
const int e = errno;
|
||||
@@ -134,7 +135,7 @@ SimpleDatabase::Check() const
|
||||
if (!fi.IsRegular())
|
||||
throw std::runtime_error("db file \"" + path_utf8 + "\" is not a regular file");
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
/* And check that we can write to it */
|
||||
if (!CheckAccess(path, R_OK | W_OK))
|
||||
throw FormatErrno("Can't open db file \"%s\" for reading/writing",
|
||||
@@ -270,6 +271,18 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
|
||||
ScopeDatabaseLock protect;
|
||||
|
||||
auto r = root->LookupDirectory(selection.uri.c_str());
|
||||
|
||||
if (r.directory->IsMount()) {
|
||||
/* pass the request and the remaining uri to the mounted database */
|
||||
protect.unlock();
|
||||
|
||||
WalkMount(r.directory->GetPath(), *(r.directory->mounted_database),
|
||||
(r.uri == nullptr)?"":r.uri, selection.recursive, selection.filter,
|
||||
visit_directory, visit_song, visit_playlist);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (r.uri == nullptr) {
|
||||
/* it's a directory */
|
||||
|
||||
|
@@ -76,7 +76,7 @@ public:
|
||||
const ConfigBlock &block);
|
||||
|
||||
gcc_pure
|
||||
Directory &GetRoot() {
|
||||
Directory &GetRoot() noexcept {
|
||||
assert(root != NULL);
|
||||
|
||||
return *root;
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
|
||||
DatabaseStats GetStats(const DatabaseSelection &selection) const override;
|
||||
|
||||
time_t GetUpdateStamp() const override {
|
||||
time_t GetUpdateStamp() const noexcept override {
|
||||
return mtime;
|
||||
}
|
||||
|
||||
|
@@ -60,7 +60,7 @@ public:
|
||||
* Parent's ObjectId
|
||||
*/
|
||||
std::string parent_id;
|
||||
|
||||
|
||||
std::string url;
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
UPnPDirObject &operator=(UPnPDirObject &&) = default;
|
||||
|
||||
void Clear() {
|
||||
void Clear() noexcept {
|
||||
id.clear();
|
||||
parent_id.clear();
|
||||
url.clear();
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool Check() const {
|
||||
bool Check() const noexcept {
|
||||
return !id.empty() && !parent_id.empty() && !name.empty() &&
|
||||
(type != UPnPDirObject::Type::ITEM ||
|
||||
item_class != UPnPDirObject::ItemClass::UNKNOWN);
|
||||
|
@@ -93,7 +93,7 @@ public:
|
||||
|
||||
DatabaseStats GetStats(const DatabaseSelection &selection) const override;
|
||||
|
||||
time_t GetUpdateStamp() const override {
|
||||
time_t GetUpdateStamp() const noexcept override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
ExcludeList::LoadFile(Path path_fs)
|
||||
ExcludeList::LoadFile(Path path_fs) noexcept
|
||||
try {
|
||||
#ifdef HAVE_CLASS_GLOB
|
||||
TextFile file(path_fs);
|
||||
@@ -67,7 +67,7 @@ try {
|
||||
}
|
||||
|
||||
bool
|
||||
ExcludeList::Check(Path name_fs) const
|
||||
ExcludeList::Check(Path name_fs) const noexcept
|
||||
{
|
||||
assert(!name_fs.IsNull());
|
||||
|
||||
|
@@ -50,7 +50,7 @@ public:
|
||||
:parent(&_parent) {}
|
||||
|
||||
gcc_pure
|
||||
bool IsEmpty() const {
|
||||
bool IsEmpty() const noexcept {
|
||||
#ifdef HAVE_CLASS_GLOB
|
||||
return ((parent == nullptr) || parent->IsEmpty()) && patterns.empty();
|
||||
#else
|
||||
@@ -62,13 +62,13 @@ public:
|
||||
/**
|
||||
* Loads and parses a .mpdignore file.
|
||||
*/
|
||||
bool LoadFile(Path path_fs);
|
||||
bool LoadFile(Path path_fs) noexcept;
|
||||
|
||||
/**
|
||||
* Checks whether one of the patterns in the .mpdignore file matches
|
||||
* the specified file name.
|
||||
*/
|
||||
bool Check(Path name_fs) const;
|
||||
bool Check(Path name_fs) const noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -91,7 +91,7 @@ bool
|
||||
directory_child_access(Storage &storage, const Directory &directory,
|
||||
const char *name, int mode) noexcept
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* CheckAccess() is useless on WIN32 */
|
||||
(void)storage;
|
||||
(void)directory;
|
||||
|
@@ -55,7 +55,7 @@ UpdateWalk::UpdateWalk(EventLoop &_loop, DatabaseListener &_listener,
|
||||
storage(_storage),
|
||||
editor(_loop, _listener)
|
||||
{
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
follow_inside_symlinks =
|
||||
config_get_bool(ConfigOption::FOLLOW_INSIDE_SYMLINKS,
|
||||
DEFAULT_FOLLOW_INSIDE_SYMLINKS);
|
||||
@@ -104,7 +104,7 @@ inline void
|
||||
UpdateWalk::PurgeDeletedFromDirectory(Directory &directory)
|
||||
{
|
||||
directory.ForEachChildSafe([&](Directory &child){
|
||||
if (DirectoryExists(storage, child))
|
||||
if (child.IsMount() || DirectoryExists(storage, child))
|
||||
return;
|
||||
|
||||
editor.LockDeleteDirectory(&child);
|
||||
@@ -133,7 +133,7 @@ UpdateWalk::PurgeDeletedFromDirectory(Directory &directory)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
static bool
|
||||
update_directory_stat(Storage &storage, Directory &directory)
|
||||
{
|
||||
@@ -156,7 +156,7 @@ static int
|
||||
FindAncestorLoop(Storage &storage, Directory *parent,
|
||||
unsigned inode, unsigned device)
|
||||
{
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
if (device == 0 && inode == 0)
|
||||
/* can't detect loops if the Storage does not support
|
||||
these numbers */
|
||||
@@ -258,7 +258,7 @@ bool
|
||||
UpdateWalk::SkipSymlink(const Directory *directory,
|
||||
const char *utf8_name) const noexcept
|
||||
{
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
const auto path_fs = storage.MapChildFS(directory->GetPath(),
|
||||
utf8_name);
|
||||
if (path_fs.IsNull())
|
||||
|
@@ -36,7 +36,7 @@ class UpdateWalk final {
|
||||
friend class UpdateArchiveVisitor;
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
static constexpr bool DEFAULT_FOLLOW_INSIDE_SYMLINKS = true;
|
||||
static constexpr bool DEFAULT_FOLLOW_OUTSIDE_SYMLINKS = true;
|
||||
|
||||
|
@@ -277,7 +277,7 @@ DecoderBridge::Ready(const AudioFormat audio_format,
|
||||
}
|
||||
|
||||
DecoderCommand
|
||||
DecoderBridge::GetCommand()
|
||||
DecoderBridge::GetCommand() noexcept
|
||||
{
|
||||
return LockGetVirtualCommand();
|
||||
}
|
||||
@@ -326,7 +326,7 @@ DecoderBridge::CommandFinished()
|
||||
}
|
||||
|
||||
SongTime
|
||||
DecoderBridge::GetSeekTime()
|
||||
DecoderBridge::GetSeekTime() noexcept
|
||||
{
|
||||
assert(dc.pipe != nullptr);
|
||||
|
||||
@@ -341,7 +341,7 @@ DecoderBridge::GetSeekTime()
|
||||
}
|
||||
|
||||
uint64_t
|
||||
DecoderBridge::GetSeekFrame()
|
||||
DecoderBridge::GetSeekFrame() noexcept
|
||||
{
|
||||
return GetSeekTime().ToScale<uint64_t>(dc.in_audio_format.sample_rate);
|
||||
}
|
||||
|
@@ -134,10 +134,10 @@ public:
|
||||
/* virtual methods from DecoderClient */
|
||||
void Ready(AudioFormat audio_format,
|
||||
bool seekable, SignedSongTime duration) override;
|
||||
DecoderCommand GetCommand() override;
|
||||
DecoderCommand GetCommand() noexcept override;
|
||||
void CommandFinished() override;
|
||||
SongTime GetSeekTime() override;
|
||||
uint64_t GetSeekFrame() override;
|
||||
SongTime GetSeekTime() noexcept override;
|
||||
uint64_t GetSeekFrame() noexcept override;
|
||||
void SeekError() override;
|
||||
InputStreamPtr OpenUri(const char *uri) override;
|
||||
size_t Read(InputStream &is, void *buffer, size_t length) override;
|
||||
|
@@ -58,7 +58,7 @@ public:
|
||||
* command pending
|
||||
*/
|
||||
gcc_pure
|
||||
virtual DecoderCommand GetCommand() = 0;
|
||||
virtual DecoderCommand GetCommand() noexcept = 0;
|
||||
|
||||
/**
|
||||
* Called by the decoder when it has performed the requested command
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
* @return the destination position for the seek in milliseconds
|
||||
*/
|
||||
gcc_pure
|
||||
virtual SongTime GetSeekTime() = 0;
|
||||
virtual SongTime GetSeekTime() noexcept = 0;
|
||||
|
||||
/**
|
||||
* Call this when you have received the DecoderCommand::SEEK command.
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
* @return the destination position for the seek in frames
|
||||
*/
|
||||
gcc_pure
|
||||
virtual uint64_t GetSeekFrame() = 0;
|
||||
virtual uint64_t GetSeekFrame() noexcept = 0;
|
||||
|
||||
/**
|
||||
* Call this instead of CommandFinished() when seeking has
|
||||
|
@@ -54,11 +54,11 @@ public:
|
||||
size_t _size)
|
||||
:client(_client), is(_is), buffer(_size) {}
|
||||
|
||||
const InputStream &GetStream() const {
|
||||
const InputStream &GetStream() const noexcept {
|
||||
return is;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
void Clear() noexcept {
|
||||
buffer.Clear();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
* How many bytes are stored in the buffer?
|
||||
*/
|
||||
gcc_pure
|
||||
size_t GetAvailable() const {
|
||||
size_t GetAvailable() const noexcept {
|
||||
return buffer.GetAvailable();
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
* you have to call Consume() to do that. The returned buffer
|
||||
* becomes invalid after a Fill() or a Consume() call.
|
||||
*/
|
||||
ConstBuffer<void> Read() const {
|
||||
ConstBuffer<void> Read() const noexcept {
|
||||
auto r = buffer.Read();
|
||||
return { r.data, r.size };
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
*
|
||||
* @param nbytes the number of bytes to consume
|
||||
*/
|
||||
void Consume(size_t nbytes) {
|
||||
void Consume(size_t nbytes) noexcept {
|
||||
buffer.Consume(nbytes);
|
||||
}
|
||||
|
||||
|
@@ -227,29 +227,29 @@ struct DecoderControl {
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool LockIsIdle() const {
|
||||
bool LockIsIdle() const noexcept {
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
return IsIdle();
|
||||
}
|
||||
|
||||
bool IsStarting() const {
|
||||
bool IsStarting() const noexcept {
|
||||
return state == DecoderState::START;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool LockIsStarting() const {
|
||||
bool LockIsStarting() const noexcept {
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
return IsStarting();
|
||||
}
|
||||
|
||||
bool HasFailed() const {
|
||||
bool HasFailed() const noexcept {
|
||||
assert(command == DecoderCommand::NONE);
|
||||
|
||||
return state == DecoderState::ERROR;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool LockHasFailed() const {
|
||||
bool LockHasFailed() const noexcept {
|
||||
const std::lock_guard<Mutex> protect(mutex);
|
||||
return HasFailed();
|
||||
}
|
||||
|
@@ -508,6 +508,7 @@ try {
|
||||
decoder_run_song(dc, song, uri_utf8, path_fs);
|
||||
} catch (...) {
|
||||
dc.state = DecoderState::ERROR;
|
||||
dc.command = DecoderCommand::NONE;
|
||||
dc.error = std::current_exception();
|
||||
dc.client_cond.signal();
|
||||
}
|
||||
|
@@ -258,7 +258,7 @@ FfmpegSendFrame(DecoderClient &client, InputStream &is,
|
||||
try {
|
||||
output_buffer = copy_interleave_frame(codec_context, frame,
|
||||
buffer);
|
||||
} catch (const std::exception e) {
|
||||
} catch (const std::exception &e) {
|
||||
/* this must be a serious error, e.g. OOM */
|
||||
LogError(e);
|
||||
return DecoderCommand::STOP;
|
||||
@@ -712,7 +712,9 @@ FfmpegDecode(DecoderClient &client, InputStream &input,
|
||||
#endif
|
||||
|
||||
const SignedSongTime total_time =
|
||||
FromFfmpegTimeChecked(av_stream.duration, av_stream.time_base);
|
||||
av_stream.duration != (int64_t)AV_NOPTS_VALUE
|
||||
? FromFfmpegTimeChecked(av_stream.duration, av_stream.time_base)
|
||||
: FromFfmpegTimeChecked(format_context.duration, AV_TIME_BASE_Q);
|
||||
|
||||
client.Ready(audio_format, input.IsSeekable(), total_time);
|
||||
|
||||
@@ -842,6 +844,10 @@ FfmpegScanStream(AVFormatContext &format_context,
|
||||
tag_handler_invoke_duration(handler, handler_ctx,
|
||||
FromFfmpegTime(stream.duration,
|
||||
stream.time_base));
|
||||
else if (format_context.duration != (int64_t)AV_NOPTS_VALUE)
|
||||
tag_handler_invoke_duration(handler, handler_ctx,
|
||||
FromFfmpegTime(format_context.duration,
|
||||
AV_TIME_BASE_Q));
|
||||
|
||||
FfmpegScanMetadata(format_context, audio_stream, handler, handler_ctx);
|
||||
|
||||
@@ -881,7 +887,8 @@ ffmpeg_scan_stream(InputStream &is,
|
||||
* more formats.
|
||||
*/
|
||||
static const char *const ffmpeg_suffixes[] = {
|
||||
"16sv", "3g2", "3gp", "4xm", "8svx", "aa3", "aac", "ac3", "afc", "aif",
|
||||
"16sv", "3g2", "3gp", "4xm", "8svx",
|
||||
"aa3", "aac", "ac3", "adx", "afc", "aif",
|
||||
"aifc", "aiff", "al", "alaw", "amr", "anim", "apc", "ape", "asf",
|
||||
"atrac", "au", "aud", "avi", "avm2", "avs", "bap", "bfi", "c93", "cak",
|
||||
"cin", "cmv", "cpk", "daud", "dct", "divx", "dts", "dv", "dvd", "dxa",
|
||||
@@ -934,6 +941,7 @@ static const char *const ffmpeg_mime_types[] = {
|
||||
"audio/x-16sv",
|
||||
"audio/x-aac",
|
||||
"audio/x-ac3",
|
||||
"audio/x-adx",
|
||||
"audio/x-aiff"
|
||||
"audio/x-alaw",
|
||||
"audio/x-au",
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "FfmpegMetaData.hxx"
|
||||
#include "tag/TagTable.hxx"
|
||||
#include "tag/TagHandler.hxx"
|
||||
#include "tag/Id3MusicBrainz.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/dict.h>
|
||||
@@ -75,6 +76,11 @@ FfmpegScanDictionary(AVDictionary *dict,
|
||||
i->name != nullptr; ++i)
|
||||
FfmpegScanTag(i->type, dict, i->name,
|
||||
handler, handler_ctx);
|
||||
|
||||
for (const struct tag_table *i = musicbrainz_txxx_tags;
|
||||
i->name != nullptr; ++i)
|
||||
FfmpegScanTag(i->type, dict, i->name,
|
||||
handler, handler_ctx);
|
||||
}
|
||||
|
||||
if (handler.pair != nullptr)
|
||||
|
@@ -46,7 +46,7 @@ FlacIORead(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
|
||||
|
||||
p += nbytes;
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
} catch (const std::system_error &e) {
|
||||
errno = e.code().category() == ErrnoCategory()
|
||||
? e.code().value()
|
||||
|
@@ -42,25 +42,27 @@ public:
|
||||
return chain;
|
||||
}
|
||||
|
||||
bool Read(const char *path) {
|
||||
bool Read(const char *path) noexcept {
|
||||
return ::FLAC__metadata_chain_read(chain, path);
|
||||
}
|
||||
|
||||
bool Read(FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) {
|
||||
bool Read(FLAC__IOHandle handle,
|
||||
FLAC__IOCallbacks callbacks) noexcept {
|
||||
return ::FLAC__metadata_chain_read_with_callbacks(chain,
|
||||
handle,
|
||||
callbacks);
|
||||
}
|
||||
|
||||
bool Read(InputStream &is) {
|
||||
bool Read(InputStream &is) noexcept {
|
||||
return Read(::ToFlacIOHandle(is), ::GetFlacIOCallbacks(is));
|
||||
}
|
||||
|
||||
bool ReadOgg(const char *path) {
|
||||
bool ReadOgg(const char *path) noexcept {
|
||||
return ::FLAC__metadata_chain_read_ogg(chain, path);
|
||||
}
|
||||
|
||||
bool ReadOgg(FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) {
|
||||
bool ReadOgg(FLAC__IOHandle handle,
|
||||
FLAC__IOCallbacks callbacks) noexcept {
|
||||
return ::FLAC__metadata_chain_read_ogg_with_callbacks(chain,
|
||||
handle,
|
||||
callbacks);
|
||||
@@ -71,12 +73,12 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
FLAC__Metadata_ChainStatus GetStatus() const {
|
||||
FLAC__Metadata_ChainStatus GetStatus() const noexcept {
|
||||
return ::FLAC__metadata_chain_status(chain);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
const char *GetStatusString() const {
|
||||
const char *GetStatusString() const noexcept {
|
||||
return FLAC__Metadata_ChainStatusString[GetStatus()];
|
||||
}
|
||||
|
||||
@@ -99,12 +101,12 @@ public:
|
||||
::FLAC__metadata_iterator_delete(iterator);
|
||||
}
|
||||
|
||||
bool Next() {
|
||||
bool Next() noexcept {
|
||||
return ::FLAC__metadata_iterator_next(iterator);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
FLAC__StreamMetadata *GetBlock() {
|
||||
FLAC__StreamMetadata *GetBlock() noexcept {
|
||||
return ::FLAC__metadata_iterator_get_block(iterator);
|
||||
}
|
||||
};
|
||||
|
@@ -293,13 +293,13 @@ gme_container_scan(Path path_fs)
|
||||
TagBuilder tag_builder;
|
||||
|
||||
auto tail = list.before_begin();
|
||||
for (unsigned i = 1; i <= num_songs; ++i) {
|
||||
for (unsigned i = 0; i < num_songs; ++i) {
|
||||
ScanMusicEmu(emu, i,
|
||||
add_tag_handler, &tag_builder);
|
||||
|
||||
char track_name[64];
|
||||
snprintf(track_name, sizeof(track_name),
|
||||
SUBTUNE_PREFIX "%03u.%s", i, subtune_suffix);
|
||||
SUBTUNE_PREFIX "%03u.%s", i+1, subtune_suffix);
|
||||
tail = list.emplace_after(tail, track_name,
|
||||
tag_builder.Commit());
|
||||
}
|
||||
|
@@ -52,14 +52,14 @@ static constexpr unsigned opus_output_buffer_frames = opus_sample_rate / 4;
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsOpusHead(const ogg_packet &packet)
|
||||
IsOpusHead(const ogg_packet &packet) noexcept
|
||||
{
|
||||
return packet.bytes >= 8 && memcmp(packet.packet, "OpusHead", 8) == 0;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsOpusTags(const ogg_packet &packet)
|
||||
IsOpusTags(const ogg_packet &packet) noexcept
|
||||
{
|
||||
return packet.bytes >= 8 && memcmp(packet.packet, "OpusTags", 8) == 0;
|
||||
}
|
||||
|
@@ -178,6 +178,20 @@ VorbisDecoder::SubmitInit()
|
||||
client.Ready(audio_format, eos_granulepos > 0, duration);
|
||||
}
|
||||
|
||||
#ifdef HAVE_TREMOR
|
||||
static inline int16_t tremor_clip_sample(int32_t x)
|
||||
{
|
||||
x >>= 9;
|
||||
|
||||
if (x < INT16_MIN)
|
||||
return INT16_MIN;
|
||||
if (x > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
VorbisDecoder::SubmitSomePcm()
|
||||
{
|
||||
@@ -197,7 +211,7 @@ VorbisDecoder::SubmitSomePcm()
|
||||
auto *dest = &buffer[c];
|
||||
|
||||
for (size_t i = 0; i < n_frames; ++i) {
|
||||
*dest = *src++;
|
||||
*dest = tremor_clip_sample(*src++);
|
||||
dest += channels;
|
||||
}
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@ private:
|
||||
};
|
||||
|
||||
class PreparedVorbisEncoder final : public PreparedEncoder {
|
||||
float quality;
|
||||
float quality = 3;
|
||||
int bitrate;
|
||||
|
||||
public:
|
||||
@@ -97,7 +97,7 @@ PreparedVorbisEncoder::PreparedVorbisEncoder(const ConfigBlock &block)
|
||||
|
||||
value = block.GetBlockValue("bitrate");
|
||||
if (value == nullptr)
|
||||
throw std::runtime_error("neither bitrate nor quality defined");
|
||||
return;
|
||||
|
||||
quality = -2.0;
|
||||
|
||||
|
@@ -199,7 +199,7 @@ public:
|
||||
* Are we currently running inside this EventLoop's thread?
|
||||
*/
|
||||
gcc_pure
|
||||
bool IsInside() const {
|
||||
bool IsInside() const noexcept {
|
||||
assert(!thread.IsNull());
|
||||
|
||||
return thread.IsInside();
|
||||
@@ -207,7 +207,7 @@ public:
|
||||
|
||||
#ifndef NDEBUG
|
||||
gcc_pure
|
||||
bool IsInsideOrVirgin() const {
|
||||
bool IsInsideOrVirgin() const noexcept {
|
||||
return virgin || IsInside();
|
||||
}
|
||||
#endif
|
||||
@@ -219,7 +219,7 @@ public:
|
||||
* are not yet/anymore handled.
|
||||
*/
|
||||
gcc_pure
|
||||
bool IsInsideOrNull() const {
|
||||
bool IsInsideOrNull() const noexcept {
|
||||
return thread.IsNull() || thread.IsInside();
|
||||
}
|
||||
};
|
||||
|
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,7 @@ MultiSocketMonitor::ClearSocketList()
|
||||
fds.clear();
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
|
||||
void
|
||||
MultiSocketMonitor::ReplaceSocketList(pollfd *pfds, unsigned n)
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* ERROR is a WIN32 macro that poisons our namespace; this is a kludge
|
||||
to allow us to use it anyway */
|
||||
#ifdef ERROR
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
struct pollfd;
|
||||
#endif
|
||||
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
/**
|
||||
* Replace the socket list with the given file descriptors.
|
||||
* The given pollfd array will be modified by this method.
|
||||
|
@@ -43,7 +43,7 @@
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#include <winsock.h>
|
||||
#else
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "SignalMonitor.hxx"
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "SocketMonitor.hxx"
|
||||
#include "util/Manual.hxx"
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
class EventLoop;
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "util/BindMethod.hxx"
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* ERROR is a WIN32 macro that poisons our namespace; this is a kludge
|
||||
to allow us to use it anyway */
|
||||
#ifdef ERROR
|
||||
|
@@ -31,7 +31,7 @@ AllocatedPath::~AllocatedPath() {}
|
||||
AllocatedPath
|
||||
AllocatedPath::FromUTF8(const char *path_utf8) noexcept
|
||||
{
|
||||
#if defined(HAVE_FS_CHARSET) || defined(WIN32)
|
||||
#if defined(HAVE_FS_CHARSET) || defined(_WIN32)
|
||||
try {
|
||||
return AllocatedPath(::PathFromUTF8(path_utf8));
|
||||
} catch (const std::runtime_error &) {
|
||||
@@ -45,7 +45,7 @@ AllocatedPath::FromUTF8(const char *path_utf8) noexcept
|
||||
AllocatedPath
|
||||
AllocatedPath::FromUTF8Throw(const char *path_utf8)
|
||||
{
|
||||
#if defined(HAVE_FS_CHARSET) || defined(WIN32)
|
||||
#if defined(HAVE_FS_CHARSET) || defined(_WIN32)
|
||||
return AllocatedPath(::PathFromUTF8(path_utf8));
|
||||
#else
|
||||
return FromFS(path_utf8);
|
||||
|
@@ -77,12 +77,12 @@ public:
|
||||
* @see IsNull()
|
||||
*/
|
||||
gcc_const
|
||||
static AllocatedPath Null() {
|
||||
static AllocatedPath Null() noexcept {
|
||||
return AllocatedPath(nullptr);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
operator Path() const {
|
||||
operator Path() const noexcept {
|
||||
return Path::FromFS(c_str());
|
||||
}
|
||||
|
||||
@@ -90,36 +90,39 @@ public:
|
||||
* Join two path components with the path separator.
|
||||
*/
|
||||
gcc_pure gcc_nonnull_all
|
||||
static AllocatedPath Build(const_pointer_type a, const_pointer_type b) {
|
||||
static AllocatedPath Build(const_pointer_type a,
|
||||
const_pointer_type b) noexcept {
|
||||
return Build(a, PathTraitsFS::GetLength(a),
|
||||
b, PathTraitsFS::GetLength(b));
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
static AllocatedPath Build(Path a, const_pointer_type b) {
|
||||
static AllocatedPath Build(Path a, const_pointer_type b) noexcept {
|
||||
return Build(a.c_str(), b);
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
static AllocatedPath Build(Path a, Path b) {
|
||||
static AllocatedPath Build(Path a, Path b) noexcept {
|
||||
return Build(a, b.c_str());
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
static AllocatedPath Build(const_pointer_type a, const AllocatedPath &b) {
|
||||
static AllocatedPath Build(const_pointer_type a,
|
||||
const AllocatedPath &b) noexcept {
|
||||
return Build(a, PathTraitsFS::GetLength(a),
|
||||
b.value.c_str(), b.value.size());
|
||||
}
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
static AllocatedPath Build(const AllocatedPath &a, const_pointer_type b) {
|
||||
static AllocatedPath Build(const AllocatedPath &a,
|
||||
const_pointer_type b) noexcept {
|
||||
return Build(a.value.c_str(), a.value.size(),
|
||||
b, PathTraitsFS::GetLength(b));
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static AllocatedPath Build(const AllocatedPath &a,
|
||||
const AllocatedPath &b) {
|
||||
const AllocatedPath &b) noexcept {
|
||||
return Build(a.value.c_str(), a.value.size(),
|
||||
b.value.c_str(), b.value.size());
|
||||
}
|
||||
@@ -129,13 +132,13 @@ public:
|
||||
* character set to a #Path instance.
|
||||
*/
|
||||
gcc_pure
|
||||
static AllocatedPath FromFS(const_pointer_type fs) {
|
||||
static AllocatedPath FromFS(const_pointer_type fs) noexcept {
|
||||
return AllocatedPath(fs);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static AllocatedPath FromFS(const_pointer_type _begin,
|
||||
const_pointer_type _end) {
|
||||
const_pointer_type _end) noexcept {
|
||||
return AllocatedPath(_begin, _end);
|
||||
}
|
||||
|
||||
@@ -144,7 +147,7 @@ public:
|
||||
* character set to a #Path instance.
|
||||
*/
|
||||
gcc_pure
|
||||
static AllocatedPath FromFS(string &&fs) {
|
||||
static AllocatedPath FromFS(string &&fs) noexcept {
|
||||
return AllocatedPath(std::move(fs));
|
||||
}
|
||||
|
||||
@@ -176,12 +179,12 @@ public:
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool operator==(const AllocatedPath &other) const {
|
||||
bool operator==(const AllocatedPath &other) const noexcept {
|
||||
return value == other.value;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool operator!=(const AllocatedPath &other) const {
|
||||
bool operator!=(const AllocatedPath &other) const noexcept {
|
||||
return value != other.value;
|
||||
}
|
||||
|
||||
@@ -197,7 +200,7 @@ public:
|
||||
* Check if this is a "nulled" instance. A "nulled" instance
|
||||
* must not be used.
|
||||
*/
|
||||
bool IsNull() const {
|
||||
bool IsNull() const noexcept {
|
||||
return value.empty();
|
||||
}
|
||||
|
||||
@@ -206,7 +209,7 @@ public:
|
||||
*
|
||||
* @see IsNull()
|
||||
*/
|
||||
void SetNull() {
|
||||
void SetNull() noexcept {
|
||||
value.clear();
|
||||
}
|
||||
|
||||
@@ -215,7 +218,7 @@ public:
|
||||
* elements (which may not be the number of characters).
|
||||
*/
|
||||
gcc_pure
|
||||
size_t length() const {
|
||||
size_t length() const noexcept {
|
||||
return value.length();
|
||||
}
|
||||
|
||||
@@ -225,7 +228,7 @@ public:
|
||||
* instance ends.
|
||||
*/
|
||||
gcc_pure
|
||||
const_pointer_type c_str() const {
|
||||
const_pointer_type c_str() const noexcept {
|
||||
return value.c_str();
|
||||
}
|
||||
|
||||
@@ -234,7 +237,7 @@ public:
|
||||
* null-terminated.
|
||||
*/
|
||||
gcc_pure
|
||||
const_pointer_type data() const {
|
||||
const_pointer_type data() const noexcept {
|
||||
return value.data();
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include "lib/icu/Converter.hxx"
|
||||
#include "util/AllocatedString.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include "lib/icu/Win32.hxx"
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@@ -70,7 +70,7 @@ GetFSCharset() noexcept
|
||||
{
|
||||
#ifdef HAVE_FS_CHARSET
|
||||
return fs_charset.empty() ? "UTF-8" : fs_charset.c_str();
|
||||
#elif defined(WIN32)
|
||||
#elif defined(_WIN32)
|
||||
return "ACP";
|
||||
#else
|
||||
return "UTF-8";
|
||||
@@ -100,7 +100,7 @@ PathToUTF8(PathTraitsFS::const_pointer_type path_fs)
|
||||
assert(path_fs != nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
const auto buffer = WideCharToMultiByte(CP_UTF8, path_fs);
|
||||
return FixSeparators(PathTraitsUTF8::string(buffer.c_str()));
|
||||
#else
|
||||
@@ -116,7 +116,7 @@ PathToUTF8(PathTraitsFS::const_pointer_type path_fs)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_FS_CHARSET) || defined(WIN32)
|
||||
#if defined(HAVE_FS_CHARSET) || defined(_WIN32)
|
||||
|
||||
PathTraitsFS::string
|
||||
PathFromUTF8(PathTraitsUTF8::const_pointer_type path_utf8)
|
||||
@@ -126,7 +126,7 @@ PathFromUTF8(PathTraitsUTF8::const_pointer_type path_utf8)
|
||||
assert(path_utf8 != nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
const auto buffer = MultiByteToWideChar(CP_UTF8, path_utf8);
|
||||
return PathTraitsFS::string(buffer.c_str());
|
||||
#else
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include "Compiler.h"
|
||||
#include "Traits.hxx"
|
||||
|
||||
#if (defined(HAVE_ICU) || defined(HAVE_ICONV)) && !defined(WIN32)
|
||||
#if (defined(HAVE_ICU) || defined(HAVE_ICONV)) && !defined(_WIN32)
|
||||
#define HAVE_FS_CHARSET
|
||||
#endif
|
||||
|
||||
|
@@ -41,7 +41,7 @@ try {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
try {
|
||||
const auto x = AllocatedPath::Build(path_fs,
|
||||
PathTraitsFS::CURRENT_DIRECTORY);
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#include "DirectoryReader.hxx"
|
||||
#include "system/Error.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
DirectoryReader::DirectoryReader(Path dir)
|
||||
:handle(FindFirstFile(MakeWildcardPath(dir.c_str()), &data))
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include "check.h"
|
||||
#include "Path.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
@@ -26,13 +26,13 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <fileapi.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
static inline constexpr uint64_t
|
||||
ConstructUint64(DWORD lo, DWORD hi)
|
||||
@@ -54,7 +54,7 @@ class FileInfo {
|
||||
bool follow_symlinks);
|
||||
friend class FileReader;
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
#else
|
||||
struct stat st;
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
FileInfo(Path path, bool follow_symlinks=true) {
|
||||
if (!GetFileInfo(path, *this, follow_symlinks)) {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
throw FormatLastError("Failed to access %s",
|
||||
path.ToUTF8().c_str());
|
||||
#else
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
}
|
||||
|
||||
bool IsRegular() const {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return (data.dwFileAttributes &
|
||||
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE)) == 0;
|
||||
#else
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
}
|
||||
|
||||
bool IsDirectory() const {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
#else
|
||||
return S_ISDIR(st.st_mode);
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
}
|
||||
|
||||
uint64_t GetSize() const {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return ConstructUint64(data.nFileSizeLow, data.nFileSizeHigh);
|
||||
#else
|
||||
return st.st_size;
|
||||
@@ -101,14 +101,14 @@ public:
|
||||
}
|
||||
|
||||
time_t GetModificationTime() const {
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return FileTimeToTimeT(data.ftLastWriteTime);
|
||||
#else
|
||||
return st.st_mtime;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
uid_t GetUid() const {
|
||||
return st.st_uid;
|
||||
}
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
inline bool
|
||||
GetFileInfo(Path path, FileInfo &info, bool follow_symlinks=true)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
(void)follow_symlinks;
|
||||
return GetFileAttributesEx(path.c_str(), GetFileExInfoStandard,
|
||||
&info.data);
|
||||
|
@@ -29,7 +29,7 @@
|
||||
void
|
||||
RenameFile(Path oldpath, Path newpath)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
if (!MoveFileEx(oldpath.c_str(), newpath.c_str(),
|
||||
MOVEFILE_REPLACE_EXISTING))
|
||||
throw MakeLastError("Failed to rename file");
|
||||
@@ -42,7 +42,7 @@ RenameFile(Path oldpath, Path newpath)
|
||||
AllocatedPath
|
||||
ReadLink(Path path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
(void)path;
|
||||
errno = EINVAL;
|
||||
return AllocatedPath::Null();
|
||||
@@ -63,7 +63,7 @@ ReadLink(Path path)
|
||||
void
|
||||
TruncateFile(Path path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr,
|
||||
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr);
|
||||
@@ -83,7 +83,7 @@ TruncateFile(Path path)
|
||||
void
|
||||
RemoveFile(Path path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
if (!DeleteFile(path.c_str()))
|
||||
throw FormatLastError("Failed to delete %s", path.c_str());
|
||||
#else
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "Path.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <fileapi.h>
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,7 @@ class AllocatedPath;
|
||||
static inline FILE *
|
||||
FOpen(Path file, PathTraitsFS::const_pointer_type mode)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return _tfopen(file.c_str(), mode);
|
||||
#else
|
||||
return fopen(file.c_str(), mode);
|
||||
@@ -56,7 +56,7 @@ FOpen(Path file, PathTraitsFS::const_pointer_type mode)
|
||||
static inline int
|
||||
OpenFile(Path file, int flags, int mode)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return _topen(file.c_str(), flags, mode);
|
||||
#else
|
||||
return open_cloexec(file.c_str(), flags, mode);
|
||||
@@ -71,7 +71,7 @@ OpenFile(Path file, int flags, int mode)
|
||||
void
|
||||
RenameFile(Path oldpath, Path newpath);
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
|
||||
/**
|
||||
* Wrapper for stat() that uses #Path names.
|
||||
@@ -107,7 +107,7 @@ RemoveFile(Path path);
|
||||
AllocatedPath
|
||||
ReadLink(Path path);
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
|
||||
static inline bool
|
||||
MakeFifo(Path path, mode_t mode)
|
||||
@@ -132,7 +132,7 @@ CheckAccess(Path path, int mode)
|
||||
static inline bool
|
||||
FileExists(Path path, bool follow_symlinks = true)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
(void)follow_symlinks;
|
||||
|
||||
const auto a = GetFileAttributes(path.c_str());
|
||||
@@ -150,7 +150,7 @@ FileExists(Path path, bool follow_symlinks = true)
|
||||
static inline bool
|
||||
DirectoryExists(Path path, bool follow_symlinks = true)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
(void)follow_symlinks;
|
||||
|
||||
const auto a = GetFileAttributes(path.c_str());
|
||||
@@ -167,7 +167,7 @@ DirectoryExists(Path path, bool follow_symlinks = true)
|
||||
static inline bool
|
||||
PathExists(Path path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES;
|
||||
#else
|
||||
return CheckAccess(path, F_OK);
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#define HAVE_CLASS_GLOB
|
||||
#include <string>
|
||||
#include <fnmatch.h>
|
||||
#elif defined(WIN32)
|
||||
#elif defined(_WIN32)
|
||||
#define HAVE_CLASS_GLOB
|
||||
#include <string>
|
||||
#include <shlwapi.h>
|
||||
@@ -40,12 +40,12 @@
|
||||
* (asterisk and question mark).
|
||||
*/
|
||||
class Glob {
|
||||
#if defined(HAVE_FNMATCH) || defined(WIN32)
|
||||
#if defined(HAVE_FNMATCH) || defined(_WIN32)
|
||||
std::string pattern;
|
||||
#endif
|
||||
|
||||
public:
|
||||
#if defined(HAVE_FNMATCH) || defined(WIN32)
|
||||
#if defined(HAVE_FNMATCH) || defined(_WIN32)
|
||||
explicit Glob(const char *_pattern)
|
||||
:pattern(_pattern) {}
|
||||
|
||||
@@ -54,10 +54,10 @@ public:
|
||||
#endif
|
||||
|
||||
gcc_pure
|
||||
bool Check(const char *name_fs) const {
|
||||
bool Check(const char *name_fs) const noexcept {
|
||||
#ifdef HAVE_FNMATCH
|
||||
return fnmatch(pattern.c_str(), name_fs, 0) == 0;
|
||||
#elif defined(WIN32)
|
||||
#elif defined(_WIN32)
|
||||
return PathMatchSpecA(name_fs, pattern.c_str());
|
||||
#endif
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#if defined(_WIN32)
|
||||
static constexpr size_t MPD_PATH_MAX = 260;
|
||||
#elif defined(MAXPATHLEN)
|
||||
static constexpr size_t MPD_PATH_MAX = MAXPATHLEN;
|
||||
|
@@ -92,7 +92,7 @@ public:
|
||||
* elements (which may not be the number of characters).
|
||||
*/
|
||||
gcc_pure
|
||||
size_t length() const {
|
||||
size_t length() const noexcept {
|
||||
assert(!IsNull());
|
||||
|
||||
return PathTraitsFS::GetLength(c_str());
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
* instance ends.
|
||||
*/
|
||||
gcc_pure
|
||||
const_pointer_type c_str() const {
|
||||
const_pointer_type c_str() const noexcept {
|
||||
return Base::c_str();
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
* null-terminated.
|
||||
*/
|
||||
gcc_pure
|
||||
const_pointer_type data() const {
|
||||
const_pointer_type data() const noexcept {
|
||||
return c_str();
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include "config.h"
|
||||
|
||||
// Use X Desktop guidelines where applicable
|
||||
#if !defined(__APPLE__) && !defined(WIN32) && !defined(ANDROID)
|
||||
#if !defined(__APPLE__) && !defined(_WIN32) && !defined(ANDROID)
|
||||
#define USE_XDG
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#else
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "Main.hxx"
|
||||
#endif
|
||||
|
||||
#if !defined(WIN32) && !defined(ANDROID)
|
||||
#if !defined(_WIN32) && !defined(ANDROID)
|
||||
class PasswdEntry
|
||||
{
|
||||
#if defined(HAVE_GETPWNAM_R) || defined(HAVE_GETPWUID_R)
|
||||
@@ -113,7 +113,7 @@ SafePathFromFS(PathTraitsFS::const_pointer_type dir)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
static AllocatedPath GetStandardDir(int folder_id)
|
||||
{
|
||||
std::array<PathTraitsFS::value_type, MAX_PATH> dir;
|
||||
@@ -226,7 +226,7 @@ try {
|
||||
AllocatedPath
|
||||
GetUserConfigDir() noexcept
|
||||
{
|
||||
#if defined(WIN32)
|
||||
#if defined(_WIN32)
|
||||
return GetStandardDir(CSIDL_LOCAL_APPDATA);
|
||||
#elif defined(USE_XDG)
|
||||
// Check for $XDG_CONFIG_HOME
|
||||
@@ -251,7 +251,7 @@ GetUserConfigDir() noexcept
|
||||
AllocatedPath
|
||||
GetUserMusicDir() noexcept
|
||||
{
|
||||
#if defined(WIN32)
|
||||
#if defined(_WIN32)
|
||||
return GetStandardDir(CSIDL_MYMUSIC);
|
||||
#elif defined(USE_XDG)
|
||||
return GetUserDir("XDG_MUSIC_DIR");
|
||||
@@ -287,7 +287,7 @@ GetUserCacheDir() noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
AllocatedPath
|
||||
GetSystemConfigDir() noexcept
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user