1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-10-04 08:07:17 +02:00

Implement basic tests for audio decoding and playing

This commit is contained in:
Filip Gawin 2018-12-06 22:49:46 +01:00
parent 50c6eedf4f
commit a63b084d31
10 changed files with 86 additions and 38 deletions

View File

@ -84,10 +84,18 @@ find_package_handle_standard_args(FFmpeg
)
set(FFMPEG_FOUND "${FFmpeg_FOUND}")
if(FFmpeg_FOUND)
add_library(ffmpeg::ffmpeg INTERFACE IMPORTED)
set_property(TARGET ffmpeg::ffmpeg
PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${FFMPEG_INCLUDE_DIR})
set_property(TARGET ffmpeg::ffmpeg
PROPERTY INTERFACE_LINK_LIBRARIES ${FFMPEG_LIBRARIES})
find_package(Threads REQUIRED)
if(FFMPEG_FOUND)
add_library(ffmpeg INTERFACE)
target_link_libraries(ffmpeg
INTERFACE
${FFMPEG_LIBRARIES}
Threads::Threads
)
target_include_directories(ffmpeg SYSTEM
INTERFACE
"${FFMPEG_INCLUDE_DIR}"
)
add_library(ffmpeg::ffmpeg ALIAS ffmpeg)
endif()

View File

@ -17,7 +17,7 @@ extern "C" {
#include <rw/types.hpp>
Sound& SoundManager::getSoundRef(size_t name) {
Sound& SoundManager::getSfxBufferRef(size_t name) {
auto ref = buffers.find(name);
if (ref != buffers.end()) {
return ref->second;
@ -27,6 +27,10 @@ Sound& SoundManager::getSoundRef(size_t name) {
return buffers[name];
}
Sound& SoundManager::getSfxSourceRef(size_t name) {
return sfx[name];
}
Sound& SoundManager::getSoundRef(const std::string& name) {
return sounds[name]; // @todo reloading, how to check is it wav/mp3?
}

View File

@ -34,7 +34,8 @@ public:
/// Load selected sfx sound
void loadSound(size_t index);
Sound& getSoundRef(size_t name);
Sound& getSfxBufferRef(size_t name);
Sound& getSfxSourceRef(size_t name);
Sound& getSoundRef(const std::string& name);
size_t createSfxInstance(size_t index);

View File

@ -273,9 +273,7 @@ bool SoundSource::prepareCodecContextSfx() {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 37, 100)
void SoundSource::decodeFramesLegacy(size_t framesToDecode) {
size_t decoded = 0;
while ((framesToDecode == 0 || decoded < framesToDecode) &&
while ((framesToDecode == 0 || decodedFrames < framesToDecode) &&
av_read_frame(formatContext, &readingPacket) == 0) {
if (readingPacket.stream_index == audioStream->index) {
AVPacket decodingPacket = readingPacket;
@ -308,7 +306,7 @@ void SoundSource::decodeFramesLegacy(size_t framesToDecode) {
}
}
av_free_packet(&readingPacket);
++decoded;
++decodedFrames;
}
}
#endif
@ -322,9 +320,7 @@ void SoundSource::decodeFramesSfxWrap() {
}
void SoundSource::decodeFrames(size_t framesToDecode) {
size_t decoded = 0;
while ((framesToDecode == 0 || decoded < framesToDecode) &&
while ((framesToDecode == 0 || decodedFrames < framesToDecode) &&
av_read_frame(formatContext, &readingPacket) == 0) {
if (readingPacket.stream_index == audioStream->index) {
AVPacket decodingPacket = readingPacket;
@ -353,7 +349,7 @@ void SoundSource::decodeFrames(size_t framesToDecode) {
}
}
av_packet_unref(&readingPacket);
++decoded;
++decodedFrames;
}
}
@ -370,9 +366,7 @@ void SoundSource::decodeAndResampleFrames(const rwfs::path& filePath,
RW_UNUSED(filePath); // it's used by macro
AVFrame* resampled = av_frame_alloc();
size_t decoded = 0;
while ((framesToDecode == 0 || decoded < framesToDecode) &&
while ((framesToDecode == 0 || decodedFrames < framesToDecode) &&
av_read_frame(formatContext, &readingPacket) == 0) {
if (readingPacket.stream_index == audioStream->index) {
int sendPacket = avcodec_send_packet(codecContext, &readingPacket);
@ -435,7 +429,7 @@ void SoundSource::decodeAndResampleFrames(const rwfs::path& filePath,
}
}
++decoded;
++decodedFrames;
}
/// Free all data used by the resampled frame.

View File

@ -77,6 +77,8 @@ public:
void loadSfx(LoaderSDT& sdt, std::size_t index, bool asWave = true,
bool streaming = false);
unsigned int decodedFrames = 0u;
private:
/// Raw data
std::vector<int16_t> data;

View File

@ -245,7 +245,7 @@ ScriptObjectType<Sound> ScriptArguments::getScriptObject(
unsigned int arg) const {
auto& param = (*this)[arg];
RW_CHECK(param.isLvalue(), "Non lvalue passed as object");
return {param.handleValue(), &getWorld()->sound.getSoundRef(arg)};
return {param.handleValue(), &getWorld()->sound.getSfxBufferRef(arg)};
}
template <>

View File

@ -4305,7 +4305,7 @@ void opcode_018d(const ScriptArguments& args, ScriptVec3 coord, const ScriptSoun
auto metaData = getSoundInstanceData(sound0);
auto bufferName = world->sound.createSfxInstance(metaData->sfx);
world->sound.playSfx(bufferName, coord, true, metaData->range);
sound1 = &world->sound.getSoundRef(bufferName);
sound1 = &world->sound.getSfxBufferRef(bufferName);
}
/**

View File

@ -1,6 +1,7 @@
set(TESTS
Animation
Archive
AudioLoading
Buoyancy
Character
Chase

View File

@ -0,0 +1,54 @@
#include "test_Globals.hpp"
#include <engine/GameWorld.hpp>
#include <audio/SoundSource.hpp>
BOOST_AUTO_TEST_SUITE(AudioLoadingTests, DATA_TEST_PREDICATE)
// @todo Shfil119 implement
// This test requires assets
BOOST_AUTO_TEST_CASE(testBufferIsPlaying) {
SoundManager manager{Global::get().e};
auto audioPath =
Global::get().e->data->index.findFilePath("audio/A1_a.wav");
manager.loadSound("A1_a", audioPath.string());
auto& sound = manager.getSoundRef("A1_a");
BOOST_REQUIRE(sound.source->decodedFrames > 0);
BOOST_REQUIRE(sound.isPlaying() == false);
sound.play();
BOOST_REQUIRE(sound.isPlaying() == true);
sound.pause();
BOOST_REQUIRE(sound.isPaused() == true);
sound.stop();
BOOST_REQUIRE(sound.isStopped() == true);
}
BOOST_AUTO_TEST_CASE(testDecodingFramesOfMusic) {
SoundManager manager{Global::get().e};
auto audioPath =
Global::get().e->data->index.findFilePath("audio/A1_a.wav");
manager.loadSound("A1_a", audioPath.string());
auto& sound = manager.getSoundRef("A1_a");
BOOST_REQUIRE(sound.source->decodedFrames > 0);
}
BOOST_AUTO_TEST_CASE(testDecodingFramesOfSfx) {
SoundManager manager{Global::get().e};
manager.createSfxInstance(157); // Callahan Bridge fire
auto& sound = manager.getSfxSourceRef(157);
BOOST_REQUIRE(sound.source->decodedFrames > 0);
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -19,22 +19,6 @@ BOOST_FIXTURE_TEST_CASE(creates_empty_sound, F) {
BOOST_REQUIRE(sound.source == nullptr);
}
// @todo Shfil119 implement
// This test requires assets
//BOOST_AUTO_TEST_CASE(testBufferIsPlaying) {
// sound.buffer = std::make_unique<SoundBuffer>();
// BOOST_REQUIRE(sound.isPlaying() == false);
// sound.play();
// BOOST_REQUIRE(sound.isPlaying() == true);
// sound.pause();
// BOOST_REQUIRE(sound.isPaused() == true);
// sound.stop();
// BOOST_REQUIRE(sound.isStopped() == true);
//}
BOOST_FIXTURE_TEST_CASE(sound_sets_openal_source_position, F) {
sound.buffer = std::make_unique<SoundBuffer>();