From 34ec2795a10082656798ee96c6d472c050cd604d Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Sun, 8 Dec 2024 00:15:42 +0000 Subject: [PATCH] Fix Ogg ov_read call on big-endian systems In the `ov_read` API, the fouth parameter says what endianness the samples should be returned in - `0` for little-endian, and `1` for big-endian. SFML wants samples in the host endian, so we need to set this parameter to 1 on big-endian systems. Fixes a unit test failure on big-endian systems. --- changelog.md | 1 + src/SFML/Audio/CMakeLists.txt | 3 +++ src/SFML/Audio/SoundFileReaderOgg.cpp | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index cdfcf327a..e3b653dc6 100644 --- a/changelog.md +++ b/changelog.md @@ -135,6 +135,7 @@ For a closer look at breaking changes and how to migrate from SFML 2, check out - Fixed `sf::SoundStream::play` bug (#2037) - Fixed poor `sf::SoundStream::setPlayingOffset` precision (#3101) +- Fixed a bug when reading Ogg files on big endian systems (#3340) ### Network diff --git a/src/SFML/Audio/CMakeLists.txt b/src/SFML/Audio/CMakeLists.txt index d911b8475..e42ba77f6 100644 --- a/src/SFML/Audio/CMakeLists.txt +++ b/src/SFML/Audio/CMakeLists.txt @@ -169,6 +169,9 @@ target_compile_definitions(sfml-audio PRIVATE MA_NO_MP3 MA_NO_FLAC MA_NO_ENCODIN # use standard fixed-width integer types target_compile_definitions(sfml-audio PRIVATE MA_USE_STDINT) +# detect the endianness as required by Ogg +target_compile_definitions(sfml-audio PRIVATE SFML_IS_BIG_ENDIAN=$) + # setup dependencies target_link_libraries(sfml-audio PUBLIC SFML::System diff --git a/src/SFML/Audio/SoundFileReaderOgg.cpp b/src/SFML/Audio/SoundFileReaderOgg.cpp index 9ea735657..9bfa9e319 100644 --- a/src/SFML/Audio/SoundFileReaderOgg.cpp +++ b/src/SFML/Audio/SoundFileReaderOgg.cpp @@ -196,8 +196,8 @@ std::uint64_t SoundFileReaderOgg::read(std::int16_t* samples, std::uint64_t maxC std::uint64_t count = 0; while (count < maxCount) { - const int bytesToRead = static_cast(maxCount - count) * static_cast(sizeof(std::int16_t)); - const long bytesRead = ov_read(&m_vorbis, reinterpret_cast(samples), bytesToRead, 0, 2, 1, nullptr); + const int bytesToRead = static_cast(maxCount - count) * static_cast(sizeof(std::int16_t)); + const long bytesRead = ov_read(&m_vorbis, reinterpret_cast(samples), bytesToRead, SFML_IS_BIG_ENDIAN, 2, 1, nullptr); if (bytesRead > 0) { const long samplesRead = bytesRead / static_cast(sizeof(std::int16_t));