Initial release
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/utility/test/ringbuffertest.cpp
|
||||
// Created by : Steinberg, 03/2018
|
||||
// Description : Test ringbuffer
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/utility/ringbuffer.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
#include "pluginterfaces/base/fstrdefs.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static ModuleInitializer InitRingbufferTests ([] () {
|
||||
registerTest ("RingBuffer", STR ("push until full"), [] (ITestResult*) {
|
||||
OneReaderOneWriter::RingBuffer<uint32> rb (4);
|
||||
if (!rb.push (0))
|
||||
return false;
|
||||
if (!rb.push (1))
|
||||
return false;
|
||||
if (!rb.push (2))
|
||||
return false;
|
||||
if (!rb.push (3))
|
||||
return false;
|
||||
if (!rb.push (4))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
registerTest ("RingBuffer", STR ("pop until empty"), [] (ITestResult*) {
|
||||
OneReaderOneWriter::RingBuffer<uint32> rb (4);
|
||||
if (!rb.push (0))
|
||||
return false;
|
||||
if (!rb.push (1))
|
||||
return false;
|
||||
if (!rb.push (2))
|
||||
return false;
|
||||
if (!rb.push (3))
|
||||
return false;
|
||||
|
||||
uint32 value;
|
||||
if (!rb.pop (value) || value != 0)
|
||||
return false;
|
||||
if (!rb.pop (value) || value != 1)
|
||||
return false;
|
||||
if (!rb.pop (value) || value != 2)
|
||||
return false;
|
||||
if (!rb.pop (value) || value != 3)
|
||||
return false;
|
||||
if (!rb.pop (value))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
registerTest ("RingBuffer", STR ("roundtrip"), [] (ITestResult*) {
|
||||
OneReaderOneWriter::RingBuffer<uint32> rb (2);
|
||||
uint32 value;
|
||||
|
||||
for (auto i = 0u; i < rb.size () * 2; ++i)
|
||||
{
|
||||
if (!rb.push (i))
|
||||
return false;
|
||||
if (!rb.pop (value) || value != i)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
registerTest ("RingBuffer", STR ("push multiple"), [] (ITestResult*) {
|
||||
OneReaderOneWriter::RingBuffer<uint32> rb (3);
|
||||
|
||||
if (!rb.push ({32u, 64u}))
|
||||
return false;
|
||||
if (rb.push ({32u, 64u}))
|
||||
return false;
|
||||
uint32 value;
|
||||
if (!rb.pop (value))
|
||||
return false;
|
||||
if (!rb.pop (value))
|
||||
return false;
|
||||
if (rb.pop (value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,150 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/utility/test/rtstatetransfertest.cpp
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : Realtime State Transfer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/utility/rttransfer.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace {
|
||||
//------------------------------------------------------------------------
|
||||
using ParameterVector = std::vector<std::pair<ParamID, ParamValue>>;
|
||||
using RTTransfer = RTTransferT<ParameterVector>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct RaceConditionTestObject
|
||||
{
|
||||
static std::atomic<uint32> numDeletes;
|
||||
//------------------------------------------------------------------------
|
||||
struct MyDeleter
|
||||
{
|
||||
void operator () (double* v) const noexcept
|
||||
{
|
||||
delete v;
|
||||
++numDeletes;
|
||||
}
|
||||
};
|
||||
|
||||
RTTransferT<double, MyDeleter> transfer;
|
||||
std::thread thread;
|
||||
std::mutex m1;
|
||||
std::mutex m2;
|
||||
std::condition_variable c1;
|
||||
|
||||
bool test (ITestResult* result)
|
||||
{
|
||||
numDeletes = 0;
|
||||
{
|
||||
auto obj1 = std::unique_ptr<double, MyDeleter> (new double (0.5));
|
||||
auto obj2 = std::unique_ptr<double, MyDeleter> (new double (1.));
|
||||
transfer.transferObject_ui (std::move (obj1));
|
||||
m2.lock ();
|
||||
thread = std::thread ([&] () {
|
||||
transfer.accessTransferObject_rt ([&] (const double&) {
|
||||
c1.notify_all ();
|
||||
m2.lock ();
|
||||
m2.unlock ();
|
||||
});
|
||||
transfer.accessTransferObject_rt ([&] (const double&) {});
|
||||
});
|
||||
std::unique_lock<std::mutex> lm1 (m1);
|
||||
c1.wait (lm1);
|
||||
transfer.transferObject_ui (std::move (obj2));
|
||||
m2.unlock ();
|
||||
|
||||
thread.join ();
|
||||
transfer.clear_ui ();
|
||||
}
|
||||
return numDeletes == 2;
|
||||
}
|
||||
};
|
||||
std::atomic<uint32> RaceConditionTestObject::numDeletes {0};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static std::atomic<uint32> CustomDeleterCallCount;
|
||||
struct CustomDeleter
|
||||
{
|
||||
template <typename T>
|
||||
void operator () (T* v) const noexcept
|
||||
{
|
||||
delete v;
|
||||
++CustomDeleterCallCount;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ModuleInitializer InitStateTransferTests ([] () {
|
||||
registerTest ("RTTransfer", STR ("Simple Transfer"), [] (ITestResult*) {
|
||||
RTTransfer helper;
|
||||
auto list = std::make_unique<ParameterVector> ();
|
||||
list->emplace_back (std::make_pair (0, 1.));
|
||||
helper.transferObject_ui (std::move (list));
|
||||
bool success = false;
|
||||
constexpr double one = 1.;
|
||||
helper.accessTransferObject_rt ([&success, one = one] (const auto& list) {
|
||||
if (list.size () == 1)
|
||||
{
|
||||
if (list[0].first == 0)
|
||||
{
|
||||
if (Test::equal (one, list[0].second))
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
list = std::make_unique<ParameterVector> ();
|
||||
list->emplace_back (std::make_pair (0, 1.));
|
||||
helper.transferObject_ui (std::move (list));
|
||||
helper.accessTransferObject_rt ([] (auto&) {});
|
||||
list = std::make_unique<ParameterVector> ();
|
||||
list->emplace_back (std::make_pair (0, 1.));
|
||||
helper.transferObject_ui (std::move (list));
|
||||
helper.accessTransferObject_rt ([] (auto&) {});
|
||||
return success;
|
||||
});
|
||||
registerTest ("RTTransfer", STR ("CheckRaceCondition"), [] (ITestResult* r) {
|
||||
RaceConditionTestObject obj;
|
||||
return obj.test (r);
|
||||
});
|
||||
registerTest ("RTTransfer", STR ("Custom Deleter"), [] (ITestResult* result) {
|
||||
CustomDeleterCallCount = 0;
|
||||
RTTransferT<double, CustomDeleter> transfer;
|
||||
auto obj1 = std::unique_ptr<double, CustomDeleter> (new double (1.));
|
||||
transfer.transferObject_ui (std::move (obj1));
|
||||
if (CustomDeleterCallCount != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
transfer.clear_ui ();
|
||||
return CustomDeleterCallCount == 1;
|
||||
});
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Anonymous
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/source/vst/utility/test/sampleaccuratetest.cpp
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : Tests for Sample Accurate Parameter Changes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/hosting/parameterchanges.h"
|
||||
#include "public.sdk/source/vst/utility/sampleaccurate.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static ModuleInitializer InitTests ([] () {
|
||||
registerTest ("SampleAccurate::Parameter", STR ("Single Change"), [] (ITestResult* result) {
|
||||
ParamID pid = 1;
|
||||
SampleAccurate::Parameter param (pid, 0.);
|
||||
ParameterValueQueue queue (pid);
|
||||
int32 index = 0;
|
||||
queue.addPoint (0, 0., index);
|
||||
queue.addPoint (100, 1., index);
|
||||
|
||||
param.beginChanges (&queue);
|
||||
param.advance (50);
|
||||
if (Test::notEqual (param.getValue (), 0.5))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.advance (50);
|
||||
if (Test::notEqual (param.getValue (), 1.))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.endChanges ();
|
||||
|
||||
return true;
|
||||
});
|
||||
registerTest ("SampleAccurate::Parameter", STR ("Multi Change"), [] (ITestResult* result) {
|
||||
ParamID pid = 1;
|
||||
SampleAccurate::Parameter param (pid, 0.);
|
||||
ParameterValueQueue queue (pid);
|
||||
int32 index = 0;
|
||||
queue.addPoint (0, 0., index);
|
||||
queue.addPoint (100, 1., index);
|
||||
queue.addPoint (120, 0., index);
|
||||
|
||||
param.beginChanges (&queue);
|
||||
param.advance (50);
|
||||
if (Test::notEqual (param.getValue (), 0.5))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.advance (50);
|
||||
if (Test::notEqual (param.getValue (), 1.))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.advance (20);
|
||||
if (Test::notEqual (param.getValue (), 0.))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.endChanges ();
|
||||
|
||||
return true;
|
||||
});
|
||||
registerTest ("SampleAccurate::Parameter", STR ("Edge"), [] (ITestResult* result) {
|
||||
ParamID pid = 1;
|
||||
SampleAccurate::Parameter param (pid, 0.);
|
||||
ParameterValueQueue queue (pid);
|
||||
int32 index = 0;
|
||||
queue.addPoint (0, 0., index);
|
||||
queue.addPoint (1, 1., index);
|
||||
queue.addPoint (2, 0., index);
|
||||
|
||||
param.beginChanges (&queue);
|
||||
param.advance (2);
|
||||
if (Test::notEqual (param.getValue (), 0.))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.endChanges ();
|
||||
|
||||
return true;
|
||||
});
|
||||
registerTest ("SampleAccurate::Parameter", STR ("Flush"), [] (ITestResult* result) {
|
||||
ParamID pid = 1;
|
||||
SampleAccurate::Parameter param (pid, 0.);
|
||||
ParameterValueQueue queue (pid);
|
||||
int32 index = 0;
|
||||
queue.addPoint (0, 0., index);
|
||||
queue.addPoint (256, 1., index);
|
||||
queue.addPoint (258, 0.5, index);
|
||||
|
||||
param.beginChanges (&queue);
|
||||
param.flushChanges ();
|
||||
if (Test::notEqual (param.getValue (), 0.5))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
param.endChanges ();
|
||||
|
||||
return true;
|
||||
});
|
||||
registerTest ("SampleAccurate::Parameter", STR ("Callback"), [] (ITestResult* result) {
|
||||
ParamID pid = 1;
|
||||
SampleAccurate::Parameter param (pid, 0.);
|
||||
ParameterValueQueue queue (pid);
|
||||
int32 index = 0;
|
||||
queue.addPoint (0, 0., index);
|
||||
queue.addPoint (128, 0., index);
|
||||
queue.addPoint (256, 1., index);
|
||||
queue.addPoint (258, 0.5, index);
|
||||
|
||||
param.beginChanges (&queue);
|
||||
bool failure = false;
|
||||
param.advance (128, [&result, &failure] (auto) {
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
failure = true;
|
||||
});
|
||||
if (failure)
|
||||
return false;
|
||||
constexpr auto half = 0.5;
|
||||
param.advance (514, [&result, &failure, half = half] (auto value) {
|
||||
if (Test::notEqual (value, half))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
failure = true;
|
||||
}
|
||||
else
|
||||
failure = false;
|
||||
});
|
||||
if (failure)
|
||||
return false;
|
||||
|
||||
param.endChanges ();
|
||||
|
||||
return true;
|
||||
});
|
||||
registerTest ("SampleAccurate::Parameter", STR ("NoChanges"), [] (ITestResult* result) {
|
||||
ParamID pid = 1;
|
||||
SampleAccurate::Parameter param (pid, 1.);
|
||||
param.endChanges ();
|
||||
|
||||
if (Test::notEqual (param.getValue (), 1.))
|
||||
{
|
||||
result->addErrorMessage (STR ("Unexpected Value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/utility/test/versionparsertest.cpp
|
||||
// Created by : Steinberg, 12/2019
|
||||
// Description : Test version parser
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
#include "public.sdk/source/vst/utility/versionparser.h"
|
||||
#include "pluginterfaces/base/fstrdefs.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static ModuleInitializer InitVersionParserTests ([] () {
|
||||
registerTest ("VersionParser", STR ("Parsing 'SDK 3.7'"), [] (ITestResult* testResult) {
|
||||
auto version = VST3::Version::parse ("SDK 3.7");
|
||||
if (version.getMajor () != 3 || version.getMinor () != 7 || version.getSub () != 0 ||
|
||||
version.getBuildnumber () != 0)
|
||||
{
|
||||
testResult->addErrorMessage (STR ("Parsing 'SDK 3.7' failed"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
registerTest ("VersionParser", STR ("Parsing 'SDK 3.7.1.38'"), [] (ITestResult* testResult) {
|
||||
auto version = VST3::Version::parse ("3.7.1.38");
|
||||
if (version.getMajor () != 3 || version.getMinor () != 7 || version.getSub () != 1 ||
|
||||
version.getBuildnumber () != 38)
|
||||
{
|
||||
testResult->addErrorMessage (STR ("Parsing '3.7.1.38' failed"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
registerTest ("VersionParser", STR ("Parsing 'SDK 3.7 Prerelease'"),
|
||||
[] (ITestResult* testResult) {
|
||||
auto version = VST3::Version::parse ("SDK 3.7 Prerelease");
|
||||
if (version.getMajor () != 3 || version.getMinor () != 7 ||
|
||||
version.getSub () != 0 || version.getBuildnumber () != 0)
|
||||
{
|
||||
testResult->addErrorMessage (STR ("Parsing 'SDK 3.7 Prerelease' failed"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
registerTest ("VersionParser", STR ("Parsing 'SDK 3.7-99'"), [] (ITestResult* testResult) {
|
||||
auto version = VST3::Version::parse ("SDK 3.7-99");
|
||||
if (version.getMajor () != 3 || version.getMinor () != 7 || version.getSub () != 0 ||
|
||||
version.getBuildnumber () != 0)
|
||||
{
|
||||
testResult->addErrorMessage (STR ("Parsing 'SDK 3.7-99' failed"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
registerTest ("VersionParser", STR ("Parsing 'No version at all'"),
|
||||
[] (ITestResult* testResult) {
|
||||
auto version = VST3::Version::parse ("No version at all");
|
||||
if (version.getMajor () != 0 || version.getMinor () != 0 ||
|
||||
version.getSub () != 0 || version.getBuildnumber () != 0)
|
||||
{
|
||||
testResult->addErrorMessage (STR ("Parsing 'No version at all' failed"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
Reference in New Issue
Block a user