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: Support sound effects in Ogg Opus format.
- Loading branch information
Showing
8 changed files
with
142 additions
and
0 deletions.
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
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,37 @@ | ||
include(FindPackageHandleStandardArgs) | ||
|
||
find_library(OpusFile_LIBRARY | ||
NAMES opusfile | ||
) | ||
|
||
set(OpusFile_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of opusfile") | ||
|
||
set(OpusFile_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of opusfile") | ||
|
||
set(OpusFile_LINK_FLAGS "" CACHE STRING "Extra link flags of opusfile") | ||
|
||
find_path(OpusFile_INCLUDE_PATH | ||
NAMES opusfile.h | ||
PATH_SUFFIXES opus | ||
) | ||
|
||
find_package_handle_standard_args(OpusFile | ||
REQUIRED_VARS OpusFile_LIBRARY OpusFile_INCLUDE_PATH | ||
) | ||
|
||
if (OpusFile_FOUND) | ||
set(OpusFile_dirs ${OpusFile_INCLUDE_PATH}) | ||
if(EXISTS "${OpusFile_INCLUDE_PATH}/opus") | ||
list(APPEND OpusFile_dirs "${OpusFile_INCLUDE_PATH}/opus") | ||
endif() | ||
if (NOT TARGET OpusFile::opusfile) | ||
add_library(OpusFile::opusfile UNKNOWN IMPORTED) | ||
set_target_properties(OpusFile::opusfile PROPERTIES | ||
IMPORTED_LOCATION "${OpusFile_LIBRARY}" | ||
INTERFACE_INCLUDE_DIRECTORIES "${OpusFile_dirs}" | ||
INTERFACE_COMPILE_OPTIONS "${OpusFile_COMPILE_OPTIONS}" | ||
INTERFACE_LINK_LIBRARIES "${OpusFile_LINK_LIBRARIES}" | ||
INTERFACE_LINK_FLAGS "${OpusFile_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* 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 sound_opus.cpp Loading of opus sounds. */ | ||
|
||
#include "stdafx.h" | ||
#include "core/bitmath_func.hpp" | ||
#include "random_access_file_type.h" | ||
#include "sound_type.h" | ||
#include "soundloader_type.h" | ||
|
||
#include <opusfile.h> | ||
|
||
#include "safeguards.h" | ||
|
||
/** Opus sound louder. */ | ||
class SoundLoader_Opus : public SoundLoader { | ||
public: | ||
SoundLoader_Opus() : SoundLoader("opus", 10) {} | ||
|
||
/* For good results, you will need at least 57 bytes (for a pure Opus-only stream). */ | ||
static constexpr size_t MIN_OPUS_FILE_SIZE = 57U; | ||
|
||
/* It is recommended that this be large enough for at least 120 ms of data at 48 kHz per channel (5760 values per channel). | ||
* Smaller buffers will simply return less data, possibly consuming more memory to buffer the data internally. */ | ||
static constexpr size_t DECODE_BUFFER_SAMPLES = 5760 * 2; | ||
static constexpr size_t DECODE_BUFFER_BYTES = DECODE_BUFFER_SAMPLES * sizeof(opus_int16); | ||
|
||
bool Load(SoundEntry &sound, bool new_format, std::vector<uint8_t> &data) override | ||
{ | ||
if (!new_format) return false; | ||
|
||
/* At least 57 bytes are needed for an Opus-only file. */ | ||
if (sound.file_size < MIN_OPUS_FILE_SIZE) return false; | ||
|
||
/* Test if data is an Ogg Opus stream. */ | ||
auto filepos = sound.file->GetPos(); | ||
std::vector<uint8_t> tmp(std::min(sound.file_size, MIN_OPUS_FILE_SIZE)); | ||
sound.file->ReadBlock(tmp.data(), tmp.size()); | ||
if (op_test(nullptr, tmp.data(), tmp.size()) != 0) return false; | ||
|
||
/* Read the whole file into memory. */ | ||
tmp.resize(sound.file_size); | ||
sound.file->SeekTo(filepos, SEEK_SET); | ||
sound.file->ReadBlock(tmp.data(), tmp.size()); | ||
|
||
int error = 0; | ||
auto of = std::unique_ptr<OggOpusFile, OggOpusFileDeleter>(op_open_memory(tmp.data(), tmp.size(), &error)); | ||
if (error != 0) return false; | ||
|
||
size_t datapos = 0; | ||
for (;;) { | ||
data.resize(datapos + DECODE_BUFFER_BYTES); | ||
int li; | ||
int read = op_read(of.get(), reinterpret_cast<opus_int16 *>(&data[datapos]), DECODE_BUFFER_BYTES, &li); | ||
if (read == 0) break; | ||
|
||
if (read < 0 || op_channel_count(of.get(), li) != 1) { | ||
/* Error reading, or incorrect channel count. */ | ||
data.clear(); | ||
return false; | ||
} | ||
|
||
datapos += read * sizeof(opus_int16); | ||
} | ||
|
||
/* OpusFile always decodes at 48kHz. */ | ||
sound.channels = 1; | ||
sound.bits_per_sample = 16; | ||
sound.rate = 48000; | ||
|
||
/* We resized by DECODE_BUFFER_BYTES just before finally reading zero bytes, undo this. */ | ||
data.resize(data.size() - DECODE_BUFFER_BYTES); | ||
|
||
return true; | ||
} | ||
|
||
private: | ||
/** Helper class to properly RAII release an OggOpusFile. */ | ||
struct OggOpusFileDeleter { | ||
void operator()(OggOpusFile *of) | ||
{ | ||
if (of != nullptr) op_free(of); | ||
} | ||
}; | ||
}; | ||
|
||
static SoundLoader_Opus _sound_loader_opus; |
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 |
---|---|---|
|
@@ -42,6 +42,9 @@ | |
{ | ||
"name": "lzo" | ||
}, | ||
{ | ||
"name": "opusfile" | ||
}, | ||
{ | ||
"name": "soxr" | ||
}, | ||
|