forked from OpenTTD/OpenTTD
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add: Use LibSoxr for high quality sample-rate conversion.
If not present the existing bad quality linear conversion can still be used.
- Loading branch information
Showing
12 changed files
with
169 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,7 @@ jobs: | |
libopus-dev \ | ||
libopusfile-dev \ | ||
libsdl2-dev \ | ||
libsoxr-dev \ | ||
zlib1g-dev \ | ||
# EOF | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
include(FindPackageHandleStandardArgs) | ||
|
||
find_library(Soxr_LIBRARY | ||
NAMES soxr | ||
) | ||
|
||
set(Soxr_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of soxr") | ||
|
||
set(Soxr_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of soxr") | ||
|
||
set(Soxr_LINK_FLAGS "" CACHE STRING "Extra link flags of soxr") | ||
|
||
find_path(Soxr_INCLUDE_PATH | ||
NAMES soxr.h | ||
) | ||
|
||
find_package_handle_standard_args(Soxr | ||
REQUIRED_VARS Soxr_LIBRARY Soxr_INCLUDE_PATH | ||
) | ||
|
||
if(Soxr_FOUND) | ||
if(NOT TARGET Soxr::soxr) | ||
add_library(Soxr::soxr UNKNOWN IMPORTED) | ||
set_target_properties(Soxr::soxr PROPERTIES | ||
IMPORTED_LOCATION "${Soxr_LIBRARY}" | ||
INTERFACE_INCLUDE_DIRECTORIES "${Soxr_INCLUDE_PATH}" | ||
INTERFACE_COMPILE_OPTIONS "${Soxr_COMPILE_OPTIONS}" | ||
INTERFACE_LINK_LIBRARIES "${Soxr_LINK_LIBRARIES}" | ||
INTERFACE_LINK_FLAGS "${Soxr_LINK_FLAGS}" | ||
) | ||
endif() | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* This file is part of OpenTTD. | ||
* OpenTTD 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, version 2. | ||
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/** @file soundresampler_soxr.cpp SOXR sound resampler. */ | ||
|
||
#include "stdafx.h" | ||
#include "core/math_func.hpp" | ||
#include "debug.h" | ||
#include "sound_type.h" | ||
#include "soundloader_type.h" | ||
|
||
#include <soxr.h> | ||
#include <thread> | ||
|
||
#include "safeguards.h" | ||
|
||
class SoundResampler_Soxr : public SoundResampler { | ||
public: | ||
SoundResampler_Soxr() : SoundResampler("soxr", "SOXR sound resampler", 0) {} | ||
|
||
static constexpr int BITS_PER_BYTE = 8; | ||
static constexpr int SOXR_BITS_PER_SAMPLE = 16; | ||
|
||
/** Convert samples from 8 bits to 16 bits. | ||
* @param in Vector of samples to convert. | ||
* @param out Vector to place converted samples. | ||
* @pre out vector must be exactly twice the size of in vector. | ||
*/ | ||
static void ConvertInt8toInt16(std::vector<uint8_t> &in, std::vector<uint8_t> &out) | ||
{ | ||
assert(std::size(out) == std::size(in) * 2); | ||
|
||
auto out_it = std::begin(out); | ||
for (const uint8_t &value : in) { | ||
if constexpr (std::endian::native != std::endian::little) { | ||
*out_it++ = value; | ||
*out_it++ = 0; | ||
} else { | ||
*out_it++ = 0; | ||
*out_it++ = value; | ||
} | ||
} | ||
} | ||
|
||
bool Resample(SoundEntry &sound, uint32_t play_rate) override | ||
{ | ||
/* We always convert with the same configuration, these are static so they only need to be set up once. */ | ||
static const soxr_io_spec_t io = soxr_io_spec(SOXR_INT16_I, SOXR_INT16_I); // 16-bit input and output. | ||
static const soxr_quality_spec_t quality = soxr_quality_spec(SOXR_VHQ, 0); // Use 'Very high quality'. | ||
static const soxr_runtime_spec_t runtime = soxr_runtime_spec(std::thread::hardware_concurrency()); // Enable multi-threading. | ||
|
||
/* The sound data to work on. */ | ||
std::vector<uint8_t> &data = *sound.data; | ||
|
||
std::vector<uint8_t> tmp; | ||
if (sound.bits_per_sample == SOXR_BITS_PER_SAMPLE) { | ||
/* No conversion necessary so just move from sound data to temporary buffer. */ | ||
data.swap(tmp); | ||
} else { | ||
/* SoxR cannot resample 8-bit audio, so convert from 8-bit to 16-bit into temporary buffer. */ | ||
tmp.resize(std::size(data) * sizeof(int16_t)); | ||
ConvertInt8toInt16(data, tmp); | ||
sound.bits_per_sample = SOXR_BITS_PER_SAMPLE; | ||
} | ||
|
||
/* Resize buffer ensuring it is correctly aligned. */ | ||
uint align = sound.channels * sound.bits_per_sample / BITS_PER_BYTE; | ||
data.resize(Align(std::size(tmp) * play_rate / sound.rate, align)); | ||
|
||
soxr_error_t error = soxr_oneshot(sound.rate, play_rate, sound.channels, | ||
std::data(tmp), std::size(tmp) / align, nullptr, | ||
std::data(data), std::size(data) / align, nullptr, | ||
&io, &quality, &runtime); | ||
|
||
if (error != nullptr) { | ||
/* Could not resample, try using the original data as-is without resampling instead. */ | ||
Debug(misc, 0, "Failed to resample: {}", soxr_strerror(error)); | ||
data.swap(tmp); | ||
} else { | ||
sound.rate = play_rate; | ||
} | ||
|
||
return true; | ||
} | ||
}; | ||
|
||
static SoundResampler_Soxr s_sound_resampler_soxr; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,9 @@ | |
{ | ||
"name": "opusfile" | ||
}, | ||
{ | ||
"name": "soxr" | ||
}, | ||
{ | ||
"name": "sdl2", | ||
"platform": "linux" | ||
|