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
10 changed files
with
227 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(Ogg_LIBRARY | ||
NAMES ogg | ||
) | ||
|
||
set(Ogg_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of ogg") | ||
|
||
set(Ogg_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of ogg") | ||
|
||
set(Ogg_LINK_FLAGS "" CACHE STRING "Extra link flags of ogg") | ||
|
||
find_path(Ogg_INCLUDE_PATH | ||
NAMES ogg.h | ||
PATH_SUFFIXES ogg | ||
) | ||
|
||
find_package_handle_standard_args(Ogg | ||
REQUIRED_VARS Ogg_LIBRARY Ogg_INCLUDE_PATH | ||
) | ||
|
||
if (Ogg_FOUND) | ||
set(Ogg_dirs ${Ogg_INCLUDE_PATH}) | ||
if(EXISTS "${Ogg_INCLUDE_PATH}/ogg") | ||
list(APPEND Ogg_dirs "${Ogg_INCLUDE_PATH}/ogg") | ||
endif() | ||
if (NOT TARGET Ogg::ogg) | ||
add_library(Ogg::ogg UNKNOWN IMPORTED) | ||
set_target_properties(Ogg::ogg PROPERTIES | ||
IMPORTED_LOCATION "${Ogg_LIBRARY}" | ||
INTERFACE_INCLUDE_DIRECTORIES "${Ogg_dirs}" | ||
INTERFACE_COMPILE_OPTIONS "${Ogg_COMPILE_OPTIONS}" | ||
INTERFACE_LINK_LIBRARIES "${Ogg_LINK_LIBRARIES}" | ||
INTERFACE_LINK_FLAGS "${Ogg_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
include(FindPackageHandleStandardArgs) | ||
|
||
find_library(Opus_LIBRARY | ||
NAMES opus | ||
) | ||
|
||
set(Opus_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of opus") | ||
|
||
set(Opus_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of opus") | ||
|
||
set(Opus_LINK_FLAGS "" CACHE STRING "Extra link flags of opus") | ||
|
||
find_path(Opus_INCLUDE_PATH | ||
NAMES opus.h | ||
PATH_SUFFIXES opus | ||
) | ||
|
||
find_package_handle_standard_args(Opus | ||
REQUIRED_VARS Opus_LIBRARY Opus_INCLUDE_PATH | ||
) | ||
|
||
if (Opus_FOUND) | ||
set(Opus_dirs ${Opus_INCLUDE_PATH}) | ||
if(EXISTS "${Opus_INCLUDE_PATH}/opus") | ||
list(APPEND Opus_dirs "${Opus_INCLUDE_PATH}/opus") | ||
endif() | ||
if (NOT TARGET Opus::opus) | ||
add_library(Opus::opus UNKNOWN IMPORTED) | ||
set_target_properties(Opus::opus PROPERTIES | ||
IMPORTED_LOCATION "${Opus_LIBRARY}" | ||
INTERFACE_INCLUDE_DIRECTORIES "${Opus_dirs}" | ||
INTERFACE_COMPILE_OPTIONS "${Opus_COMPILE_OPTIONS}" | ||
INTERFACE_LINK_LIBRARIES "${Opus_LINK_LIBRARIES}" | ||
INTERFACE_LINK_FLAGS "${Opus_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
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 | ||
) | ||
|
||
find_package(Ogg) | ||
find_package(Opus) | ||
|
||
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 "Ogg::ogg;Opus::opus;${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,95 @@ | ||
/* | ||
* 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 "random_access_file_type.h" | ||
#include "sound_type.h" | ||
#include "soundloader_type.h" | ||
|
||
#include <opusfile.h> | ||
|
||
#include "safeguards.h" | ||
|
||
/** Opus sound loader. */ | ||
class SoundLoader_Opus : public SoundLoader { | ||
public: | ||
SoundLoader_Opus() : SoundLoader("opus", "Opus sound loader", 10) {} | ||
|
||
static constexpr uint16_t OPUS_SAMPLE_RATE = 48000; ///< OpusFile always decodes at 48kHz. | ||
static constexpr uint8_t OPUS_SAMPLE_BITS = 16; ///< OpusFile op_read() uses 16 bits per sample. | ||
|
||
/* 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, as identified by the initial file header. */ | ||
auto filepos = sound.file->GetPos(); | ||
std::vector<uint8_t> tmp(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 link_index; | ||
int read = op_read(of.get(), reinterpret_cast<opus_int16 *>(&data[datapos]), DECODE_BUFFER_BYTES, &link_index); | ||
if (read == 0) break; | ||
|
||
if (read < 0 || op_channel_count(of.get(), link_index) != 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 = OPUS_SAMPLE_BITS; | ||
sound.rate = OPUS_SAMPLE_RATE; | ||
|
||
/* 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 RAII release an OggOpusFile. */ | ||
struct OggOpusFileDeleter { | ||
void operator()(OggOpusFile *of) | ||
{ | ||
if (of != nullptr) op_free(of); | ||
} | ||
}; | ||
}; | ||
|
||
static SoundLoader_Opus s_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": "sdl2", | ||
"platform": "linux" | ||
|