From b763852f575fa9395289e7fe3e26f9b133961c81 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Mon, 7 May 2018 10:53:48 +0200
Subject: [PATCH 01/10] decoder/dsd: allow 4 MB ID3 tags

Closes #277
---
 NEWS                           | 1 +
 src/decoder/plugins/DsdLib.cxx | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index d7c78c319..dfaea67cd 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ ver 0.20.20 (not yet released)
   - fix "modified-since" filter regression
 * decoder
   - dsdiff, dsf: support more MIME types
+  - dsdiff, dsf: allow 4 MB ID3 tags
 
 ver 0.20.19 (2018/04/26)
 * protocol
diff --git a/src/decoder/plugins/DsdLib.cxx b/src/decoder/plugins/DsdLib.cxx
index 000af531a..bad8ad641 100644
--- a/src/decoder/plugins/DsdLib.cxx
+++ b/src/decoder/plugins/DsdLib.cxx
@@ -128,7 +128,7 @@ dsdlib_tag_id3(InputStream &is,
 		return;
 
 	const auto count64 = size - tagoffset;
-	if (count64 < 10 || count64 > 1024 * 1024)
+	if (count64 < 10 || count64 > 4 * 1024 * 1024)
 		return;
 
 	if (!dsdlib_skip_to(nullptr, is, tagoffset))

From d495ec71a89fe9e1e70263302967c0c774ffdba0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20Koutensk=C3=BD?= <koutak.m@gmail.com>
Date: Fri, 4 May 2018 20:29:12 +0200
Subject: [PATCH 02/10] decoder/opus: add support for R128_ALBUM_GAIN tag

---
 NEWS                             | 1 +
 src/decoder/plugins/OpusTags.cxx | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/NEWS b/NEWS
index dfaea67cd..53f24ed5f 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ ver 0.20.20 (not yet released)
 * decoder
   - dsdiff, dsf: support more MIME types
   - dsdiff, dsf: allow 4 MB ID3 tags
+  - opus: support R128_ALBUM_GAIN tag
 
 ver 0.20.19 (2018/04/26)
 * protocol
diff --git a/src/decoder/plugins/OpusTags.cxx b/src/decoder/plugins/OpusTags.cxx
index 8baeccd2f..41c499aec 100644
--- a/src/decoder/plugins/OpusTags.cxx
+++ b/src/decoder/plugins/OpusTags.cxx
@@ -53,6 +53,14 @@ ScanOneOpusTag(const char *name, const char *value,
 		long l = strtol(value, &endptr, 10);
 		if (endptr > value && *endptr == 0)
 			rgi->track.gain = double(l) / 256.;
+	} else if (rgi != nullptr && strcmp(name, "R128_ALBUM_GAIN") == 0) {
+		/* R128_ALBUM_GAIN is a Q7.8 fixed point number in
+		   dB */
+
+		char *endptr;
+		long l = strtol(value, &endptr, 10);
+		if (endptr > value && *endptr == 0)
+			rgi->album.gain = double(l) / 256.;
 	}
 
 	tag_handler_invoke_pair(handler, ctx, name, value);

From c76f4ac89bb8a79c2af417d418ae14c5f190f1a2 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Sat, 12 May 2018 14:44:07 +0200
Subject: [PATCH 03/10] player/Thread: pause all outputs in single mode

This mostly affects the Pulse output plugin which needs to "cork" the
stream (closes #278).
---
 NEWS                  | 2 ++
 src/player/Thread.cxx | 1 +
 2 files changed, 3 insertions(+)

diff --git a/NEWS b/NEWS
index 53f24ed5f..06685148b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 ver 0.20.20 (not yet released)
 * protocol
   - fix "modified-since" filter regression
+* output
+  - pulse: cork stream when paused due to "single" mode
 * decoder
   - dsdiff, dsf: support more MIME types
   - dsdiff, dsf: allow 4 MB ID3 tags
diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx
index 651117088..fcb7b39da 100644
--- a/src/player/Thread.cxx
+++ b/src/player/Thread.cxx
@@ -950,6 +950,7 @@ Player::SongBorder()
 	const bool border_pause = pc.LockApplyBorderPause();
 	if (border_pause) {
 		paused = true;
+		pc.outputs.Pause();
 		idle_add(IDLE_PLAYER);
 	}
 }

From 786ac87b7655b3d290aa7f2c7fcc745dcf68cf2c Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Sat, 12 May 2018 15:00:17 +0200
Subject: [PATCH 04/10] python/build: add support for Meson/ninja based
 projects

---
 python/build/meson.py | 95 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 python/build/meson.py

diff --git a/python/build/meson.py b/python/build/meson.py
new file mode 100644
index 000000000..05abb694c
--- /dev/null
+++ b/python/build/meson.py
@@ -0,0 +1,95 @@
+import os.path, subprocess, sys
+
+from build.project import Project
+
+class MesonProject(Project):
+    def __init__(self, url, md5, installed, configure_args=[],
+                 **kwargs):
+        Project.__init__(self, url, md5, installed, **kwargs)
+        self.configure_args = configure_args
+
+    def _make_cross_file(self, toolchain):
+        if toolchain.is_windows:
+            system = 'windows'
+        else:
+            system = 'linux'
+
+        if toolchain.is_arm:
+            cpu_family = 'arm'
+            if toolchain.is_armv7:
+                cpu = 'armv7'
+            else:
+                cpu = 'armv6'
+        else:
+            cpu_family = 'x86'
+            if 'x86_64' in toolchain.arch:
+                cpu = 'x86_64'
+            else:
+                cpu = 'i686'
+
+        # TODO: support more CPUs
+        endian = 'little'
+
+        # TODO: write pkg-config wrapper
+
+        path = os.path.join(toolchain.build_path, 'meson.cross')
+        with open(path, 'w') as f:
+            f.write("""
+[binaries]
+c = '%s'
+cpp = '%s'
+ar = '%s'
+strip = '%s'
+
+[properties]
+root = '%s'
+
+c_args = %s
+c_link_args = %s
+
+cpp_args = %s
+cpp_link_args = %s
+
+[host_machine]
+system = '%s'
+cpu_family = '%s'
+cpu = '%s'
+endian = '%s'
+            """ % (toolchain.cc, toolchain.cxx, toolchain.ar, toolchain.strip,
+                   toolchain.install_prefix,
+                   repr((toolchain.cppflags + ' ' + toolchain.cflags).split()),
+                   repr(toolchain.ldflags.split()),
+                   repr((toolchain.cppflags + ' ' + toolchain.cxxflags).split()),
+                   repr(toolchain.ldflags.split()),
+                   system, cpu_family, cpu, endian))
+        return path
+
+    def configure(self, toolchain):
+        src = self.unpack(toolchain)
+        cross_file = self._make_cross_file(toolchain)
+        build = self.make_build_path(toolchain)
+        configure = [
+            'meson',
+            src, build,
+
+            '--prefix', toolchain.install_prefix,
+
+            # this is necessary because Meson uses Debian's build machine
+            # MultiArch path (e.g. "lib/x86_64-linux-gnu") for cross
+            # builds, which is obviously wrong
+            '--libdir', 'lib',
+
+            '--buildtype', 'plain',
+
+            '--default-library=static',
+
+            '--cross-file', cross_file,
+        ] + self.configure_args
+
+        subprocess.check_call(configure, env=toolchain.env)
+        return build
+
+    def build(self, toolchain):
+        build = self.configure(toolchain)
+        subprocess.check_call(['ninja', 'install'],
+                              cwd=build, env=toolchain.env)

From 62127bbb123d143e52cc1bc95f636843a75eba4b Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Sat, 24 Feb 2018 22:59:33 +0100
Subject: [PATCH 05/10] python/build/libs.py: add libmpdclient

---
 NEWS                 | 2 ++
 android/build.py     | 1 +
 python/build/libs.py | 7 +++++++
 win32/build.py       | 1 +
 4 files changed, 11 insertions(+)

diff --git a/NEWS b/NEWS
index 06685148b..69685ec7d 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ ver 0.20.20 (not yet released)
   - dsdiff, dsf: support more MIME types
   - dsdiff, dsf: allow 4 MB ID3 tags
   - opus: support R128_ALBUM_GAIN tag
+* Android, Windows
+  - enable the "proxy" database plugin
 
 ver 0.20.19 (2018/04/26)
 * protocol
diff --git a/android/build.py b/android/build.py
index 19dcbaee7..ee64d3059 100755
--- a/android/build.py
+++ b/android/build.py
@@ -138,6 +138,7 @@ class AndroidNdkToolchain:
 # a list of third-party libraries to be used by MPD on Android
 from build.libs import *
 thirdparty_libs = [
+    libmpdclient,
     libogg,
     libvorbis,
     opus,
diff --git a/python/build/libs.py b/python/build/libs.py
index c11be6188..be77050db 100644
--- a/python/build/libs.py
+++ b/python/build/libs.py
@@ -3,10 +3,17 @@ from os.path import abspath
 
 from build.project import Project
 from build.zlib import ZlibProject
+from build.meson import MesonProject
 from build.autotools import AutotoolsProject
 from build.ffmpeg import FfmpegProject
 from build.boost import BoostProject
 
+libmpdclient = MesonProject(
+    'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.14.tar.xz',
+    '0a84e2791bfe3077cf22ee1784c805d5bb550803dffe56a39aa3690a38061372',
+    'lib/libmpdclient.a',
+)
+
 libogg = AutotoolsProject(
     'http://downloads.xiph.org/releases/ogg/libogg-1.3.3.tar.xz',
     '4f3fc6178a533d392064f14776b23c397ed4b9f48f5de297aba73b643f955c08',
diff --git a/win32/build.py b/win32/build.py
index 38cc9c271..99203a6d6 100755
--- a/win32/build.py
+++ b/win32/build.py
@@ -76,6 +76,7 @@ class CrossGccToolchain:
 # a list of third-party libraries to be used by MPD on Android
 from build.libs import *
 thirdparty_libs = [
+    libmpdclient,
     libogg,
     libvorbis,
     opus,

From 8bf250c2282cccc158bd0c26e8a972c48321a2d5 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 22 May 2018 11:17:19 +0200
Subject: [PATCH 06/10] python/build/libs: upgrade CURL to 7.60.0

---
 python/build/libs.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/python/build/libs.py b/python/build/libs.py
index be77050db..a0818376a 100644
--- a/python/build/libs.py
+++ b/python/build/libs.py
@@ -341,8 +341,8 @@ ffmpeg = FfmpegProject(
 )
 
 curl = AutotoolsProject(
-    'http://curl.haxx.se/download/curl-7.59.0.tar.xz',
-    'e44eaabdf916407585bf5c7939ff1161e6242b6b015d3f2f5b758b2a330461fc',
+    'http://curl.haxx.se/download/curl-7.60.0.tar.xz',
+    '8736ff8ded89ddf7e926eec7b16f82597d029fc1469f3a551f1fafaac164e6a0',
     'lib/libcurl.a',
     [
         '--disable-shared', '--enable-static',

From 626329a1cce84e7668b9e3cdb34186e702e4a0c5 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 22 May 2018 12:31:37 +0200
Subject: [PATCH 07/10] python/build/meson.py: create build_path if it does not
 exist

---
 python/build/meson.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python/build/meson.py b/python/build/meson.py
index 05abb694c..4cda8ec2a 100644
--- a/python/build/meson.py
+++ b/python/build/meson.py
@@ -33,6 +33,7 @@ class MesonProject(Project):
         # TODO: write pkg-config wrapper
 
         path = os.path.join(toolchain.build_path, 'meson.cross')
+        os.makedirs(toolchain.build_path, exist_ok=True)
         with open(path, 'w') as f:
             f.write("""
 [binaries]

From bc14a6038ee1e2b749470b4011abddc14367197d Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 22 May 2018 12:37:01 +0200
Subject: [PATCH 08/10] Makefile.am: invoke javac with source/target 1.6

Fixes:

```
error: Source option 5 is no longer supported. Use 6 or later.
error: Target option 1.5 is no longer supported. Use 1.6 or later.
```
---
 Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 266a61c6a..d5416681a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -330,7 +330,7 @@ android/build/gen/org/musicpd/R.java: android/build/resources.apk
 
 android/build/classes.dex: $(JAVA_SOURCE_PATHS) android/build/gen/org/musicpd/R.java
 	@$(MKDIR_P) $(JAVA_CLASSFILES_DIR)
-	$(JAVAC) -source 1.5 -target 1.5 -Xlint:-options \
+	$(JAVAC) -source 1.6 -target 1.6 -Xlint:-options \
 		-cp $(ANDROID_SDK_PLATFORM_DIR)/android.jar:$(JAVA_CLASSFILES_DIR) \
 		-d $(JAVA_CLASSFILES_DIR) $^
 	$(DX) --dex --output $@ $(JAVA_CLASSFILES_DIR)

From 16b0e53a360351155c1ee69369d3ac9fe5e66bbc Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 22 May 2018 12:40:11 +0200
Subject: [PATCH 09/10] android/AndroidManifest.xml: increment version number
 to 0.20.20

---
 android/AndroidManifest.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 16f96a9cf..acdf78a17 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -2,8 +2,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="org.musicpd"
           android:installLocation="auto"
-          android:versionCode="18"
-          android:versionName="0.20.19">
+          android:versionCode="19"
+          android:versionName="0.20.20">
 
   <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17"/>
 

From ab197b6d4392c57c89fcd7bd48a1a69b85874653 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 22 May 2018 12:40:18 +0200
Subject: [PATCH 10/10] release v0.20.20

---
 NEWS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 69685ec7d..e8a353c95 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-ver 0.20.20 (not yet released)
+ver 0.20.20 (2018/05/22)
 * protocol
   - fix "modified-since" filter regression
 * output