Added benchmarks and tests for AudioBuffers
This commit is contained in:
parent
7773ef81bc
commit
32aaa6b917
8 changed files with 142 additions and 10 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -10,3 +10,6 @@
|
|||
[submodule "external/cxxopts"]
|
||||
path = external/cxxopts
|
||||
url = https://github.com/jarro2783/cxxopts
|
||||
[submodule "external/benchmark"]
|
||||
path = external/benchmark
|
||||
url = https://github.com/google/benchmark
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ project(sfizz VERSION 1.0.0 LANGUAGES CXX)
|
|||
# Set the highest possible standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Disable Abseil tests
|
||||
set(BUILD_TESTING OFF)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT ANDROID)
|
||||
add_compile_options(-stdlib=libc++)
|
||||
|
|
@ -15,11 +13,19 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT ANDROID)
|
|||
add_link_options(-stdlib=libc++) # New command on CMake master, not in 3.12 release
|
||||
endif()
|
||||
|
||||
# Disable Abseil tests
|
||||
set(BUILD_TESTING OFF)
|
||||
add_subdirectory(external/abseil-cpp)
|
||||
add_subdirectory(external/spdlog)
|
||||
add_subdirectory(external/Catch2)
|
||||
add_subdirectory(external/cxxopts)
|
||||
|
||||
#Disable Benchmark tests and installation
|
||||
set(BENCHMARK_ENABLE_TESTING OFF)
|
||||
set(BENCHMARK_ENABLE_INSTALL OFF)
|
||||
set(BENCHMARK_ENABLE_GTEST_TESTS OFF)
|
||||
add_subdirectory(external/benchmark)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(COMMON_SOURCES
|
||||
|
|
@ -31,10 +37,6 @@ set(COMMON_SOURCES
|
|||
)
|
||||
|
||||
set(TEST_SOURCES
|
||||
sources/Opcode.cpp
|
||||
sources/Synth.cpp
|
||||
sources/Region.cpp
|
||||
sources/Parser.cpp
|
||||
tests/Regex.cpp
|
||||
tests/Helpers.cpp
|
||||
tests/Region.cpp
|
||||
|
|
@ -46,6 +48,10 @@ set(TEST_SOURCES
|
|||
tests/Main.cpp
|
||||
)
|
||||
|
||||
set(BENCHMARK_SOURCES
|
||||
benchmarks/Main.cpp
|
||||
benchmarks/AudioBuffers.cpp
|
||||
)
|
||||
|
||||
###############################
|
||||
add_executable(sfzprint sources/ParserMain.cpp ${COMMON_SOURCES})
|
||||
|
|
@ -74,4 +80,12 @@ target_link_libraries(sfizz_tests stdc++fs)
|
|||
endif(UNIX)
|
||||
target_link_libraries(sfizz_tests Catch2::Catch2 absl::strings)
|
||||
target_include_directories(sfizz_tests SYSTEM PRIVATE sources)
|
||||
file(COPY "tests" DESTINATION ${CMAKE_BINARY_DIR})
|
||||
file(COPY "tests" DESTINATION ${CMAKE_BINARY_DIR})
|
||||
|
||||
###############################
|
||||
add_executable(sfizz_bench ${BENCHMARK_SOURCES} ${COMMON_SOURCES})
|
||||
# Per OS properties
|
||||
if(UNIX)
|
||||
target_link_libraries(sfizz_bench stdc++fs)
|
||||
endif(UNIX)
|
||||
target_link_libraries(sfizz_bench absl::strings benchmark)
|
||||
49
benchmarks/AudioBuffers.cpp
Normal file
49
benchmarks/AudioBuffers.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#include <benchmark/benchmark.h>
|
||||
#include "../sources/AudioBuffer.h"
|
||||
#include <algorithm>
|
||||
|
||||
static void AB_Joint_Fill_float(benchmark::State& state) {
|
||||
AudioBuffer<float> buffer (65535);
|
||||
float fillValue = 0.0f;
|
||||
for (auto _ : state) {
|
||||
std::fill(buffer.begin(0), buffer.end(0), fillValue);
|
||||
std::fill(buffer.begin(1), buffer.end(1), fillValue);
|
||||
fillValue += 1.0f;
|
||||
}
|
||||
}
|
||||
// Register the function as a benchmark
|
||||
BENCHMARK(AB_Joint_Fill_float);
|
||||
|
||||
static void AB_Split_Fill_float(benchmark::State& state) {
|
||||
SplitAudioBuffer<float> buffer (65535);
|
||||
float fillValue = 0.0f;
|
||||
for (auto _ : state) {
|
||||
std::fill(buffer.begin(0), buffer.end(0), fillValue);
|
||||
std::fill(buffer.begin(1), buffer.end(1), fillValue);
|
||||
fillValue += 1.0f;
|
||||
}
|
||||
}
|
||||
BENCHMARK(AB_Split_Fill_float);
|
||||
|
||||
static void AB_Joint_Fill_double(benchmark::State& state) {
|
||||
AudioBuffer<double> buffer (65535);
|
||||
double fillValue = 0.0;
|
||||
for (auto _ : state) {
|
||||
std::fill(buffer.begin(0), buffer.end(0), fillValue);
|
||||
std::fill(buffer.begin(1), buffer.end(1), fillValue);
|
||||
fillValue += 1.0;
|
||||
}
|
||||
}
|
||||
// Register the function as a benchmark
|
||||
BENCHMARK(AB_Joint_Fill_double);
|
||||
|
||||
static void AB_Split_Fill_double(benchmark::State& state) {
|
||||
SplitAudioBuffer<double> buffer (65535);
|
||||
double fillValue = 0.0;
|
||||
for (auto _ : state) {
|
||||
std::fill(buffer.begin(0), buffer.end(0), fillValue);
|
||||
std::fill(buffer.begin(1), buffer.end(1), fillValue);
|
||||
fillValue += 1.0;
|
||||
}
|
||||
}
|
||||
BENCHMARK(AB_Split_Fill_double);
|
||||
3
benchmarks/Main.cpp
Normal file
3
benchmarks/Main.cpp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include <benchmark/benchmark.h>
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
1
external/benchmark
vendored
Submodule
1
external/benchmark
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 66482d538d6c6041b29ab6a95cf5b6d561fbd306
|
||||
|
|
@ -44,6 +44,30 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Type* begin(int channelIndex) noexcept
|
||||
{
|
||||
ASSERT(channelIndex >= 0);
|
||||
return buffer.data() + numFrames * channelIndex;
|
||||
}
|
||||
|
||||
Type* end(int channelIndex) noexcept
|
||||
{
|
||||
ASSERT(channelIndex >= 0);
|
||||
return buffer.data() + numFrames * (channelIndex + 1);
|
||||
}
|
||||
|
||||
// const Type* cbegin(int channelIndex) noexcept
|
||||
// {
|
||||
// ASSERT(channelIndex >= 0);
|
||||
// return buffer.data() + numFrames * channelIndex;
|
||||
// }
|
||||
|
||||
// const Type* cend(int channelIndex) noexcept
|
||||
// {
|
||||
// ASSERT(channelIndex >= 0);
|
||||
// return buffer.data() + numFrames * (channelIndex + 1);
|
||||
// }
|
||||
|
||||
Type& operator()(int channelIndex, int sampleIndex) noexcept
|
||||
{
|
||||
return getSample(channelIndex, sampleIndex);
|
||||
|
|
@ -99,13 +123,32 @@ public:
|
|||
|
||||
Type* getChannel(int channelIndex) noexcept
|
||||
{
|
||||
ASSERT(channelIndex >= 0);
|
||||
if (channelIndex < NumChannels)
|
||||
return &buffers[channelIndex].data();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Type* begin(int channelIndex) noexcept
|
||||
{
|
||||
return buffers[channelIndex].begin();
|
||||
}
|
||||
|
||||
Type* end(int channelIndex) noexcept
|
||||
{
|
||||
return buffers[channelIndex].end();
|
||||
}
|
||||
|
||||
// const Type* cbegin(int channelIndex) noexcept
|
||||
// {
|
||||
// return buffers[channelIndex].cbegin();
|
||||
// }
|
||||
|
||||
// const Type* cend(int channelIndex) noexcept
|
||||
// {
|
||||
// return buffers[channelIndex].cend();
|
||||
// }
|
||||
|
||||
int getNumFrames() const noexcept { return numFrames; }
|
||||
int getNumChannels() const noexcept { return NumChannels; }
|
||||
bool empty() const noexcept { return numFrames == 0; }
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ public:
|
|||
|
||||
Type* begin() noexcept { return data(); }
|
||||
Type* end() noexcept { return data() + alignedSize; }
|
||||
const Type* cbegin() const noexcept { return data(); }
|
||||
const Type* cend() const noexcept { return data() + alignedSize; }
|
||||
// const Type* cbegin() const noexcept { return data(); }
|
||||
// const Type* cend() const noexcept { return data() + alignedSize; }
|
||||
private:
|
||||
size_t largerSize { 0 };
|
||||
size_t alignedSize { 0 };
|
||||
|
|
|
|||
|
|
@ -91,4 +91,23 @@ TEST_CASE("[AudioBuffer/SplitBuffer] Access 2")
|
|||
for (auto chanIdx = 0; chanIdx < splitDoubleBuffer.getNumChannels(); ++chanIdx)
|
||||
for (auto frameIdx = 0; frameIdx < splitDoubleBuffer.getNumFrames(); ++frameIdx)
|
||||
REQUIRE(splitDoubleBuffer(chanIdx, frameIdx) == static_cast<int>(splitDoubleBuffer.getNumFrames()) * chanIdx + frameIdx);
|
||||
}
|
||||
|
||||
TEST_CASE("[AudioBuffer/SplitBuffer] Iterators")
|
||||
{
|
||||
const int size { 256 };
|
||||
const float fillValue { 2.0f };
|
||||
AudioBuffer<float> buffer(size);
|
||||
for (auto chanIdx = 0; chanIdx < buffer.getNumChannels(); ++chanIdx)
|
||||
std::fill(buffer.begin(chanIdx), buffer.end(chanIdx), fillValue);
|
||||
|
||||
for (auto chanIdx = 0; chanIdx < buffer.getNumChannels(); ++chanIdx)
|
||||
REQUIRE( std::all_of(buffer.begin(chanIdx), buffer.end(chanIdx), [fillValue](auto value) { return value == fillValue; }) );
|
||||
|
||||
SplitAudioBuffer<float> splitBuffer(size);
|
||||
for (auto chanIdx = 0; chanIdx < splitBuffer.getNumChannels(); ++chanIdx)
|
||||
std::fill(splitBuffer.begin(chanIdx), splitBuffer.end(chanIdx), fillValue);
|
||||
|
||||
for (auto chanIdx = 0; chanIdx < splitBuffer.getNumChannels(); ++chanIdx)
|
||||
REQUIRE( std::all_of(splitBuffer.begin(chanIdx), splitBuffer.end(chanIdx), [fillValue](auto value) { return value == fillValue; }) );
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue