diff --git a/.travis.yml b/.travis.yml index f6b7419f8..40c7afcca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,70 +2,37 @@ language: cpp jobs: include: - # Ubuntu Bionic (18.04) with GCC 7 + # Ubuntu Focal (20.04) with GCC 9.3 - os: linux - dist: bionic + dist: focal addons: apt: - sources: - - sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson) packages: + - meson - libgtest-dev - libboost-dev - - python3.6 - - python3-urllib3 - - ninja-build - before_install: - - wget https://bootstrap.pypa.io/get-pip.py - - /usr/bin/python3.6 get-pip.py --user --no-cache-dir - install: - - /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir - env: - - MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH" - # Ubuntu Bionic (18.04) with GCC 7 on big-endian + # Ubuntu Focal (20.04) with GCC 9.3 on big-endian - os: linux arch: s390x - dist: bionic + dist: focal addons: apt: - sources: - - sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson) packages: + - meson - libgtest-dev - libboost-dev - - python3.6 - - python3-urllib3 - - ninja-build - before_install: - - wget https://bootstrap.pypa.io/get-pip.py - - /usr/bin/python3.6 get-pip.py --user --no-cache-dir - install: - - /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir - env: - - MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH" - # Ubuntu Bionic (18.04) with GCC 7 on ARM64 + # Ubuntu Focal (20.04) with GCC 9.3 on ARM64 - os: linux arch: arm64 - dist: bionic + dist: focal addons: apt: - sources: - - sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson) packages: + - meson - libgtest-dev - libboost-dev - - python3.6 - - python3-urllib3 - - ninja-build - before_install: - - wget https://bootstrap.pypa.io/get-pip.py - - /usr/bin/python3.6 get-pip.py --user --no-cache-dir - install: - - /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir - env: - - MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH" # Ubuntu Trusty (16.04) with GCC 8 - os: linux @@ -75,7 +42,7 @@ jobs: sources: - ubuntu-toolchain-r-test - sourceline: 'ppa:mhier/libboost-latest' - - sourceline: 'ppa:mstipicevic/ninja-build-1-7-2' + - sourceline: 'ppa:ricotz/toolchain' - sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson) packages: - g++-8 @@ -94,12 +61,13 @@ jobs: - MATRIX_EVAL="export CC='ccache gcc-8' CXX='ccache g++-8' LDFLAGS=-fuse-ld=gold PATH=\$HOME/.local/bin:\$PATH" - os: osx - osx_image: xcode10.3 + osx_image: xcode11.6 addons: homebrew: packages: - ccache - meson + - googletest - icu4c - ffmpeg - libnfs @@ -117,7 +85,6 @@ jobs: - faad2 - wavpack - libmpdclient - update: true env: - MATRIX_EVAL="export PATH=/usr/local/opt/ccache/libexec:$PATH HOMEBREW_NO_ANALYTICS=1" @@ -134,13 +101,6 @@ before_install: - eval "${MATRIX_EVAL}" install: - # C++14 - - # Work around "Target /usr/local/lib/libgtest.a is a symlink - # belonging to nss. You can unlink it" during gtest install - - test "$TRAVIS_OS_NAME" != "osx" || brew unlink nss - - - test "$TRAVIS_OS_NAME" != "osx" || brew install https://gist.githubusercontent.com/Kronuz/96ac10fbd8472eb1e7566d740c4034f8/raw/gtest.rb before_script: - ccache -s diff --git a/NEWS b/NEWS index 68551434a..d02f6f3a0 100644 --- a/NEWS +++ b/NEWS @@ -11,12 +11,18 @@ ver 0.23 (not yet released) ver 0.22.7 (not yet released) * protocol - don't use glibc extension to parse time stamps +* input + - curl: send user/password in the first request, save one roundtrip * decoder - ffmpeg: fix build problem with FFmpeg 3.4 - gme: support RSN files * storage - curl: don't use glibc extension +* database + - simple: fix database corruption bug * output + - fix crash when pausing with multiple partitions + - jack: enable on Windows - httpd: send header "Access-Control-Allow-Origin: *" - wasapi: add algorithm for finding usable audio format - wasapi: use default device only if none was configured diff --git a/doc/meson.build b/doc/meson.build index 82fd3b0cf..24a586bb4 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -23,20 +23,6 @@ if get_option('html_manual') install: true, install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()), ) - - custom_target( - 'upload', - input: sphinx_output, - output: 'upload', - build_always_stale: true, - command: [ - 'rsync', '-vpruz', '--delete', meson.current_build_dir() + '/', - 'www.musicpd.org:/var/www/mpd/doc/', - '--chmod=Dug+rwx,Do+rx,Fug+rw,Fo+r', - '--include=html', '--include=html/**', - '--exclude=*', - ], - ) endif if get_option('manpages') diff --git a/doc/plugins.rst b/doc/plugins.rst index ff8a16f4d..aaeb0631d 100644 --- a/doc/plugins.rst +++ b/doc/plugins.rst @@ -918,6 +918,10 @@ jack The jack plugin connects to a `JACK server `_. +On Windows, this plugin loads :file:`libjack64.dll` at runtime. This +means you need to `download and install the JACK windows build +`_. + .. list-table:: :widths: 20 80 :header-rows: 1 diff --git a/python/build/boost.py b/python/build/boost.py index 26cdfae4f..8d33ba775 100644 --- a/python/build/boost.py +++ b/python/build/boost.py @@ -21,3 +21,8 @@ class BoostProject(Project): dest = os.path.join(includedir, 'boost') shutil.rmtree(dest, ignore_errors=True) shutil.copytree(os.path.join(src, 'boost'), dest) + + # touch the boost/version.hpp file to ensure it's newer than + # the downloaded Boost tarball, to avoid reinstalling Boost on + # every run + os.utime(os.path.join(toolchain.install_prefix, self.installed)) diff --git a/python/build/jack.py b/python/build/jack.py new file mode 100644 index 000000000..6e71e7f1d --- /dev/null +++ b/python/build/jack.py @@ -0,0 +1,47 @@ +import os, shutil +import re + +from .project import Project + +# This class installs just the public headers and a fake pkg-config +# file which defines the macro "DYNAMIC_JACK". This tells MPD's JACK +# output plugin to load the libjack64.dll dynamically using +# LoadLibrary(). This kludge avoids the runtime DLL dependency for +# users who don't use JACK, but still allows using the system JACK +# client library. +# +# The problem with JACK is that it uses an extremely fragile shared +# memory protocol to communicate with the daemon. One needs to use +# daemon and client library from the same build. That's why we don't +# build libjack statically here; it would probably not be compatible +# with the user's JACK daemon. + +class JackProject(Project): + def __init__(self, url, md5, installed, + **kwargs): + m = re.match(r'.*/v([\d.]+)\.tar\.gz$', url) + self.version = m.group(1) + Project.__init__(self, url, md5, installed, + name='jack2', version=self.version, + base='jack2-' + self.version, + **kwargs) + + def build(self, toolchain): + src = self.unpack(toolchain) + + includes = ['jack.h', 'ringbuffer.h', 'systemdeps.h', 'transport.h', 'types.h', 'weakmacros.h'] + includedir = os.path.join(toolchain.install_prefix, 'include', 'jack') + os.makedirs(includedir, exist_ok=True) + + for i in includes: + shutil.copyfile(os.path.join(src, 'common', 'jack', i), + os.path.join(includedir, i)) + + with open(os.path.join(toolchain.install_prefix, 'lib', 'pkgconfig', 'jack.pc'), 'w') as f: + print("prefix=" + toolchain.install_prefix, file=f) + print("", file=f) + print("Name: jack", file=f) + print("Description: dummy", file=f) + print("Version: " + self.version, file=f) + print("Libs: ", file=f) + print("Cflags: -DDYNAMIC_JACK", file=f) diff --git a/python/build/libs.py b/python/build/libs.py index e5277856c..d3e50ab09 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -9,6 +9,7 @@ from build.autotools import AutotoolsProject from build.ffmpeg import FfmpegProject from build.openssl import OpenSSLProject from build.boost import BoostProject +from build.jack import JackProject libmpdclient = MesonProject( 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz', @@ -149,8 +150,8 @@ gme = CmakeProject( ) ffmpeg = FfmpegProject( - 'http://ffmpeg.org/releases/ffmpeg-4.3.1.tar.xz', - 'ad009240d46e307b4e03a213a0f49c11b650e445b1f8be0dda2a9212b34d2ffb', + 'http://ffmpeg.org/releases/ffmpeg-4.4.tar.xz', + '06b10a183ce5371f915c6bb15b7b1fffbe046e8275099c96affc29e17645d909', 'lib/libavcodec.a', [ '--disable-shared', '--enable-static', @@ -378,14 +379,14 @@ ffmpeg = FfmpegProject( ) openssl = OpenSSLProject( - 'https://www.openssl.org/source/openssl-3.0.0-alpha10.tar.gz', - 'b1699acf2148db31f12edf5ebfdf12a92bfd3f0e60538d169710408a3cd3b138', + 'https://www.openssl.org/source/openssl-3.0.0-alpha16.tar.gz', + '08ce8244b59d75f40f91170dfcb012bf25309cdcb1fef9502e39d694f883d1d1', 'include/openssl/ossl_typ.h', ) curl = AutotoolsProject( - 'http://curl.haxx.se/download/curl-7.74.0.tar.xz', - '999d5f2c403cf6e25d58319fdd596611e455dd195208746bc6e6d197a77e878b', + 'https://curl.se/download/curl-7.76.1.tar.xz', + '64bb5288c39f0840c07d077e30d9052e1cbb9fa6c2dc52523824cc859e679145', 'lib/libcurl.a', [ '--disable-shared', '--enable-static', @@ -443,8 +444,14 @@ libnfs = AutotoolsProject( autoreconf=True, ) +jack = JackProject( + 'https://github.com/jackaudio/jack2/archive/v1.9.17.tar.gz', + '38f674bbc57852a8eb3d9faa1f96a0912d26f7d5df14c11005ad499c8ae352f2', + 'lib/pkgconfig/jack.pc', +) + boost = BoostProject( - 'https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.bz2', - '953db31e016db7bb207f11432bef7df100516eeb746843fa0486a222e3fd49cb', + 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', + 'f0397ba6e982c4450f27bf32a2a83292aba035b827a5623a14636ea583318c41', 'include/boost/version.hpp', ) diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index a2c8e505b..95e3fb9dd 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -423,6 +423,10 @@ CurlInputStream::InitEasy() request->SetOption(CURLOPT_MAXREDIRS, 5L); request->SetOption(CURLOPT_FAILONERROR, 1L); + /* this option eliminates the probe request when + username/password are specified */ + request->SetOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + if (proxy != nullptr) request->SetOption(CURLOPT_PROXY, proxy); diff --git a/src/lib/curl/patches/no_netrc.patch b/src/lib/curl/patches/no_netrc.patch index 9746f1435..c825ea36a 100644 --- a/src/lib/curl/patches/no_netrc.patch +++ b/src/lib/curl/patches/no_netrc.patch @@ -1,19 +1,20 @@ -diff -ur curl-7.63.0.orig/lib/url.c curl-7.63.0/lib/url.c ---- curl-7.63.0.orig/lib/url.c 2019-01-21 10:15:51.368019445 +0100 -+++ curl-7.63.0/lib/url.c 2019-01-21 10:19:16.307523984 +0100 -@@ -3057,6 +3057,7 @@ +Index: curl-7.71.1/lib/url.c +=================================================================== +--- curl-7.71.1.orig/lib/url.c ++++ curl-7.71.1/lib/url.c +@@ -2871,6 +2871,7 @@ } conn->bits.netrc = FALSE; +#ifndef __BIONIC__ - if(data->set.use_netrc != CURL_NETRC_IGNORED && - (!*userp || !**userp || !*passwdp || !**passwdp)) { + if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { bool netrc_user_changed = FALSE; -@@ -3090,6 +3091,7 @@ - } + bool netrc_passwd_changed = FALSE; +@@ -2895,6 +2896,7 @@ + conn->bits.user_passwd = TRUE; /* enable user+password */ } } +#endif /* for updated strings, we update them in the URL */ - if(user_changed) { + if(*userp) { diff --git a/src/lib/jack/Dynamic.hxx b/src/lib/jack/Dynamic.hxx new file mode 100644 index 000000000..92d4d72c9 --- /dev/null +++ b/src/lib/jack/Dynamic.hxx @@ -0,0 +1,182 @@ +/* + * Copyright 2003-2021 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "system/Error.hxx" + +/* sorry for this horrible piece of code - there's no elegant way to + load DLLs at runtime */ + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + +using jack_set_error_function_t = std::add_pointer_t; +static jack_set_error_function_t _jack_set_error_function; + +using jack_set_info_function_t = std::add_pointer_t; +static jack_set_info_function_t _jack_set_info_function; + +using jack_client_open_t = std::add_pointer_t; +static jack_client_open_t _jack_client_open; + +using jack_client_close_t = std::add_pointer_t; +static jack_client_close_t _jack_client_close; + +using jack_connect_t = std::add_pointer_t; +static jack_connect_t _jack_connect; + +using jack_activate_t = std::add_pointer_t; +static jack_activate_t _jack_activate; + +using jack_deactivate_t = std::add_pointer_t; +static jack_deactivate_t _jack_deactivate; + +using jack_get_sample_rate_t = std::add_pointer_t; +static jack_get_sample_rate_t _jack_get_sample_rate; + +using jack_set_process_callback_t = std::add_pointer_t; +static jack_set_process_callback_t _jack_set_process_callback; + +using jack_on_info_shutdown_t = std::add_pointer_t; +static jack_on_info_shutdown_t _jack_on_info_shutdown; + +using jack_free_t = std::add_pointer_t; +static jack_free_t _jack_free; + +using jack_get_ports_t = std::add_pointer_t; +static jack_get_ports_t _jack_get_ports; + +using jack_port_register_t = std::add_pointer_t; +static jack_port_register_t _jack_port_register; + +using jack_port_name_t = std::add_pointer_t; +static jack_port_name_t _jack_port_name; + +using jack_port_get_buffer_t = std::add_pointer_t; +static jack_port_get_buffer_t _jack_port_get_buffer; + +using jack_ringbuffer_create_t = std::add_pointer_t; +static jack_ringbuffer_create_t _jack_ringbuffer_create; + +using jack_ringbuffer_free_t = std::add_pointer_t; +static jack_ringbuffer_free_t _jack_ringbuffer_free; + +using jack_ringbuffer_get_write_vector_t = std::add_pointer_t; +static jack_ringbuffer_get_write_vector_t _jack_ringbuffer_get_write_vector; + +using jack_ringbuffer_write_advance_t = std::add_pointer_t; +static jack_ringbuffer_write_advance_t _jack_ringbuffer_write_advance; + +using jack_ringbuffer_read_space_t = std::add_pointer_t; +static jack_ringbuffer_read_space_t _jack_ringbuffer_read_space; + +using jack_ringbuffer_read_t = std::add_pointer_t; +static jack_ringbuffer_read_t _jack_ringbuffer_read; + +using jack_ringbuffer_read_advance_t = std::add_pointer_t; +static jack_ringbuffer_read_advance_t _jack_ringbuffer_read_advance; + +using jack_ringbuffer_reset_t = std::add_pointer_t; +static jack_ringbuffer_reset_t _jack_ringbuffer_reset; + +template +static void +GetFunction(HMODULE h, const char *name, T &result) +{ + auto f = GetProcAddress(h, name); + if (f == nullptr) + throw FormatRuntimeError("No such libjack function: %s", name); + + result = reinterpret_cast(f); +} + +static void +LoadJackLibrary() +{ +#ifdef _WIN64 +#define LIBJACK "libjack64" +#else +#define LIBJACK "libjack" +#endif + + auto libjack = LoadLibraryA(LIBJACK); + if (!libjack) + throw FormatLastError("Failed to load " LIBJACK ".dll"); + + GetFunction(libjack, "jack_set_error_function", _jack_set_error_function); + GetFunction(libjack, "jack_set_info_function", _jack_set_info_function); + + GetFunction(libjack, "jack_client_open", _jack_client_open); + GetFunction(libjack, "jack_client_close", _jack_client_close); + GetFunction(libjack, "jack_connect", _jack_connect); + GetFunction(libjack, "jack_activate", _jack_activate); + GetFunction(libjack, "jack_deactivate", _jack_deactivate); + GetFunction(libjack, "jack_free", _jack_free); + + GetFunction(libjack, "jack_get_sample_rate", _jack_get_sample_rate); + GetFunction(libjack, "jack_set_process_callback", _jack_set_process_callback); + GetFunction(libjack, "jack_on_info_shutdown", _jack_on_info_shutdown); + + GetFunction(libjack, "jack_get_ports", _jack_get_ports); + GetFunction(libjack, "jack_port_register", _jack_port_register); + GetFunction(libjack, "jack_port_name", _jack_port_name); + GetFunction(libjack, "jack_port_get_buffer", _jack_port_get_buffer); + + GetFunction(libjack, "jack_ringbuffer_create", _jack_ringbuffer_create); + GetFunction(libjack, "jack_ringbuffer_free", _jack_ringbuffer_free); + GetFunction(libjack, "jack_ringbuffer_get_write_vector", _jack_ringbuffer_get_write_vector); + GetFunction(libjack, "jack_ringbuffer_write_advance", _jack_ringbuffer_write_advance); + GetFunction(libjack, "jack_ringbuffer_read_space", _jack_ringbuffer_read_space); + GetFunction(libjack, "jack_ringbuffer_read", _jack_ringbuffer_read); + GetFunction(libjack, "jack_ringbuffer_read_advance", _jack_ringbuffer_read_advance); + GetFunction(libjack, "jack_ringbuffer_reset", _jack_ringbuffer_reset); +} + +#define jack_set_error_function _jack_set_error_function +#define jack_set_info_function _jack_set_info_function + +#define jack_client_open _jack_client_open +#define jack_client_close _jack_client_close +#define jack_connect _jack_connect +#define jack_activate _jack_activate +#define jack_deactivate _jack_deactivate +#define jack_free _jack_free + +#define jack_get_sample_rate _jack_get_sample_rate +#define jack_set_process_callback _jack_set_process_callback +#define jack_on_info_shutdown _jack_on_info_shutdown + +#define jack_get_ports _jack_get_ports +#define jack_port_register _jack_port_register +#define jack_port_name _jack_port_name +#define jack_port_get_buffer _jack_port_get_buffer + +#define jack_ringbuffer_create _jack_ringbuffer_create +#define jack_ringbuffer_free _jack_ringbuffer_free +#define jack_ringbuffer_get_write_vector _jack_ringbuffer_get_write_vector +#define jack_ringbuffer_write_advance _jack_ringbuffer_write_advance +#define jack_ringbuffer_read_space _jack_ringbuffer_read_space +#define jack_ringbuffer_read _jack_ringbuffer_read +#define jack_ringbuffer_read_advance _jack_ringbuffer_read_advance +#define jack_ringbuffer_reset _jack_ringbuffer_reset + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/src/output/Control.cxx b/src/output/Control.cxx index 6141710e4..625c6ff37 100644 --- a/src/output/Control.cxx +++ b/src/output/Control.cxx @@ -118,7 +118,7 @@ AudioOutputControl::GetLogName() const noexcept { assert(!IsDummy()); - return output->GetLogName(); + return output ? output->GetLogName() : name.c_str(); } Mixer * @@ -364,7 +364,7 @@ AudioOutputControl::LockPlay() noexcept void AudioOutputControl::LockPauseAsync() noexcept { - if (output->mixer != nullptr && !output->SupportsPause()) + if (output && output->mixer != nullptr && !output->SupportsPause()) /* the device has no pause mode: close the mixer, unless its "global" flag is set (checked by mixer_auto_close()) */ diff --git a/src/output/plugins/JackOutputPlugin.cxx b/src/output/plugins/JackOutputPlugin.cxx index 5f58f93f1..b0cb910d6 100644 --- a/src/output/plugins/JackOutputPlugin.cxx +++ b/src/output/plugins/JackOutputPlugin.cxx @@ -44,6 +44,10 @@ static constexpr unsigned MAX_PORTS = 16; static constexpr size_t jack_sample_size = sizeof(jack_default_audio_sample_t); +#ifdef DYNAMIC_JACK +#include "lib/jack/Dynamic.hxx" +#endif // _WIN32 + class JackOutput final : public AudioOutput { /** * libjack options passed to jack_client_open(). @@ -463,6 +467,10 @@ JackOutput::Disable() noexcept static AudioOutput * mpd_jack_init(EventLoop &, const ConfigBlock &block) { +#ifdef DYNAMIC_JACK + LoadJackLibrary(); +#endif + jack_set_error_function(mpd_jack_error); #ifdef HAVE_JACK_SET_INFO_FUNCTION diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx index 9d862eb32..b2cb5c8fc 100644 --- a/src/storage/plugins/CurlStorage.cxx +++ b/src/storage/plugins/CurlStorage.cxx @@ -262,6 +262,10 @@ public: request.SetOption(CURLOPT_FOLLOWLOCATION, 1L); request.SetOption(CURLOPT_MAXREDIRS, 1L); + /* this option eliminates the probe request when + username/password are specified */ + request.SetOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + request_headers.Append(StringFormat<40>("depth: %u", depth)); request_headers.Append("content-type: text/xml"); diff --git a/src/tag/Pool.cxx b/src/tag/Pool.cxx index e977c6784..e5a6d57f2 100644 --- a/src/tag/Pool.cxx +++ b/src/tag/Pool.cxx @@ -114,10 +114,7 @@ tag_pool_get_item(TagType type, StringView value) noexcept auto slot_p = tag_value_slot_p(type, value); for (auto slot = *slot_p; slot != nullptr; slot = slot->next) { if (slot->item.type == type && - /* strncmp() only works if there are no null - bytes, which FixTagString() has already ensured - at this point */ - strncmp(value.data, slot->item.value, value.size) == 0 && + value.Equals(slot->item.value) && slot->ref < TagPoolSlot::MAX_REF) { assert(slot->ref > 0); ++slot->ref; diff --git a/test/test_mixramp.cxx b/test/test_mixramp.cxx index ca010f246..6f32fec04 100644 --- a/test/test_mixramp.cxx +++ b/test/test_mixramp.cxx @@ -13,25 +13,25 @@ TEST(MixRamp, Interpolate) const char *input = "1.0 0.00;3.0 0.10;6.0 2.50;"; char *foo = strdup(input); - EXPECT_NEAR(double(0), + EXPECT_NEAR(0., mixramp_interpolate(foo, 0).count(), 0.05); free(foo); foo = strdup(input); - EXPECT_NEAR(float(0), + EXPECT_NEAR(0., mixramp_interpolate(foo, 1).count(), 0.005); free(foo); foo = strdup(input); - EXPECT_NEAR(float(0.1), + EXPECT_NEAR(0.1, mixramp_interpolate(foo, 3).count(), 0.005); free(foo); foo = strdup(input); - EXPECT_NEAR(float(2.5), + EXPECT_NEAR(2.5, mixramp_interpolate(foo, 6).count(), 0.01); free(foo); @@ -41,25 +41,25 @@ TEST(MixRamp, Interpolate) free(foo); foo = strdup(input); - EXPECT_NEAR(float(0.05), + EXPECT_NEAR(0.05, mixramp_interpolate(foo, 2).count(), 0.05); free(foo); foo = strdup(input); - EXPECT_NEAR(float(1.3), + EXPECT_NEAR(1.3, mixramp_interpolate(foo, 4.5).count(), 0.05); free(foo); foo = strdup(input); - EXPECT_NEAR(float(0.9), + EXPECT_NEAR(0.9, mixramp_interpolate(foo, 4).count(), 0.05); free(foo); foo = strdup(input); - EXPECT_NEAR(float(1.7), + EXPECT_NEAR(1.7, mixramp_interpolate(foo, 5).count(), 0.05); free(foo); diff --git a/test/test_pcm_format.cxx b/test/test_pcm_format.cxx index 1c448294f..4ecd19270 100644 --- a/test/test_pcm_format.cxx +++ b/test/test_pcm_format.cxx @@ -79,8 +79,8 @@ TEST(PcmTest, FormatFloat16) EXPECT_EQ(N, f.size); for (size_t i = 0; i != f.size; ++i) { - EXPECT_GE(f[i], -1.); - EXPECT_LE(f[i], 1.); + EXPECT_GE(f[i], -1.f); + EXPECT_LE(f[i], 1.f); } PcmDither dither; @@ -125,8 +125,8 @@ TEST(PcmTest, FormatFloat32) EXPECT_EQ(N, f.size); for (size_t i = 0; i != f.size; ++i) { - EXPECT_GE(f[i], -1.); - EXPECT_LE(f[i], 1.); + EXPECT_GE(f[i], -1.f); + EXPECT_LE(f[i], 1.f); } auto d = pcm_convert_to_32(buffer2, diff --git a/test/test_pcm_volume.cxx b/test/test_pcm_volume.cxx index f8b3fec59..11ea75303 100644 --- a/test/test_pcm_volume.cxx +++ b/test/test_pcm_volume.cxx @@ -154,7 +154,7 @@ TEST(PcmTest, VolumeFloat) const auto _dest = ConstBuffer::FromVoid(dest); for (unsigned i = 0; i < N; ++i) - EXPECT_NEAR(_src[i] / 2, _dest[i], 1); + EXPECT_NEAR((double)_src[i] / 2., (double)_dest[i], 1.); pv.Close(); } diff --git a/win32/build.py b/win32/build.py index 8aa87e288..9f3011831 100755 --- a/win32/build.py +++ b/win32/build.py @@ -108,6 +108,7 @@ thirdparty_libs = [ curl, libexpat, libnfs, + jack, boost, ]