Skip to content

Commit

Permalink
Sanity check tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MeijisIrlnd committed Sep 14, 2024
1 parent 4a7dfa6 commit 4114b17
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 3 deletions.
9 changes: 6 additions & 3 deletions include/mostly_harmless/mostlyharmless_Plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ namespace mostly_harmless {
*/
virtual std::unique_ptr<gui::IEditor> 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.
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
3 changes: 3 additions & 0 deletions tests/audio/mostlyharmless_TestHelpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//
// Created by Syl Morrison on 11/09/2024.
//
47 changes: 47 additions & 0 deletions tests/audio/mostlyharmless_TestHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// Created by Syl Morrison on 11/09/2024.
//

#ifndef MOSTLYHARMLESS_MOSTLYHARMLESS_TESTHELPERS_H
#define MOSTLYHARMLESS_MOSTLYHARMLESS_TESTHELPERS_H
#include <marvin/library/marvin_Concepts.h>
#include <marvin/library/marvin_Literals.h>
#include <marvin/containers/marvin_BufferView.h>
#include <vector>
namespace mostly_harmless::testing {
template<marvin::FloatType SampleType, size_t N>
requires (N > 0)
[[nodiscard]] std::vector<SampleType> generateImpulse() {
std::vector<SampleType> impulse(N, static_cast<SampleType>(0.0));
impulse.front() = static_cast<SampleType>(1.0);
return impulse;
}

template<marvin::FloatType SampleType, size_t NumChannels, size_t BufferSize>
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<SampleType>(1);
}
return arr;
}

template<marvin::FloatType SampleType>
bool checkBuffer(marvin::containers::BufferView<SampleType> 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
107 changes: 107 additions & 0 deletions tests/audio/mostlyharmless_TestPlugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// Created by Syl Morrison on 11/09/2024.
//
#include "mostlyharmless_TestHelpers.h"
#include <mostly_harmless/mostlyharmless_Plugin.h>
#include <mostly_harmless/gui/mostlyharmless_WebviewEditor.h>
#include <marvin/library/marvin_Literals.h>
#include <catch2/catch_test_macros.hpp>
namespace mostly_harmless::testing {
template <marvin::FloatType SampleType>
class GenericPlugin : public mostly_harmless::Plugin<SampleType> {
public:
explicit GenericPlugin(const clap_host* host) : mostly_harmless::Plugin<SampleType>(host, {}) {
}
void initialise(double sampleRate, std::uint32_t minFrame, std::uint32_t maxFrame) noexcept override {
}

void process(marvin::containers::BufferView<SampleType> 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<mostly_harmless::gui::IEditor> createEditor() noexcept override {
return nullptr;
}

private:
};
// ret name arg


std::uint32_t size(const struct clap_input_events* list) {
return 0;
}

template <marvin::FloatType SampleType, size_t NumChannels, size_t BufferSize> void testPlugin() {
using namespace marvin::literals;
auto host = std::make_unique<clap_host>();
GenericPlugin<SampleType> plugin{ host.get() };
plugin.activate(44100.0, BufferSize, BufferSize);
clap_audio_buffer in;
SampleType** buffer = generateImpulse<SampleType, NumChannels, BufferSize>();
if constexpr (std::same_as<float, SampleType>) {
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<mostly_harmless::Plugin<SampleType>*>(&plugin)->process(&process);
marvin::containers::BufferView<SampleType> 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<float, 1, 64>();
testPlugin<double, 1, 64>();
testPlugin<float, 2, 128>();
testPlugin<double, 2, 128>();
}
}
1 change: 1 addition & 0 deletions tests/utils/mostlyharmless_TaskThreadTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <catch2/catch_test_macros.hpp>
#include <mostly_harmless/utils/mostlyharmless_TaskThread.h>
#include <mutex>
#include <thread>
namespace mostly_harmless::testing {
TEST_CASE("Test TaskThread") {
std::mutex mutex;
Expand Down
1 change: 1 addition & 0 deletions tests/utils/mostlyharmless_TimerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <catch2/catch_test_macros.hpp>
#include <mostly_harmless/utils/mostlyharmless_Timer.h>
#include <iostream>
#include <cmath>

namespace mostly_harmless::tests {
TEST_CASE("Test Timer") {
Expand Down

0 comments on commit 4114b17

Please sign in to comment.