From 4114b17686527b5e34edfae14c8afe2650bd1a98 Mon Sep 17 00:00:00 2001 From: MeijisIrlnd Date: Sat, 14 Sep 2024 12:15:18 +0100 Subject: [PATCH] Sanity check tests --- .../mostly_harmless/mostlyharmless_Plugin.h | 9 +- tests/CMakeLists.txt | 1 + tests/audio/mostlyharmless_TestHelpers.cpp | 3 + tests/audio/mostlyharmless_TestHelpers.h | 47 ++++++++ tests/audio/mostlyharmless_TestPlugin.cpp | 107 ++++++++++++++++++ .../utils/mostlyharmless_TaskThreadTests.cpp | 1 + tests/utils/mostlyharmless_TimerTests.cpp | 1 + 7 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 tests/audio/mostlyharmless_TestHelpers.cpp create mode 100644 tests/audio/mostlyharmless_TestHelpers.h create mode 100644 tests/audio/mostlyharmless_TestPlugin.cpp diff --git a/include/mostly_harmless/mostlyharmless_Plugin.h b/include/mostly_harmless/mostlyharmless_Plugin.h index 151bb06..2e03de1 100644 --- a/include/mostly_harmless/mostlyharmless_Plugin.h +++ b/include/mostly_harmless/mostlyharmless_Plugin.h @@ -99,6 +99,12 @@ namespace mostly_harmless { */ virtual std::unique_ptr createEditor() noexcept = 0; + /// @private + bool activate(double sampleRate, std::uint32_t minFrameCount, std::uint32_t maxFrameCount) noexcept override; + /// @private + clap_process_status process(const clap_process* processContext) noexcept override; + /// @private + void paramsFlush(const clap_input_events* in, const clap_output_events* out) noexcept override; protected: /** Retrieves a parameter by its param id was constructed with. @@ -158,9 +164,6 @@ namespace mostly_harmless { void handleEvent(const clap_event_header_t* event) noexcept; private: - bool activate(double sampleRate, std::uint32_t minFrameCount, std::uint32_t maxFrameCount) noexcept override; - clap_process_status process(const clap_process* processContext) noexcept override; - void paramsFlush(const clap_input_events* in, const clap_output_events* out) noexcept override; void handleGuiEvents(const clap_output_events_t* outputQueue) noexcept; [[nodiscard]] bool implementsParams() const noexcept override; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 08f37ea..ff19e54 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,4 +3,5 @@ set(MOSTLYHARMLESS_TEST_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/mostlyharmless_TestDescriptor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/utils/mostlyharmless_TaskThreadTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/utils/mostlyharmless_TimerTests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/audio/mostlyharmless_TestPlugin.cpp PARENT_SCOPE) \ No newline at end of file diff --git a/tests/audio/mostlyharmless_TestHelpers.cpp b/tests/audio/mostlyharmless_TestHelpers.cpp new file mode 100644 index 0000000..3bd6135 --- /dev/null +++ b/tests/audio/mostlyharmless_TestHelpers.cpp @@ -0,0 +1,3 @@ +// +// Created by Syl Morrison on 11/09/2024. +// diff --git a/tests/audio/mostlyharmless_TestHelpers.h b/tests/audio/mostlyharmless_TestHelpers.h new file mode 100644 index 0000000..e69f3db --- /dev/null +++ b/tests/audio/mostlyharmless_TestHelpers.h @@ -0,0 +1,47 @@ +// +// Created by Syl Morrison on 11/09/2024. +// + +#ifndef MOSTLYHARMLESS_MOSTLYHARMLESS_TESTHELPERS_H +#define MOSTLYHARMLESS_MOSTLYHARMLESS_TESTHELPERS_H +#include +#include +#include +#include +namespace mostly_harmless::testing { + template + requires (N > 0) + [[nodiscard]] std::vector generateImpulse() { + std::vector impulse(N, static_cast(0.0)); + impulse.front() = static_cast(1.0); + return impulse; + } + + template + SampleType** generateImpulse() { + using namespace marvin::literals; + SampleType** arr = new SampleType*[2]; + for(auto channel = 0_sz; channel < NumChannels; ++channel) { + arr[channel] = new SampleType[BufferSize]; + std::memset(arr[channel], 0, BufferSize * sizeof(SampleType)); + arr[channel][0] = static_cast(1); + } + return arr; + } + + template + bool checkBuffer(marvin::containers::BufferView buffer) { + using namespace marvin::literals; + const auto* const* read = buffer.getArrayOfReadPointers(); + for(auto channel = 0_sz; channel < buffer.getNumChannels(); ++channel) { + for(auto sample = 0_sz; sample < buffer.getNumSamples(); ++sample) { + const auto x = read[channel][sample]; + if(std::isnan(x) || std::isinf(x)) { + return false; + } + } + } + return true; + } +} +#endif // MOSTLYHARMLESS_MOSTLYHARMLESS_TESTHELPERS_H diff --git a/tests/audio/mostlyharmless_TestPlugin.cpp b/tests/audio/mostlyharmless_TestPlugin.cpp new file mode 100644 index 0000000..ee0cca7 --- /dev/null +++ b/tests/audio/mostlyharmless_TestPlugin.cpp @@ -0,0 +1,107 @@ +// +// Created by Syl Morrison on 11/09/2024. +// +#include "mostlyharmless_TestHelpers.h" +#include +#include +#include +#include +namespace mostly_harmless::testing { + template + class GenericPlugin : public mostly_harmless::Plugin { + public: + explicit GenericPlugin(const clap_host* host) : mostly_harmless::Plugin(host, {}) { + } + void initialise(double sampleRate, std::uint32_t minFrame, std::uint32_t maxFrame) noexcept override { + } + + void process(marvin::containers::BufferView buffer, mostly_harmless::events::InputEventContext context) noexcept override { + } + + void flushParams(mostly_harmless::events::InputEventContext context) noexcept override { + } + + void reset() noexcept override { + } + + void loadState(std::string_view data) noexcept override { + } + + void saveState(std::ostringstream& outStream) noexcept override { + } + + std::unique_ptr createEditor() noexcept override { + return nullptr; + } + + private: + }; + // ret name arg + + + std::uint32_t size(const struct clap_input_events* list) { + return 0; + } + + template void testPlugin() { + using namespace marvin::literals; + auto host = std::make_unique(); + GenericPlugin plugin{ host.get() }; + plugin.activate(44100.0, BufferSize, BufferSize); + clap_audio_buffer in; + SampleType** buffer = generateImpulse(); + if constexpr (std::same_as) { + in = { + .data32 = buffer, + .data64 = nullptr, + .channel_count = NumChannels, + .latency = 0, + .constant_mask = 0x0 + }; + } else { + in = { + .data32 = nullptr, + .data64 = buffer, + .channel_count = NumChannels, + .latency = 0, + .constant_mask = 0x0 + }; + } + + auto* ctx = malloc(sizeof(SampleType) * 100); + clap_input_events inputEvents{ + .ctx = ctx, + .size = size + }; + + const clap_process process{ + .steady_time = -1, + .frames_count = BufferSize, + .transport = nullptr, + .audio_inputs = &in, + .audio_outputs = &in, + .audio_inputs_count = NumChannels, + .audio_outputs_count = NumChannels, + .in_events = &inputEvents, + .out_events = nullptr + }; + const auto res = static_cast*>(&plugin)->process(&process); + marvin::containers::BufferView view{ buffer, NumChannels, BufferSize}; + const auto bufferOk = checkBuffer(view); + REQUIRE(bufferOk); + + + free(ctx); + for (auto i = 0_sz; i < NumChannels; ++i) { + delete[] buffer[i]; + } + delete[] buffer; + } + + TEST_CASE("Test Plugin") { + testPlugin(); + testPlugin(); + testPlugin(); + testPlugin(); + } +} \ No newline at end of file diff --git a/tests/utils/mostlyharmless_TaskThreadTests.cpp b/tests/utils/mostlyharmless_TaskThreadTests.cpp index d8bf76b..2a4f38d 100644 --- a/tests/utils/mostlyharmless_TaskThreadTests.cpp +++ b/tests/utils/mostlyharmless_TaskThreadTests.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace mostly_harmless::testing { TEST_CASE("Test TaskThread") { std::mutex mutex; diff --git a/tests/utils/mostlyharmless_TimerTests.cpp b/tests/utils/mostlyharmless_TimerTests.cpp index 8a3c6c9..20998ce 100644 --- a/tests/utils/mostlyharmless_TimerTests.cpp +++ b/tests/utils/mostlyharmless_TimerTests.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace mostly_harmless::tests { TEST_CASE("Test Timer") {