Merge branch 'v0.22.x'
This commit is contained in:
commit
a2bdac571a
64
.travis.yml
64
.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
|
||||
|
|
6
NEWS
6
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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -918,6 +918,10 @@ jack
|
|||
|
||||
The jack plugin connects to a `JACK server <http://jackaudio.org/>`_.
|
||||
|
||||
On Windows, this plugin loads :file:`libjack64.dll` at runtime. This
|
||||
means you need to `download and install the JACK windows build
|
||||
<https://jackaudio.org/downloads/>`_.
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:header-rows: 1
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
|
@ -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',
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<decltype(jack_set_error_function)>;
|
||||
static jack_set_error_function_t _jack_set_error_function;
|
||||
|
||||
using jack_set_info_function_t = std::add_pointer_t<decltype(jack_set_info_function)>;
|
||||
static jack_set_info_function_t _jack_set_info_function;
|
||||
|
||||
using jack_client_open_t = std::add_pointer_t<decltype(jack_client_open)>;
|
||||
static jack_client_open_t _jack_client_open;
|
||||
|
||||
using jack_client_close_t = std::add_pointer_t<decltype(jack_client_close)>;
|
||||
static jack_client_close_t _jack_client_close;
|
||||
|
||||
using jack_connect_t = std::add_pointer_t<decltype(jack_connect)>;
|
||||
static jack_connect_t _jack_connect;
|
||||
|
||||
using jack_activate_t = std::add_pointer_t<decltype(jack_activate)>;
|
||||
static jack_activate_t _jack_activate;
|
||||
|
||||
using jack_deactivate_t = std::add_pointer_t<decltype(jack_deactivate)>;
|
||||
static jack_deactivate_t _jack_deactivate;
|
||||
|
||||
using jack_get_sample_rate_t = std::add_pointer_t<decltype(jack_get_sample_rate)>;
|
||||
static jack_get_sample_rate_t _jack_get_sample_rate;
|
||||
|
||||
using jack_set_process_callback_t = std::add_pointer_t<decltype(jack_set_process_callback)>;
|
||||
static jack_set_process_callback_t _jack_set_process_callback;
|
||||
|
||||
using jack_on_info_shutdown_t = std::add_pointer_t<decltype(jack_on_info_shutdown)>;
|
||||
static jack_on_info_shutdown_t _jack_on_info_shutdown;
|
||||
|
||||
using jack_free_t = std::add_pointer_t<decltype(jack_free)>;
|
||||
static jack_free_t _jack_free;
|
||||
|
||||
using jack_get_ports_t = std::add_pointer_t<decltype(jack_get_ports)>;
|
||||
static jack_get_ports_t _jack_get_ports;
|
||||
|
||||
using jack_port_register_t = std::add_pointer_t<decltype(jack_port_register)>;
|
||||
static jack_port_register_t _jack_port_register;
|
||||
|
||||
using jack_port_name_t = std::add_pointer_t<decltype(jack_port_name)>;
|
||||
static jack_port_name_t _jack_port_name;
|
||||
|
||||
using jack_port_get_buffer_t = std::add_pointer_t<decltype(jack_port_get_buffer)>;
|
||||
static jack_port_get_buffer_t _jack_port_get_buffer;
|
||||
|
||||
using jack_ringbuffer_create_t = std::add_pointer_t<decltype(jack_ringbuffer_create)>;
|
||||
static jack_ringbuffer_create_t _jack_ringbuffer_create;
|
||||
|
||||
using jack_ringbuffer_free_t = std::add_pointer_t<decltype(jack_ringbuffer_free)>;
|
||||
static jack_ringbuffer_free_t _jack_ringbuffer_free;
|
||||
|
||||
using jack_ringbuffer_get_write_vector_t = std::add_pointer_t<decltype(jack_ringbuffer_get_write_vector)>;
|
||||
static jack_ringbuffer_get_write_vector_t _jack_ringbuffer_get_write_vector;
|
||||
|
||||
using jack_ringbuffer_write_advance_t = std::add_pointer_t<decltype(jack_ringbuffer_write_advance)>;
|
||||
static jack_ringbuffer_write_advance_t _jack_ringbuffer_write_advance;
|
||||
|
||||
using jack_ringbuffer_read_space_t = std::add_pointer_t<decltype(jack_ringbuffer_read_space)>;
|
||||
static jack_ringbuffer_read_space_t _jack_ringbuffer_read_space;
|
||||
|
||||
using jack_ringbuffer_read_t = std::add_pointer_t<decltype(jack_ringbuffer_read)>;
|
||||
static jack_ringbuffer_read_t _jack_ringbuffer_read;
|
||||
|
||||
using jack_ringbuffer_read_advance_t = std::add_pointer_t<decltype(jack_ringbuffer_read_advance)>;
|
||||
static jack_ringbuffer_read_advance_t _jack_ringbuffer_read_advance;
|
||||
|
||||
using jack_ringbuffer_reset_t = std::add_pointer_t<decltype(jack_ringbuffer_reset)>;
|
||||
static jack_ringbuffer_reset_t _jack_ringbuffer_reset;
|
||||
|
||||
template<typename T>
|
||||
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<T>(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
|
|
@ -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()) */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -154,7 +154,7 @@ TEST(PcmTest, VolumeFloat)
|
|||
|
||||
const auto _dest = ConstBuffer<float>::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();
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ thirdparty_libs = [
|
|||
curl,
|
||||
libexpat,
|
||||
libnfs,
|
||||
jack,
|
||||
boost,
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in New Issue