summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS11
-rw-r--r--android/AndroidManifest.xml4
-rw-r--r--doc/plugins.rst3
-rw-r--r--python/build/libs.py20
-rw-r--r--src/archive/plugins/Bzip2ArchivePlugin.cxx52
-rw-r--r--src/archive/plugins/Iso9660ArchivePlugin.cxx24
-rw-r--r--src/archive/plugins/ZzipArchivePlugin.cxx25
-rw-r--r--src/decoder/DecoderAPI.cxx27
-rw-r--r--src/decoder/DecoderAPI.hxx20
-rw-r--r--src/decoder/plugins/SndfileDecoderPlugin.cxx4
-rw-r--r--src/input/Init.cxx2
-rw-r--r--src/lib/icu/meson.build2
-rw-r--r--src/neighbor/plugins/SmbclientNeighborPlugin.cxx5
-rw-r--r--src/output/plugins/OSXOutputPlugin.cxx14
-rw-r--r--src/output/plugins/sles/SlesOutputPlugin.cxx37
-rw-r--r--src/util/ByteOrder.hxx40
-rwxr-xr-xwin32/build.py5
17 files changed, 185 insertions, 110 deletions
diff --git a/NEWS b/NEWS
index 661a143f1..f2d1364c9 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,17 @@ ver 0.22 (not yet released)
* switch to C++17
- GCC 7 or clang 4 (or newer) recommended
+ver 0.21.26 (not yet released)
+* output
+ - osx: fix crash bug
+ - sles: support floating point samples
+* archive
+ - bzip2: fix crash on corrupt bzip2 file
+ - bzip2: flush output at end of input file
+ - zzip: fix crash on corrupt ZIP file
+* decoder
+ - sndfile: fix lost samples at end of file
+
ver 0.21.25 (2020/07/06)
* protocol:
- fix crash when using "rangeid" while playing
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index e2a31db83..746a2490f 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="48"
- android:versionName="0.21.25">
+ android:versionCode="49"
+ android:versionName="0.21.26">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
diff --git a/doc/plugins.rst b/doc/plugins.rst
index 49bc00b78..e5056a7ab 100644
--- a/doc/plugins.rst
+++ b/doc/plugins.rst
@@ -1119,7 +1119,8 @@ sles
Plugin using the `OpenSL ES <https://www.khronos.org/opensles/>`__
audio API. Its primary use is local playback on Android, where
-:ref:`ALSA <alsa_plugin>` is not available.
+:ref:`ALSA <alsa_plugin>` is not available. It supports 16 bit and
+floating point samples.
solaris
diff --git a/python/build/libs.py b/python/build/libs.py
index e211a0107..4886e8e19 100644
--- a/python/build/libs.py
+++ b/python/build/libs.py
@@ -10,8 +10,8 @@ from build.ffmpeg import FfmpegProject
from build.boost import BoostProject
libmpdclient = MesonProject(
- 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.18.tar.xz',
- '4cb01e1f567e0169aca94875fb6e1200e7f5ce35b63a4df768ec1591fb1081fa',
+ 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz',
+ '158aad4c2278ab08e76a3f2b0166c99b39fae00ee17231bd225c5a36e977a189',
'lib/libmpdclient.a',
)
@@ -25,8 +25,8 @@ libogg = AutotoolsProject(
)
libvorbis = AutotoolsProject(
- 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.6.tar.xz',
- 'af00bb5a784e7c9e69f56823de4637c350643deedaf333d0fa86ecdba6fcb415',
+ 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.xz',
+ 'b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b',
'lib/libvorbis.a',
[
'--disable-shared', '--enable-static',
@@ -148,8 +148,8 @@ gme = CmakeProject(
)
ffmpeg = FfmpegProject(
- 'http://ffmpeg.org/releases/ffmpeg-4.2.3.tar.xz',
- '9df6c90aed1337634c1fb026fb01c154c29c82a64ea71291ff2da9aacb9aad31',
+ 'http://ffmpeg.org/releases/ffmpeg-4.3.1.tar.xz',
+ 'ad009240d46e307b4e03a213a0f49c11b650e445b1f8be0dda2a9212b34d2ffb',
'lib/libavcodec.a',
[
'--disable-shared', '--enable-static',
@@ -377,8 +377,8 @@ ffmpeg = FfmpegProject(
)
curl = AutotoolsProject(
- 'http://curl.haxx.se/download/curl-7.70.0.tar.xz',
- '032f43f2674008c761af19bf536374128c16241fb234699a55f9fb603fcfbae7',
+ 'http://curl.haxx.se/download/curl-7.72.0.tar.xz',
+ '0ded0808c4d85f2ee0db86980ae610cc9d165e9ca9da466196cc73c346513713',
'lib/libcurl.a',
[
'--disable-shared', '--enable-static',
@@ -433,7 +433,7 @@ libnfs = AutotoolsProject(
)
boost = BoostProject(
- 'https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.bz2',
- '4eb3b8d442b426dc35346235c8733b5ae35ba431690e38c6a8263dce9fcbb402',
+ 'https://dl.bintray.com/boostorg/release/1.74.0/source/boost_1_74_0.tar.bz2',
+ '83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1',
'include/boost/version.hpp',
)
diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx
index 3ea1b755a..3234eafa8 100644
--- a/src/archive/plugins/Bzip2ArchivePlugin.cxx
+++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx
@@ -59,9 +59,9 @@ public:
class Bzip2InputStream final : public InputStream {
std::shared_ptr<InputStream> input;
- bool eof = false;
+ bz_stream bzstream{};
- bz_stream bzstream;
+ bool eof = false;
char buffer[5000];
@@ -69,7 +69,7 @@ public:
Bzip2InputStream(std::shared_ptr<InputStream> _input,
const char *uri,
Mutex &mutex);
- ~Bzip2InputStream() override;
+ ~Bzip2InputStream() noexcept override;
/* virtual methods from InputStream */
[[nodiscard]] bool IsEOF() const noexcept override;
@@ -81,25 +81,6 @@ private:
bool FillBuffer();
};
-/* single archive handling allocation helpers */
-
-inline void
-Bzip2InputStream::Open()
-{
- bzstream.bzalloc = nullptr;
- bzstream.bzfree = nullptr;
- bzstream.opaque = nullptr;
-
- bzstream.next_in = (char *)buffer;
- bzstream.avail_in = 0;
-
- int ret = BZ2_bzDecompressInit(&bzstream, 0, 0);
- if (ret != BZ_OK)
- throw std::runtime_error("BZ2_bzDecompressInit() has failed");
-
- SetReady();
-}
-
/* archive open && listing routine */
static std::unique_ptr<ArchiveFile>
@@ -118,10 +99,16 @@ Bzip2InputStream::Bzip2InputStream(std::shared_ptr<InputStream> _input,
:InputStream(_uri, _mutex),
input(std::move(_input))
{
- Open();
+ bzstream.next_in = (char *)buffer;
+
+ int ret = BZ2_bzDecompressInit(&bzstream, 0, 0);
+ if (ret != BZ_OK)
+ throw std::runtime_error("BZ2_bzDecompressInit() has failed");
+
+ SetReady();
}
-Bzip2InputStream::~Bzip2InputStream()
+Bzip2InputStream::~Bzip2InputStream() noexcept
{
BZ2_bzDecompressEnd(&bzstream);
}
@@ -151,22 +138,18 @@ Bzip2InputStream::FillBuffer()
size_t
Bzip2InputStream::Read(std::unique_lock<Mutex> &, void *ptr, size_t length)
{
- const ScopeUnlock unlock(mutex);
-
- int bz_result;
- size_t nbytes = 0;
-
if (eof)
return 0;
+ const ScopeUnlock unlock(mutex);
+
bzstream.next_out = (char *)ptr;
bzstream.avail_out = length;
do {
- if (!FillBuffer())
- return 0;
+ const bool had_input = FillBuffer();
- bz_result = BZ2_bzDecompress(&bzstream);
+ const int bz_result = BZ2_bzDecompress(&bzstream);
if (bz_result == BZ_STREAM_END) {
eof = true;
@@ -175,9 +158,12 @@ Bzip2InputStream::Read(std::unique_lock<Mutex> &, void *ptr, size_t length)
if (bz_result != BZ_OK)
throw std::runtime_error("BZ2_bzDecompress() has failed");
+
+ if (!had_input && bzstream.avail_out == length)
+ throw std::runtime_error("Unexpected end of bzip2 file");
} while (bzstream.avail_out == length);
- nbytes = length - bzstream.avail_out;
+ const size_t nbytes = length - bzstream.avail_out;
offset += nbytes;
return nbytes;
diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx
index 1b4540957..78b17d5b1 100644
--- a/src/archive/plugins/Iso9660ArchivePlugin.cxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx
@@ -148,24 +148,22 @@ Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor)
class Iso9660InputStream final : public InputStream {
std::shared_ptr<Iso9660> iso;
- iso9660_stat_t *statbuf;
+ const lsn_t lsn;
public:
Iso9660InputStream(std::shared_ptr<Iso9660> _iso,
const char *_uri,
Mutex &_mutex,
- iso9660_stat_t *_statbuf)
+ lsn_t _lsn, offset_type _size)
:InputStream(_uri, _mutex),
- iso(std::move(_iso)), statbuf(_statbuf) {
- size = statbuf->size;
+ iso(std::move(_iso)),
+ lsn(_lsn)
+ {
+ size = _size;
seekable = true;
SetReady();
}
- ~Iso9660InputStream() override {
- free(statbuf);
- }
-
/* virtual methods from InputStream */
[[nodiscard]] bool IsEOF() const noexcept override;
size_t Read(std::unique_lock<Mutex> &lock,
@@ -185,8 +183,12 @@ Iso9660ArchiveFile::OpenStream(const char *pathname,
throw FormatRuntimeError("not found in the ISO file: %s",
pathname);
+ const lsn_t lsn = statbuf->lsn;
+ const offset_type size = statbuf->size;
+ free(statbuf);
+
return std::make_unique<Iso9660InputStream>(iso, pathname, mutex,
- statbuf);
+ lsn, size);
}
size_t
@@ -197,7 +199,7 @@ Iso9660InputStream::Read(std::unique_lock<Mutex> &,
int readed = 0;
int no_blocks, cur_block;
- size_t left_bytes = statbuf->size - offset;
+ size_t left_bytes = size - offset;
if (left_bytes < read_size) {
no_blocks = CEILING(left_bytes, ISO_BLOCKSIZE);
@@ -210,7 +212,7 @@ Iso9660InputStream::Read(std::unique_lock<Mutex> &,
cur_block = offset / ISO_BLOCKSIZE;
- readed = iso->SeekRead(ptr, statbuf->lsn + cur_block, no_blocks);
+ readed = iso->SeekRead(ptr, lsn + cur_block, no_blocks);
if (readed != no_blocks * ISO_BLOCKSIZE)
throw FormatRuntimeError("error reading ISO file at lsn %lu",
diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx
index c1e48e557..582a16b04 100644
--- a/src/archive/plugins/ZzipArchivePlugin.cxx
+++ b/src/archive/plugins/ZzipArchivePlugin.cxx
@@ -34,6 +34,8 @@
#include <utility>
+#include <inttypes.h> /* for PRIoffset (PRIu64) */
+
struct ZzipDir {
ZZIP_DIR *const dir;
@@ -56,8 +58,9 @@ class ZzipArchiveFile final : public ArchiveFile {
std::shared_ptr<ZzipDir> dir;
public:
- explicit ZzipArchiveFile(std::shared_ptr<ZzipDir> &&_dir)
- :dir(std::move(_dir)) {}
+ template<typename D>
+ explicit ZzipArchiveFile(D &&_dir) noexcept
+ :dir(std::forward<D>(_dir)) {}
void Visit(ArchiveVisitor &visitor) override;
@@ -93,11 +96,12 @@ class ZzipInputStream final : public InputStream {
ZZIP_FILE *const file;
public:
- ZzipInputStream(std::shared_ptr<ZzipDir> _dir, const char *_uri,
+ template<typename D>
+ ZzipInputStream(D &&_dir, const char *_uri,
Mutex &_mutex,
ZZIP_FILE *_file)
:InputStream(_uri, _mutex),
- dir(std::move(_dir)), file(_file) {
+ dir(std::forward<D>(_dir)), file(_file) {
//we are seekable (but its not recommendent to do so)
seekable = true;
@@ -108,7 +112,7 @@ public:
SetReady();
}
- ~ZzipInputStream() override {
+ ~ZzipInputStream() noexcept override {
zzip_file_close(file);
}
@@ -148,12 +152,17 @@ ZzipInputStream::Read(std::unique_lock<Mutex> &, void *ptr, size_t read_size)
{
const ScopeUnlock unlock(mutex);
- int ret = zzip_file_read(file, ptr, read_size);
- if (ret < 0)
+ zzip_ssize_t nbytes = zzip_file_read(file, ptr, read_size);
+ if (nbytes < 0)
throw std::runtime_error("zzip_file_read() has failed");
+ if (nbytes == 0 && !IsEOF())
+ throw FormatRuntimeError("Unexpected end of file %s"
+ " at %" PRIoffset " of %" PRIoffset,
+ GetURI(), GetOffset(), GetSize());
+
offset = zzip_tell(file);
- return ret;
+ return nbytes;
}
bool
diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx
index c061df035..2087f00ca 100644
--- a/src/decoder/DecoderAPI.cxx
+++ b/src/decoder/DecoderAPI.cxx
@@ -26,7 +26,7 @@
size_t
decoder_read(DecoderClient *client,
InputStream &is,
- void *buffer, size_t length)
+ void *buffer, size_t length) noexcept
{
assert(buffer != nullptr);
@@ -42,9 +42,30 @@ decoder_read(DecoderClient *client,
}
}
+size_t
+decoder_read_much(DecoderClient *client, InputStream &is,
+ void *_buffer, size_t size) noexcept
+{
+ uint8_t *buffer = (uint8_t *)_buffer;
+
+ size_t total = 0;
+
+ while (size > 0 && !is.LockIsEOF()) {
+ size_t nbytes = decoder_read(client, is, buffer, size);
+ if (nbytes == 0)
+ return false;
+
+ total += nbytes;
+ buffer += nbytes;
+ size -= nbytes;
+ }
+
+ return total;
+}
+
bool
decoder_read_full(DecoderClient *client, InputStream &is,
- void *_buffer, size_t size)
+ void *_buffer, size_t size) noexcept
{
auto *buffer = (uint8_t *)_buffer;
@@ -61,7 +82,7 @@ decoder_read_full(DecoderClient *client, InputStream &is,
}
bool
-decoder_skip(DecoderClient *client, InputStream &is, size_t size)
+decoder_skip(DecoderClient *client, InputStream &is, size_t size) noexcept
{
while (size > 0) {
char buffer[1024];
diff --git a/src/decoder/DecoderAPI.hxx b/src/decoder/DecoderAPI.hxx
index 058f3ea55..e5027f384 100644
--- a/src/decoder/DecoderAPI.hxx
+++ b/src/decoder/DecoderAPI.hxx
@@ -63,17 +63,29 @@ class StopDecoder {};
*/
size_t
decoder_read(DecoderClient *decoder, InputStream &is,
- void *buffer, size_t length);
+ void *buffer, size_t length) noexcept;
static inline size_t
decoder_read(DecoderClient &decoder, InputStream &is,
- void *buffer, size_t length)
+ void *buffer, size_t length) noexcept
{
return decoder_read(&decoder, is, buffer, length);
}
/**
* Blocking read from the input stream. Attempts to fill the buffer
+ * as much as possible, until either end-of-file is reached or an
+ * error occurs.
+ *
+ * @return the number of bytes read, or 0 if one of the following
+ * occurs: end of file; error; command (like SEEK or STOP).
+ */
+size_t
+decoder_read_much(DecoderClient *decoder, InputStream &is,
+ void *buffer, size_t size) noexcept;
+
+/**
+ * Blocking read from the input stream. Attempts to fill the buffer
* completely; there is no partial result.
*
* @return true on success, false on error or command or not enough
@@ -81,7 +93,7 @@ decoder_read(DecoderClient &decoder, InputStream &is,
*/
bool
decoder_read_full(DecoderClient *decoder, InputStream &is,
- void *buffer, size_t size);
+ void *buffer, size_t size) noexcept;
/**
* Skip data on the #InputStream.
@@ -89,6 +101,6 @@ decoder_read_full(DecoderClient *decoder, InputStream &is,
* @return true on success, false on error or command
*/
bool
-decoder_skip(DecoderClient *decoder, InputStream &is, size_t size);
+decoder_skip(DecoderClient *decoder, InputStream &is, size_t size) noexcept;
#endif
diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx
index bde242c87..bf9451b0b 100644
--- a/src/decoder/plugins/SndfileDecoderPlugin.cxx
+++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx
@@ -47,9 +47,7 @@ struct SndfileInputStream {
size_t Read(void *buffer, size_t size) {
/* libsndfile chokes on partial reads; therefore
always force full reads */
- return decoder_read_full(client, is, buffer, size)
- ? size
- : 0;
+ return decoder_read_much(client, is, buffer, size);
}
};
diff --git a/src/input/Init.cxx b/src/input/Init.cxx
index 49f0b279f..6398ad231 100644
--- a/src/input/Init.cxx
+++ b/src/input/Init.cxx
@@ -67,7 +67,7 @@ input_stream_global_init(const ConfigData &config, EventLoop &event_loop)
plugin->init(event_loop, *block);
input_plugins_enabled[i] = true;
} catch (const PluginUnconfigured &e) {
- LogFormat(LogLevel::INFO, e,
+ LogFormat(LogLevel::DEBUG, e,
"Input plugin '%s' is not configured",
plugin->name);
continue;
diff --git a/src/lib/icu/meson.build b/src/lib/icu/meson.build
index 5386a62b4..bd6e30944 100644
--- a/src/lib/icu/meson.build
+++ b/src/lib/icu/meson.build
@@ -18,7 +18,7 @@ if icu_dep.found()
'Init.cxx',
]
elif not get_option('iconv').disabled()
- have_iconv = compiler.has_function('iconv')
+ have_iconv = compiler.has_function('iconv', prefix : '#include <iconv.h>')
conf.set('HAVE_ICONV', have_iconv)
if not have_iconv and get_option('iconv').enabled()
error('iconv() not available')
diff --git a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
index 9ea58f33d..03da63886 100644
--- a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
+++ b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
@@ -109,11 +109,6 @@ NeighborExplorer::List
SmbclientNeighborExplorer::GetList() const noexcept
{
const std::lock_guard<Mutex> protect(mutex);
- /*
- List list;
- for (const auto &i : servers)
- list.emplace_front(i.Export());
- */
return list;
}
diff --git a/src/output/plugins/OSXOutputPlugin.cxx b/src/output/plugins/OSXOutputPlugin.cxx
index f4c7f25a0..2d489c474 100644
--- a/src/output/plugins/OSXOutputPlugin.cxx
+++ b/src/output/plugins/OSXOutputPlugin.cxx
@@ -477,7 +477,7 @@ osx_output_set_buffer_size(AudioUnit au, AudioStreamBasicDescription desc)
}
static void
-osx_output_hog_device(AudioDeviceID dev_id, bool hog)
+osx_output_hog_device(AudioDeviceID dev_id, bool hog) noexcept
{
static constexpr AudioObjectPropertyAddress aopa = {
kAudioDevicePropertyHogMode,
@@ -485,8 +485,16 @@ osx_output_hog_device(AudioDeviceID dev_id, bool hog)
kAudioObjectPropertyElementMaster
};
- pid_t hog_pid = AudioObjectGetPropertyDataT<pid_t>(dev_id,
- aopa);
+ pid_t hog_pid;
+
+ try {
+ hog_pid = AudioObjectGetPropertyDataT<pid_t>(dev_id, aopa);
+ } catch (...) {
+ Log(LogLevel::DEBUG, std::current_exception(),
+ "Failed to query HogMode");
+ return;
+ }
+
if (hog) {
if (hog_pid != -1) {
FormatDebug(osx_output_domain,
diff --git a/src/output/plugins/sles/SlesOutputPlugin.cxx b/src/output/plugins/sles/SlesOutputPlugin.cxx
index 3b345e2e0..5a4c22a53 100644
--- a/src/output/plugins/sles/SlesOutputPlugin.cxx
+++ b/src/output/plugins/sles/SlesOutputPlugin.cxx
@@ -173,12 +173,12 @@ SlesOutput::Open(AudioFormat &audio_format)
if (audio_format.channels > 2)
audio_format.channels = 1;
- SLDataFormat_PCM format_pcm;
+ SLAndroidDataFormat_PCM_EX format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = audio_format.channels;
/* from the Android NDK docs: "Note that the field samplesPerSec is
actually in units of milliHz, despite the misleading name." */
- format_pcm.samplesPerSec = audio_format.sample_rate * 1000u;
+ format_pcm.sampleRate = audio_format.sample_rate * 1000u;
format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
format_pcm.channelMask = audio_format.channels == 1
@@ -187,6 +187,36 @@ SlesOutput::Open(AudioFormat &audio_format)
format_pcm.endianness = IsLittleEndian()
? SL_BYTEORDER_LITTLEENDIAN
: SL_BYTEORDER_BIGENDIAN;
+ format_pcm.representation = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
+
+ switch (audio_format.format) {
+ /* note: Android doesn't support
+ SL_PCMSAMPLEFORMAT_FIXED_24 and
+ SL_PCMSAMPLEFORMAT_FIXED_32, so let's not bother
+ implement it here; SL_PCMSAMPLEFORMAT_FIXED_8
+ appears to be unsigned, so not usable for us (and
+ converting S8 to U8 is not worth the trouble) */
+
+ case SampleFormat::S16:
+ /* bitsPerSample and containerSize already set for 16
+ bit */
+ break;
+
+ case SampleFormat::FLOAT:
+ /* Android has an OpenSLES extension for floating
+ point samples:
+ https://developer.android.com/ndk/guides/audio/opensl/android-extensions */
+ format_pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
+ format_pcm.bitsPerSample = format_pcm.containerSize =
+ SL_PCMSAMPLEFORMAT_FIXED_32;
+ format_pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
+ break;
+
+ default:
+ /* fall back to 16 bit */
+ audio_format.format = SampleFormat::S16;
+ break;
+ }
SLDataSource audioSrc = { &loc_bufq, &format_pcm };
@@ -291,9 +321,6 @@ SlesOutput::Open(AudioFormat &audio_format)
n_queued = 0;
next = 0;
filled = 0;
-
- // TODO: support other sample formats
- audio_format.format = SampleFormat::S16;
}
void
diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx
index d4a61b729..2c145a262 100644
--- a/src/util/ByteOrder.hxx
+++ b/src/util/ByteOrder.hxx
@@ -74,39 +74,39 @@
#endif
constexpr bool
-IsLittleEndian()
+IsLittleEndian() noexcept
{
return IS_LITTLE_ENDIAN;
}
constexpr bool
-IsBigEndian()
+IsBigEndian() noexcept
{
return IS_BIG_ENDIAN;
}
constexpr uint16_t
-GenericByteSwap16(uint16_t value)
+GenericByteSwap16(uint16_t value) noexcept
{
return (value >> 8) | (value << 8);
}
constexpr uint32_t
-GenericByteSwap32(uint32_t value)
+GenericByteSwap32(uint32_t value) noexcept
{
return (value >> 24) | ((value >> 8) & 0x0000ff00) |
((value << 8) & 0x00ff0000) | (value << 24);
}
constexpr uint64_t
-GenericByteSwap64(uint64_t value)
+GenericByteSwap64(uint64_t value) noexcept
{
return uint64_t(GenericByteSwap32(uint32_t(value >> 32)))
| (uint64_t(GenericByteSwap32(value)) << 32);
}
constexpr uint16_t
-ByteSwap16(uint16_t value)
+ByteSwap16(uint16_t value) noexcept
{
#if CLANG_OR_GCC_VERSION(4,8)
return __builtin_bswap16(value);
@@ -116,7 +116,7 @@ ByteSwap16(uint16_t value)
}
constexpr uint32_t
-ByteSwap32(uint32_t value)
+ByteSwap32(uint32_t value) noexcept
{
#if CLANG_OR_GCC_VERSION(4,3)
return __builtin_bswap32(value);
@@ -126,7 +126,7 @@ ByteSwap32(uint32_t value)
}
constexpr uint64_t
-ByteSwap64(uint64_t value)
+ByteSwap64(uint64_t value) noexcept
{
#if CLANG_OR_GCC_VERSION(4,3)
return __builtin_bswap64(value);
@@ -139,7 +139,7 @@ ByteSwap64(uint64_t value)
* Converts a 16bit value from big endian to the system's byte order
*/
constexpr uint16_t
-FromBE16(uint16_t value)
+FromBE16(uint16_t value) noexcept
{
return IsBigEndian() ? value : ByteSwap16(value);
}
@@ -148,7 +148,7 @@ FromBE16(uint16_t value)
* Converts a 32bit value from big endian to the system's byte order
*/
constexpr uint32_t
-FromBE32(uint32_t value)
+FromBE32(uint32_t value) noexcept
{
return IsBigEndian() ? value : ByteSwap32(value);
}
@@ -157,7 +157,7 @@ FromBE32(uint32_t value)
* Converts a 64bit value from big endian to the system's byte order
*/
constexpr uint64_t
-FromBE64(uint64_t value)
+FromBE64(uint64_t value) noexcept
{
return IsBigEndian() ? value : ByteSwap64(value);
}
@@ -166,7 +166,7 @@ FromBE64(uint64_t value)
* Converts a 16bit value from little endian to the system's byte order
*/
constexpr uint16_t
-FromLE16(uint16_t value)
+FromLE16(uint16_t value) noexcept
{
return IsLittleEndian() ? value : ByteSwap16(value);
}
@@ -175,7 +175,7 @@ FromLE16(uint16_t value)
* Converts a 32bit value from little endian to the system's byte order
*/
constexpr uint32_t
-FromLE32(uint32_t value)
+FromLE32(uint32_t value) noexcept
{
return IsLittleEndian() ? value : ByteSwap32(value);
}
@@ -184,7 +184,7 @@ FromLE32(uint32_t value)
* Converts a 64bit value from little endian to the system's byte order
*/
constexpr uint64_t
-FromLE64(uint64_t value)
+FromLE64(uint64_t value) noexcept
{
return IsLittleEndian() ? value : ByteSwap64(value);
}
@@ -193,7 +193,7 @@ FromLE64(uint64_t value)
* Converts a 16bit value from the system's byte order to big endian
*/
constexpr uint16_t
-ToBE16(uint16_t value)
+ToBE16(uint16_t value) noexcept
{
return IsBigEndian() ? value : ByteSwap16(value);
}
@@ -202,7 +202,7 @@ ToBE16(uint16_t value)
* Converts a 32bit value from the system's byte order to big endian
*/
constexpr uint32_t
-ToBE32(uint32_t value)
+ToBE32(uint32_t value) noexcept
{
return IsBigEndian() ? value : ByteSwap32(value);
}
@@ -211,7 +211,7 @@ ToBE32(uint32_t value)
* Converts a 64bit value from the system's byte order to big endian
*/
constexpr uint64_t
-ToBE64(uint64_t value)
+ToBE64(uint64_t value) noexcept
{
return IsBigEndian() ? value : ByteSwap64(value);
}
@@ -220,7 +220,7 @@ ToBE64(uint64_t value)
* Converts a 16bit value from the system's byte order to little endian
*/
constexpr uint16_t
-ToLE16(uint16_t value)
+ToLE16(uint16_t value) noexcept
{
return IsLittleEndian() ? value : ByteSwap16(value);
}
@@ -229,7 +229,7 @@ ToLE16(uint16_t value)
* Converts a 32bit value from the system's byte order to little endian
*/
constexpr uint32_t
-ToLE32(uint32_t value)
+ToLE32(uint32_t value) noexcept
{
return IsLittleEndian() ? value : ByteSwap32(value);
}
@@ -238,7 +238,7 @@ ToLE32(uint32_t value)
* Converts a 64bit value from the system's byte order to little endian
*/
constexpr uint64_t
-ToLE64(uint64_t value)
+ToLE64(uint64_t value) noexcept
{
return IsLittleEndian() ? value : ByteSwap64(value);
}
diff --git a/win32/build.py b/win32/build.py
index fb636ded5..8aa87e288 100755
--- a/win32/build.py
+++ b/win32/build.py
@@ -66,6 +66,11 @@ class CrossGccToolchain:
' -static-libstdc++ -static-libgcc'
self.libs = ''
+ # Explicitly disable _FORTIFY_SOURCE because it is broken with
+ # mingw. This prevents some libraries such as libFLAC to
+ # enable it.
+ self.cppflags += ' -D_FORTIFY_SOURCE=0'
+
self.is_arm = arch.startswith('arm')
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
self.is_aarch64 = arch == 'aarch64'