Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,91 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/busactivation.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/bus/busactivation.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// BusActivationTest
//------------------------------------------------------------------------
BusActivationTest::BusActivationTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API BusActivationTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
int32 numTotalBusses = 0;
int32 numFailedActivations = 0;
for (MediaType type = kAudio; type < kNumMediaTypes; type++)
{
int32 numInputs = vstPlug->getBusCount (type, kInput);
int32 numOutputs = vstPlug->getBusCount (type, kOutput);
numTotalBusses += (numInputs + numOutputs);
for (int32 i = 0; i < numInputs + numOutputs; ++i)
{
BusDirection busDirection = i < numInputs ? kInput : kOutput;
int32 busIndex = busDirection == kInput ? i : i - numInputs;
BusInfo busInfo = {};
if (vstPlug->getBusInfo (type, busDirection, busIndex, busInfo) != kResultTrue)
{
addErrorMessage (testResult, STR ("IComponent::getBusInfo (..) failed."));
return false;
}
addMessage (testResult, printf (" Bus Activation: %s %s Bus (%d) (%s)",
busDirection == kInput ? "Input" : "Output",
type == kAudio ? "Audio" : "Event", busIndex,
busInfo.busType == kMain ? "kMain" : "kAux"));
if ((busInfo.flags & BusInfo::kDefaultActive) == false)
{
if (vstPlug->activateBus (type, busDirection, busIndex, true) != kResultOk)
numFailedActivations++;
if (vstPlug->activateBus (type, busDirection, busIndex, false) != kResultOk)
numFailedActivations++;
}
else if ((busInfo.flags & BusInfo::kDefaultActive) == true)
{
if (vstPlug->activateBus (type, busDirection, busIndex, false) != kResultOk)
numFailedActivations++;
if (vstPlug->activateBus (type, busDirection, busIndex, true) != kResultOk)
numFailedActivations++;
}
}
}
if (numFailedActivations > 0)
addErrorMessage (testResult, STR ("Bus activation failed."));
return (numFailedActivations == 0);
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/busactivation.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Bus Activation.
* \ingroup TestClass
*/
class BusActivationTest : public TestBase
{
public:
BusActivationTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Bus Activation")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,100 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/busconsistency.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/bus/busconsistency.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// BusConsistencyTest
//------------------------------------------------------------------------
BusConsistencyTest::BusConsistencyTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API BusConsistencyTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
bool failed = false;
int32 numFalseDescQueries = 0;
for (MediaType mediaType = kAudio; mediaType < kNumMediaTypes; mediaType++)
{
for (BusDirection dir = kInput; dir <= kOutput; dir++)
{
int32 numBusses = vstPlug->getBusCount (mediaType, dir);
if (numBusses > 0)
{
auto* busArray = new BusInfo[numBusses];
if (busArray)
{
// get all bus descriptions and save them in an array
int32 busIndex;
for (busIndex = 0; busIndex < numBusses; busIndex++)
{
memset (&busArray[busIndex], 0, sizeof (BusInfo));
vstPlug->getBusInfo (mediaType, dir, busIndex, busArray[busIndex]);
}
// test by getting descriptions randomly and comparing with saved ones
int32 randIndex = 0;
BusInfo info = {};
for (busIndex = 0;
busIndex <= numBusses * TestDefaults::instance ().numIterations;
busIndex++)
{
randIndex = rand () % (numBusses);
memset (&info, 0, sizeof (BusInfo));
/*tresult result =*/vstPlug->getBusInfo (mediaType, dir, randIndex, info);
if (memcmp ((void*)&busArray[randIndex], (void*)&info, sizeof (BusInfo)) !=
TestDefaults::instance ().buffersAreEqual)
{
failed |= true;
numFalseDescQueries++;
}
}
delete[] busArray;
}
}
}
}
if (numFalseDescQueries > 0)
{
addErrorMessage (
testResult,
printf (
"The component returned %i inconsistent buses! (getBusInfo () returns sometime different info for the same bus!",
numFalseDescQueries));
}
return failed == false;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/busconsistency.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Bus Consistency.
* \ingroup TestClass
*/
class BusConsistencyTest : public TestBase
{
public:
BusConsistencyTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Bus Consistency")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,83 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/businvalidindex.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/bus/businvalidindex.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// BusInvalidIndexTest
//------------------------------------------------------------------------
BusInvalidIndexTest::BusInvalidIndexTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API BusInvalidIndexTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
bool failed = false;
int32 numInvalidDesc = 0;
for (MediaType mediaType = kAudio; mediaType < kNumMediaTypes; mediaType++)
{
int32 numBusses =
vstPlug->getBusCount (mediaType, kInput) + vstPlug->getBusCount (mediaType, kOutput);
for (BusDirection dir = kInput; dir <= kOutput; dir++)
{
BusInfo descBefore = {};
BusInfo descAfter = {};
int32 randIndex = 0;
// todo: rand with negative numbers
for (int32 i = 0; i <= numBusses * TestDefaults::instance ().numIterations; ++i)
{
randIndex = rand ();
if (0 > randIndex || randIndex > numBusses)
{
/*tresult result =*/vstPlug->getBusInfo (mediaType, dir, randIndex, descAfter);
if (memcmp ((void*)&descBefore, (void*)&descAfter, sizeof (BusInfo)) != 0)
{
failed |= true;
numInvalidDesc++;
}
}
}
}
}
if (numInvalidDesc > 0)
{
addErrorMessage (testResult,
printf ("The component returned %i buses queried with an invalid index!",
numInvalidDesc));
}
return failed == false;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/businvalidindex.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Bus Invalid Index.
* \ingroup TestClass
*/
class BusInvalidIndexTest : public TestBase
{
public:
BusInvalidIndexTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Bus Invalid Index")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,86 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/checkaudiobusarrangement.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/bus/checkaudiobusarrangement.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// CheckAudioBusArrangementTest
//------------------------------------------------------------------------
CheckAudioBusArrangementTest::CheckAudioBusArrangementTest (ITestPlugProvider* plugProvider)
: TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool CheckAudioBusArrangementTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
int32 numInputs = vstPlug->getBusCount (kAudio, kInput);
int32 numOutputs = vstPlug->getBusCount (kAudio, kOutput);
int32 arrangementMismatchs = 0;
if (auto audioEffect = U::cast<IAudioProcessor> (vstPlug))
{
for (int32 i = 0; i < numInputs + numOutputs; ++i)
{
BusDirection dir = i < numInputs ? kInput : kOutput;
int32 busIndex = dir == kInput ? i : i - numInputs;
addMessage (testResult, printf (" Check %s Audio Bus Arrangement (%d)",
dir == kInput ? "Input" : "Output", busIndex));
BusInfo busInfo = {};
if (vstPlug->getBusInfo (kAudio, dir, busIndex, busInfo) == kResultTrue)
{
SpeakerArrangement arrangement;
if (audioEffect->getBusArrangement (dir, busIndex, arrangement) == kResultTrue)
{
if (busInfo.channelCount != SpeakerArr::getChannelCount (arrangement))
{
arrangementMismatchs++;
addErrorMessage (testResult, STR ("channelCount is inconsistent!"));
}
}
else
{
addErrorMessage (testResult,
STR ("IAudioProcessor::getBusArrangement (..) failed!"));
return false;
}
}
else
{
addErrorMessage (testResult, STR ("IComponent::getBusInfo (..) failed!"));
return false;
}
}
}
return (arrangementMismatchs == 0);
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/checkaudiobusarrangement.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Check Audio Bus Arrangement.
* \ingroup TestClass
*/
class CheckAudioBusArrangementTest : public TestBase
{
public:
CheckAudioBusArrangementTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Check Audio Bus Arrangement")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,89 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/scanbusses.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/bus/scanbusses.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ScanBussesTest
//------------------------------------------------------------------------
ScanBussesTest::ScanBussesTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API ScanBussesTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
int32 numBusses = 0;
for (MediaType mediaType = kAudio; mediaType < kNumMediaTypes; mediaType++)
{
int32 numInputs = vstPlug->getBusCount (mediaType, kInput);
int32 numOutputs = vstPlug->getBusCount (mediaType, kOutput);
numBusses += (numInputs + numOutputs);
if ((mediaType == (kNumMediaTypes - 1)) && (numBusses == 0))
{
addErrorMessage (testResult, STR ("This component does not export any buses!!!"));
return false;
}
addMessage (testResult,
printf ("=> %s Buses: [%d In(s) => %d Out(s)]",
mediaType == kAudio ? "Audio" : "Event", numInputs, numOutputs));
for (int32 i = 0; i < numInputs + numOutputs; ++i)
{
BusDirection busDirection = i < numInputs ? kInput : kOutput;
int32 busIndex = busDirection == kInput ? i : i - numInputs;
BusInfo busInfo = {};
if (vstPlug->getBusInfo (mediaType, busDirection, busIndex, busInfo) == kResultTrue)
{
auto busName = StringConvert::convert (busInfo.name);
if (busName.empty ())
{
addErrorMessage (testResult, printf ("Bus %d has no name!!!", busIndex));
return false;
}
addMessage (
testResult,
printf (" %s[%d]: \"%s\" (%s-%s) ", busDirection == kInput ? "In " : "Out",
busIndex, busName.data (), busInfo.busType == kMain ? "Main" : "Aux",
busInfo.kDefaultActive ? "Default Active" : "Default Inactive"));
}
else
return false;
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/scanbusses.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Scan Buses.
* \ingroup TestClass
*/
class ScanBussesTest : public TestBase
{
public:
ScanBussesTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Scan Buses")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,139 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/sidechainarrangement.cpp
// Created by : Steinberg, 11/2019
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/bus/sidechainarrangement.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// SideChainArrangementTest
//------------------------------------------------------------------------
SideChainArrangementTest::SideChainArrangementTest (ITestPlugProvider* plugProvider)
: TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API SideChainArrangementTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
bool failed = false;
auto audioEffect = U::cast<IAudioProcessor> (vstPlug);
if (!audioEffect)
return failed;
// get the side chain arrangements
// set Main/first Input and output to Mono
// get the current arrangement and compare
// check if Audio sideChain is supported
bool hasInputSideChain = false;
int32 numInBusses = vstPlug->getBusCount (kAudio, kInput);
if (numInBusses < 2)
return true;
for (int32 busIndex = 0; busIndex < numInBusses; busIndex++)
{
BusInfo info;
if (vstPlug->getBusInfo (kAudio, kInput, busIndex, info) != kResultTrue)
{
addErrorMessage (testResult, STR ("IComponent::getBusInfo (..) failed."));
continue;
}
if (info.busType == kAux)
hasInputSideChain = true;
}
if (!hasInputSideChain)
return true;
auto* inputArrArray = new SpeakerArrangement[numInBusses];
for (int32 busIndex = 0; busIndex < numInBusses; busIndex++)
{
if (audioEffect->getBusArrangement (kInput, busIndex, inputArrArray[busIndex]) !=
kResultTrue)
{
addErrorMessage (testResult, STR ("IComponent::getBusArrangement (..) failed."));
}
}
int32 numOutBusses = vstPlug->getBusCount (kAudio, kOutput);
SpeakerArrangement* outputArrArray = nullptr;
if (numOutBusses > 0)
{
outputArrArray = new SpeakerArrangement[numOutBusses];
for (int32 busIndex = 0; busIndex < numOutBusses; busIndex++)
{
if (audioEffect->getBusArrangement (kOutput, busIndex, outputArrArray[busIndex]) !=
kResultTrue)
{
addErrorMessage (testResult, STR ("IComponent::getBusArrangement (..) failed."));
}
}
outputArrArray[0] = kSpeakerM;
}
inputArrArray[0] = kSpeakerM;
if (audioEffect->setBusArrangements (inputArrArray, numInBusses, outputArrArray,
numOutBusses) == kResultTrue)
{
for (int32 busIndex = 0; busIndex < numInBusses; busIndex++)
{
SpeakerArrangement tmp;
if (audioEffect->getBusArrangement (kInput, busIndex, tmp) == kResultTrue)
{
if (tmp != inputArrArray[busIndex])
{
addErrorMessage (
testResult,
printf (
"Input %d: setBusArrangements was returning kResultTrue but getBusArrangement returns different arrangement!",
busIndex));
failed = true;
}
}
}
for (int32 busIndex = 0; busIndex < numOutBusses; busIndex++)
{
SpeakerArrangement tmp;
if (audioEffect->getBusArrangement (kOutput, busIndex, tmp) != kResultTrue)
{
if (tmp != outputArrArray[busIndex])
{
addErrorMessage (
testResult,
printf (
"Output %d: setBusArrangements was returning kResultTrue but getBusArrangement returns different arrangement!",
busIndex));
failed = true;
}
}
}
}
return failed == false;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/bus/sidechainarrangement.h
// Created by : Steinberg, 11/2020
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test SideChain Arrangement.
* \ingroup TestClass
*/
class SideChainArrangementTest : public TestBase
{
public:
SideChainArrangementTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("SideChain Arrangement")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/editorclasses.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/editorclasses.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// EditorClassesTest
//------------------------------------------------------------------------
EditorClassesTest::EditorClassesTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API EditorClassesTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
// no controller is allowed...
if (FUnknownPtr<IEditController> (vstPlug).getInterface ())
{
addMessage (testResult, STR ("Processor and edit controller united."));
return true;
}
TUID controllerClassTUID;
if (vstPlug->getControllerClassId (controllerClassTUID) != kResultOk)
{
addMessage (testResult,
STR ("This component does not export an edit controller class ID!!!"));
return true;
}
FUID controllerClassUID;
controllerClassUID = FUID::fromTUID (controllerClassTUID);
if (controllerClassUID.isValid () == false)
{
addErrorMessage (testResult, STR ("The edit controller class has no valid UID!!!"));
return false;
}
addMessage (testResult, STR ("This component has an edit controller class"));
char8 cidString[50];
controllerClassUID.toRegistryString (cidString);
addMessage (testResult, printf (" Controller CID: %s", cidString));
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/editorclasses.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Scan Editor Classes.
* \ingroup TestClass
*/
class EditorClassesTest : public TestBase
{
public:
EditorClassesTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Scan Editor Classes")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,66 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/midilearn.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/midilearn.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstmidicontrollers.h"
#include "pluginterfaces/vst/ivstmidilearn.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// MidiLearnTest
//------------------------------------------------------------------------
MidiLearnTest::MidiLearnTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API MidiLearnTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (!controller)
{
addMessage (testResult, STR ("No Edit Controller supplied!"));
return true;
}
auto midiLearn = U::cast<IMidiLearn> (controller);
if (!midiLearn)
{
addMessage (testResult, STR ("No MIDI Learn interface supplied!"));
return true;
}
if (midiLearn->onLiveMIDIControllerInput (0, 0, ControllerNumbers::kCtrlPan) != kResultTrue)
addMessage (testResult, STR ("onLiveMIDIControllerInput do not return kResultTrue!"));
if (midiLearn->onLiveMIDIControllerInput (0, 0, ControllerNumbers::kCtrlVibratoDelay) !=
kResultTrue)
addMessage (testResult, STR ("onLiveMIDIControllerInput do not return kResultTrue!"));
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/midilearn.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test MIDI Learn.
* \ingroup TestClass
*/
class MidiLearnTest : public TestBase
{
public:
MidiLearnTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("MIDI Learn")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,140 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/midimapping.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/midimapping.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstmidicontrollers.h"
#include <unordered_set>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// MidiMappingTest
//------------------------------------------------------------------------
MidiMappingTest::MidiMappingTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API MidiMappingTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (!controller)
{
addMessage (testResult, STR ("No Edit Controller supplied!"));
return true;
}
auto midiMapping = U::cast<IMidiMapping> (controller);
if (!midiMapping)
{
addMessage (testResult, STR ("No MIDI Mapping interface supplied!"));
return true;
}
int32 numParameters = controller->getParameterCount ();
int32 eventBusCount = vstPlug->getBusCount (kEvent, kInput);
bool interruptProcess = false;
std::unordered_set<ParamID> parameterIds;
for (int32 i = 0; i < numParameters; ++i)
{
ParameterInfo parameterInfo;
if (controller->getParameterInfo (i, parameterInfo) == kResultTrue)
parameterIds.insert (parameterInfo.id);
}
for (int32 bus = 0; bus < eventBusCount + 1; bus++)
{
if (interruptProcess)
break;
BusInfo info;
if (vstPlug->getBusInfo (kEvent, kInput, bus, info) == kResultTrue)
{
if (bus >= eventBusCount)
{
addMessage (testResult, STR ("getBusInfo supplied for an unknown event bus"));
break;
}
}
else
break;
for (int16 channel = 0; channel < info.channelCount; channel++)
{
if (interruptProcess)
break;
int32 foundCount = 0;
// test with the cc outside the valid range too (>=kCountCtrlNumber)
for (CtrlNumber cc = 0; cc < kCountCtrlNumber + 1; cc++)
{
ParamID tag;
if (midiMapping->getMidiControllerAssignment (bus, channel, cc, tag) == kResultTrue)
{
if (bus >= eventBusCount)
{
addMessage (testResult,
STR ("MIDI Mapping supplied for an unknown event bus"));
interruptProcess = true;
break;
}
if (cc >= kCountCtrlNumber)
{
addMessage (
testResult,
STR (
"MIDI Mapping supplied for a wrong ControllerNumbers value (bigger than the max)"));
break;
}
if (parameterIds.find (tag) == parameterIds.end ())
{
addErrorMessage (
testResult,
printf ("Unknown ParamID [%d] returned for MIDI Mapping", tag));
return false;
}
foundCount++;
}
else
{
if (bus >= eventBusCount)
interruptProcess = true;
}
}
if (foundCount == 0 && (bus < eventBusCount))
{
addMessage (
testResult,
printf (
"MIDI Mapping getMidiControllerAssignment (%d, %d) : no assignment available!",
bus, channel));
}
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/midimapping.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test MIDI Mapping.
* \ingroup TestClass
*/
class MidiMappingTest : public TestBase
{
public:
//------------------------------------------------------------------------
MidiMappingTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("MIDI Mapping")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,134 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/parameterfunctionname.cpp
// Created by : Steinberg, 04/2020
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/parameterfunctionname.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstparameterfunctionname.h"
#include "pluginterfaces/vst/ivstunits.h"
#include <unordered_map>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ParameterFunctionNameTest
//------------------------------------------------------------------------
ParameterFunctionNameTest::ParameterFunctionNameTest (ITestPlugProvider* plugProvider)
: TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API ParameterFunctionNameTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (!controller)
{
addMessage (testResult, STR ("No Edit Controller supplied!"));
return true;
}
auto iParameterFunctionName = U::cast<IParameterFunctionName> (controller);
if (!iParameterFunctionName)
{
addMessage (testResult, STR ("No IParameterFunctionName support."));
return true;
}
addMessage (testResult, STR ("IParameterFunctionName supported."));
int32 numParameters = controller->getParameterCount ();
if (numParameters <= 0)
{
addMessage (testResult, STR ("This component does not export any parameters!"));
return true;
}
// used for ID check
std::unordered_map<int32, int32> paramIds;
for (int32 i = 0; i < numParameters; ++i)
{
ParameterInfo paramInfo = {};
tresult result = controller->getParameterInfo (i, paramInfo);
if (result != kResultOk)
{
addErrorMessage (testResult, printf ("Parameter %03d: is missing!!!", i));
return false;
}
int32 paramId = paramInfo.id;
if (paramId < 0)
{
addErrorMessage (testResult,
printf ("Parameter %03d (id=%d): Invalid Id!!!", i, paramId));
return false;
}
auto search = paramIds.find (paramId);
if (search != paramIds.end ())
{
addErrorMessage (testResult,
printf ("Parameter %03d (id=%d): ID already used by idx=%03d!!!", i,
paramId, search->second));
return false;
}
else
paramIds[paramId] = i;
} // end for each parameter
auto iUnitInfo2 = U::cast<IUnitInfo> (controller);
const CString arrayFunctionName[] = {FunctionNameType::kCompGainReduction,
FunctionNameType::kCompGainReductionMax,
FunctionNameType::kCompGainReductionPeakHold,
FunctionNameType::kCompResetGainReductionMax,
FunctionNameType::kLowLatencyMode,
FunctionNameType::kRandomize,
FunctionNameType::kDryWetMix};
ParamID paramID;
for (auto item : arrayFunctionName)
{
if (iParameterFunctionName->getParameterIDFromFunctionName (kRootUnitId, item, paramID) ==
kResultTrue)
{
addMessage (testResult,
printf ("FunctionName %s supported => paramID %d", item, paramID));
auto search = paramIds.find (paramID);
if (search == paramIds.end ())
{
addErrorMessage (
testResult,
printf ("Parameter (id=%d) for FunctionName %s: not Found!!!", paramID, item));
return false;
}
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/ParameterFunctionNameTest.h
// Created by : Steinberg, 04/2020
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Parameter Function Name.
\ingroup TestClass */
//------------------------------------------------------------------------
class ParameterFunctionNameTest : public TestBase
{
public:
//------------------------------------------------------------------------
ParameterFunctionNameTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Parameter Function Name")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,83 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/plugcompat.cpp
// Created by : Steinberg, 03/2022
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/plugcompat.h"
#include "public.sdk/source/vst/moduleinfo/moduleinfoparser.h"
#include "pluginterfaces/base/funknownimpl.h"
#include <string>
//------------------------------------------------------------------------
namespace Steinberg {
//------------------------------------------------------------------------
namespace {
//------------------------------------------------------------------------
struct StringStream : U::ImplementsNonDestroyable<U::Directly<IBStream>>
{
std::string str;
tresult PLUGIN_API read (void*, int32, int32*) override { return kNotImplemented; }
tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) override
{
str.append (static_cast<char*> (buffer), numBytes);
if (numBytesWritten)
*numBytesWritten = numBytes;
return kResultTrue;
}
tresult PLUGIN_API seek (int64, int32, int64*) override { return kNotImplemented; }
tresult PLUGIN_API tell (int64*) override { return kNotImplemented; }
};
//------------------------------------------------------------------------
} // anonymous
//------------------------------------------------------------------------
bool checkPluginCompatibility (VST3::Hosting::Module::Ptr& module,
IPtr<IPluginCompatibility> compat, std::ostream* errorStream)
{
bool failure = false;
if (auto moduleInfoPath = VST3::Hosting::Module::getModuleInfoPath (module->getPath ()))
{
if (errorStream)
{
*errorStream
<< "Warning: The module contains a moduleinfo.json file and the module factory exports a IPluginCompatibility class. The moduleinfo.json one is preferred.\n";
}
}
StringStream strStream;
if (compat->getCompatibilityJSON (&strStream) != kResultTrue)
{
if (errorStream)
{
*errorStream
<< "Error: Call to IPluginCompatiblity::getCompatibilityJSON (IBStream*) failed\n";
}
failure = true;
}
else if (auto result = ModuleInfoLib::parseCompatibilityJson (strStream.str, errorStream))
{
// TODO: Check that the "New" classes are part of the Module;
}
else
{
failure = true;
}
return !failure;
}
//------------------------------------------------------------------------
} // Steinberg
@@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/plugcompat.h
// Created by : Steinberg, 03/2022
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/hosting/module.h"
#include "pluginterfaces/base/iplugincompatibility.h"
#include <iosfwd>
//------------------------------------------------------------------------
namespace Steinberg {
//------------------------------------------------------------------------
bool checkPluginCompatibility (VST3::Hosting::Module::Ptr& module,
IPtr<IPluginCompatibility> compat, std::ostream* errorStream);
//------------------------------------------------------------------------
} // Steinberg
@@ -0,0 +1,364 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/scanparameters.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/scanparameters.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstunits.h"
#include <algorithm>
#include <map>
#include <unordered_map>
#include <vector>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ScanParametersTest
//------------------------------------------------------------------------
ScanParametersTest::ScanParametersTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API ScanParametersTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (!controller)
{
addMessage (testResult, STR ("No Edit Controller supplied!"));
return true;
}
int32 numParameters = controller->getParameterCount ();
if (numParameters <= 0)
{
addMessage (testResult, STR ("This component does not export any parameters!"));
return true;
}
addMessage (testResult, printf ("This component exports %d parameter(s)", numParameters));
auto iUnitInfo2 = U::cast<IUnitInfo> (controller);
if (!iUnitInfo2 && numParameters > 20)
{
addMessage (
testResult,
STR ("Note: it could be better to use UnitInfo in order to sort Parameters (>20)."));
}
struct SUnitCount
{
int32 idx {-1};
int32 numParams {0};
std::string name;
};
std::unordered_map<int32, SUnitCount> unitIds;
// root unit
unitIds[kRootUnitId].name = "Root";
if (iUnitInfo2)
{
for (int32 ui = 0, uc = iUnitInfo2->getUnitCount (); ui < uc; ++ui)
{
UnitInfo uinfo = {};
if (iUnitInfo2->getUnitInfo (ui, uinfo) == kResultTrue)
{
// check if ID is already used by another unit
if (uinfo.id != kRootUnitId)
{
auto search = unitIds.find (uinfo.id);
if (search != unitIds.end ())
{
addErrorMessage (
testResult,
printf ("=>Unit %03d (id=%d): ID already used by idx=%03d!!!", ui,
uinfo.id, search->second.idx));
return false;
}
}
std::string unitTitle;
unitTitle = StringConvert::convert (uinfo.name);
unitIds[uinfo.id] = {ui, 0, unitTitle}; // init counter
}
else
{
addErrorMessage (testResult, printf ("IUnitInfo::getUnitInfo (%d..) failed.", ui));
return false;
}
}
}
// used for ID check
std::unordered_map<int32, int32> paramIds;
std::map<int32, std::vector<std::string>> listTitleUnitMap;
bool foundBypass = false;
for (int32 i = 0; i < numParameters; ++i)
{
ParameterInfo paramInfo = {};
tresult result = controller->getParameterInfo (i, paramInfo);
if (result != kResultOk)
{
addErrorMessage (testResult, printf ("=>Parameter %03d: is missing!!!", i));
return false;
}
int32 paramId = paramInfo.id;
if (paramId < 0)
{
addErrorMessage (testResult,
printf ("=>Parameter %03d (id=%d): Invalid Id!!!", i, paramId));
return false;
}
// check if ID is already used by another parameter
auto search = paramIds.find (paramId);
if (search != paramIds.end ())
{
addErrorMessage (testResult,
printf ("=>Parameter %03d (id=%d): ID already used by idx=%03d!!!", i,
paramId, search->second));
return false;
}
paramIds[paramId] = i;
const char8* paramType = kEmptyString8;
if (paramInfo.stepCount < 0)
{
addErrorMessage (
testResult,
printf ("=>Parameter %03d (id=%d): invalid stepcount (<0)!!!", i, paramId));
return false;
}
if (paramInfo.stepCount == 0)
paramType = "Float";
else if (paramInfo.stepCount == 1)
paramType = "Toggle";
else
paramType = "Discrete";
auto paramTitle = StringConvert::convert (paramInfo.title);
auto paramUnits = StringConvert::convert (paramInfo.units);
addMessage (
testResult,
printf (
R"( Parameter %03d (id=%d): [title="%s"] [unit="%s"] [type = %s, default = %lf, unit = %d])",
i, paramId, paramTitle.data (), paramUnits.data (), paramType,
paramInfo.defaultNormalizedValue, paramInfo.unitId));
if (paramTitle.empty ())
{
addErrorMessage (testResult,
printf ("=>Parameter %03d (id=%d): has no title!!!", i, paramId));
return false;
}
// check if the same title is present in the same unit
auto it = listTitleUnitMap.find (paramInfo.unitId);
if (it != listTitleUnitMap.end ())
{
const std::vector<std::string>& list = it->second;
auto found = std::find (list.begin (), list.end (), paramTitle);
if (found != list.end ())
{
addMessage (
testResult,
printf (
"=>Parameter %03d (id=%d): [title=\"%s\"] has the same title as another parameter in this unit = %d!",
i, paramId, paramTitle.c_str (), paramInfo.unitId));
}
}
listTitleUnitMap[paramInfo.unitId].push_back (paramTitle);
if (paramInfo.defaultNormalizedValue != -1.f &&
(paramInfo.defaultNormalizedValue < 0. || paramInfo.defaultNormalizedValue > 1.))
{
addErrorMessage (
testResult,
printf (
"=>Parameter %03d (id=%d): paramInfo.defaultNormalizedValue is not normalized!!!",
i, paramId));
return false;
}
int32 unitId = paramInfo.unitId;
if (unitId < -1)
{
addErrorMessage (
testResult,
printf ("=>Parameter %03d (id=%d): No appropriate unit ID!!!", i, paramId));
return false;
}
if (unitId >= -1)
{
auto iUnitInfo = U::cast<IUnitInfo> (controller);
if (!iUnitInfo && unitId != kRootUnitId)
{
addErrorMessage (
testResult,
printf (
"IUnitInfo interface is missing, but ParameterInfo::unitID is not %03d (kRootUnitId).",
kRootUnitId));
return false;
}
auto searchUnit = unitIds.find (unitId);
if (searchUnit != unitIds.end ())
{
unitIds[unitId].numParams++;
}
else if (unitId != kRootUnitId)
{
addErrorMessage (
testResult,
printf (
"=>Parameter %03d (id=%d) has a UnitID (%d), which isn't defined in IUnitInfo.",
i, paramId, unitId));
return false;
}
else // if (unitId == kRootUnitId)
unitIds[kRootUnitId].numParams++;
}
//---check for incompatible flags---------------------
// kCanAutomate and kIsReadOnly
if (((paramInfo.flags & ParameterInfo::kCanAutomate) != 0) &&
((paramInfo.flags & ParameterInfo::kIsReadOnly) != 0))
{
addErrorMessage (
testResult,
printf (
"=>Parameter %03d (id=%d) must not be kCanAutomate and kReadOnly at the same time.",
i, paramId));
return false;
}
// kIsProgramChange and kIsReadOnly
if (((paramInfo.flags & ParameterInfo::kIsProgramChange) != 0) &&
((paramInfo.flags & ParameterInfo::kIsReadOnly) != 0))
{
addErrorMessage (
testResult,
printf (
"=>Parameter %03d (id=%d) must not be kIsProgramChange and kReadOnly at the same time.",
i, paramId));
return false;
}
// kIsBypass only or kIsBypass and kCanAutomate only
if (((paramInfo.flags & ParameterInfo::kIsBypass) != 0) &&
!((paramInfo.flags == ParameterInfo::kIsBypass) ||
((paramInfo.flags & ParameterInfo::kCanAutomate) != 0)))
{
addErrorMessage (
testResult,
printf (
"=>Parameter %03d (id=%d) is kIsBypass and could have only kCanAutomate as other flag at the same time.",
i, paramId));
return false;
}
//---maybe wrong combination of flags-------------------
// kIsBypass but not kCanAutomate
if (paramInfo.flags == ParameterInfo::kIsBypass)
{
addMessage (testResult,
printf ("=>Parameter %03d (id=%d) is kIsBypass, but not kCanAutomate!", i,
paramId));
}
// kIsHidden and (kCanAutomate or not kIsReadOnly)
if (paramInfo.flags == ParameterInfo::kIsHidden)
{
if ((paramInfo.flags & ParameterInfo::kCanAutomate) != 0)
{
addMessage (
testResult,
printf ("=>Parameter %03d (id=%d) is kIsHidden and kCanAutomate!", i, paramId));
}
if ((paramInfo.flags & ParameterInfo::kIsReadOnly) == 0)
{
addMessage (testResult,
printf ("=>Parameter %03d (id=%d) is kIsHidden and NOT kIsReadOnly!", i,
paramId));
}
}
// kIsProgramChange and not kIsList
if (((paramInfo.flags & ParameterInfo::kIsProgramChange) != 0) &&
((paramInfo.flags & ParameterInfo::kIsList) == 0))
{
addMessage (testResult,
printf ("=>Parameter %03d (id=%d) is kIsProgramChange, but not a kIsList!",
i, paramId));
}
// kIsReadOnly and kIsWrapAround
if (((paramInfo.flags & ParameterInfo::kIsReadOnly) != 0) &&
((paramInfo.flags & ParameterInfo::kIsWrapAround) != 0))
{
addMessage (
testResult,
printf ("=>Parameter %03d (id=%d) is kIsReadOnly, no need to be kIsWrapAround too!",
i, paramId));
}
//---check bypass--------------------------------------
if ((paramInfo.flags & ParameterInfo::kIsBypass) != 0)
{
if (!foundBypass)
foundBypass = true;
else
{
addErrorMessage (
testResult,
printf ("=>Parameter %03d (id=%d): There can only be one bypass (kIsBypass).",
i, paramId));
return false;
}
}
} // end for each parameter
for (const auto& unit : unitIds)
{
if (unit.second.numParams > 128) // 128 due to MIDI CC mapped parameter
{
addMessage (
testResult,
printf (
"Note: This Unit (idx=%d, id=%d, name=\"%s\") has %d parameters: it could be better to split it in sub-units!.",
unit.second.idx, unit.first, unit.second.name.data (), unit.second.numParams));
}
}
if (foundBypass == false)
{
StringResult subCat;
plugProvider->getSubCategories (subCat);
if (subCat.get ().find ("Instrument") != std::string::npos)
addMessage (testResult, STR ("No bypass parameter found. This is an instrument."));
else
addMessage (testResult, STR ("Warning: No bypass parameter found. Is this intended ?"));
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/scanparameters.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Scan Parameters.
* \ingroup TestClass
*/
class ScanParametersTest : public TestBase
{
public:
//------------------------------------------------------------------------
ScanParametersTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Scan Parameters")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/suspendresume.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/suspendresume.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// SuspendResumeTest
//------------------------------------------------------------------------
SuspendResumeTest::SuspendResumeTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: TestEnh (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API SuspendResumeTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
for (int32 i = 0; i < 3; ++i)
{
if (audioEffect)
{
if (audioEffect->canProcessSampleSize (kSample32) == kResultOk)
processSetup.symbolicSampleSize = kSample32;
else if (audioEffect->canProcessSampleSize (kSample64) == kResultOk)
processSetup.symbolicSampleSize = kSample64;
else
{
addErrorMessage (testResult,
STR ("No appropriate symbolic sample size supported!"));
return false;
}
if (audioEffect->setupProcessing (processSetup) != kResultOk)
{
addErrorMessage (testResult, STR ("Process setup failed!"));
return false;
}
}
tresult result = vstPlug->setActive (true);
if (result != kResultOk)
return false;
result = vstPlug->setActive (false);
if (result != kResultOk)
return false;
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/suspendresume.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Suspend/Resume.
* \ingroup TestClass
*/
class SuspendResumeTest : public TestEnh
{
public:
//------------------------------------------------------------------------
SuspendResumeTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
DECLARE_VSTTEST ("Suspend/Resume")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,63 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/terminit.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/general/terminit.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// TerminateInitializeTest
//------------------------------------------------------------------------
TerminateInitializeTest::TerminateInitializeTest (ITestPlugProvider* plugProvider)
: TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool TerminateInitializeTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
auto plugBase = U::cast<IPluginBase> (vstPlug);
if (!plugBase)
{
addErrorMessage (testResult, STR ("No IPluginBase interface available."));
return false;
}
bool result = true;
if (plugBase->terminate () != kResultTrue)
{
addErrorMessage (testResult, STR ("IPluginBase::terminate () failed."));
result = false;
}
if (plugBase->initialize (TestingPluginContext::get ()) != kResultTrue)
{
addErrorMessage (testResult, STR ("IPluginBase::initialize (..) failed."));
result = false;
}
return result;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/general/terminit.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Terminate/Initialize.
* \ingroup TestClass
*/
class TerminateInitializeTest : public TestBase
{
public:
//------------------------------------------------------------------------
TerminateInitializeTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Terminate/Initialize")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,94 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/noteexpression/keyswitch.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/noteexpression/keyswitch.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstnoteexpression.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// KeyswitchTest
//------------------------------------------------------------------------
KeyswitchTest::KeyswitchTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API KeyswitchTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (!controller)
{
addMessage (testResult, STR ("No Edit Controller supplied!"));
return true;
}
auto keyswitch = U::cast<IKeyswitchController> (controller);
if (!keyswitch)
{
addMessage (testResult, STR ("No Keyswitch interface supplied!"));
return true;
}
int32 eventBusCount = vstPlug->getBusCount (kEvent, kInput);
for (int32 bus = 0; bus < eventBusCount; bus++)
{
BusInfo busInfo;
vstPlug->getBusInfo (kEvent, kInput, bus, busInfo);
for (int16 channel = 0; channel < busInfo.channelCount; channel++)
{
int32 count = keyswitch->getKeyswitchCount (bus, channel);
if (count > 0)
{
addMessage (testResult, printf ("Keyswitch support bus[%d], channel[%d]: %d", bus,
channel, count));
}
for (int32 i = 0; i < count; ++i)
{
KeyswitchInfo info;
if (keyswitch->getKeyswitchInfo (bus, channel, i, info) == kResultTrue)
{
}
else
{
addErrorMessage (
testResult,
printf ("Keyswitch getKeyswitchInfo (%d, %d, %d) return kResultFalse!", bus,
channel, i));
return false;
}
}
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/noteexpression/keyswitch.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Keyswitch.
* \ingroup TestClass
*/
class KeyswitchTest : public TestBase
{
public:
//------------------------------------------------------------------------
KeyswitchTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Keyswitch")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,164 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/noteexpression/noteexpression.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/noteexpression/noteexpression.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstnoteexpression.h"
#include "pluginterfaces/vst/ivstphysicalui.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// NoteExpressionTest
//------------------------------------------------------------------------
NoteExpressionTest::NoteExpressionTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API NoteExpressionTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (!controller)
{
addMessage (testResult, STR ("No Edit Controller supplied!"));
return true;
}
auto noteExpression = U::cast<INoteExpressionController> (controller);
if (!noteExpression)
{
addMessage (testResult, STR ("No Note Expression interface supplied!"));
return true;
}
auto noteExpressionPUIMapping = U::cast<INoteExpressionPhysicalUIMapping> (controller);
if (!noteExpressionPUIMapping)
{
addMessage (testResult, STR ("No Note Expression PhysicalUIMapping interface supplied!"));
}
int32 eventBusCount = vstPlug->getBusCount (kEvent, kInput);
const uint32 maxPUI = kPUITypeCount;
PhysicalUIMap puiArray[maxPUI];
PhysicalUIMapList puiMap;
puiMap.count = maxPUI;
puiMap.map = puiArray;
for (uint32 i = 0; i < maxPUI; i++)
{
puiMap.map[i].physicalUITypeID = static_cast<PhysicalUITypeID> (i);
}
for (int32 bus = 0; bus < eventBusCount; bus++)
{
BusInfo busInfo;
vstPlug->getBusInfo (kEvent, kInput, bus, busInfo);
for (int16 channel = 0; channel < busInfo.channelCount; channel++)
{
int32 count = noteExpression->getNoteExpressionCount (bus, channel);
if (count > 0)
{
addMessage (testResult, printf ("Note Expression count bus[%d], channel[%d]: %d",
bus, channel, count));
}
for (int32 i = 0; i < count; ++i)
{
NoteExpressionTypeInfo info;
if (noteExpression->getNoteExpressionInfo (bus, channel, i, info) == kResultTrue)
{
addMessage (testResult, printf ("Note Expression TypeID: %d [%s]", info.typeId,
StringConvert::convert (info.title).data ()));
NoteExpressionTypeID id = info.typeId;
NoteExpressionValue valueNormalized = info.valueDesc.defaultValue;
String128 string;
if (noteExpression->getNoteExpressionStringByValue (
bus, channel, id, valueNormalized, string) != kResultTrue)
{
addMessage (
testResult,
printf (
"Note Expression getNoteExpressionStringByValue (%d, %d, %d) return kResultFalse!",
bus, channel, id));
}
if (noteExpression->getNoteExpressionValueByString (
bus, channel, id, string, valueNormalized) != kResultTrue)
{
addMessage (
testResult,
printf (
"Note Expression getNoteExpressionValueByString (%d, %d, %d) return kResultFalse!",
bus, channel, id));
}
}
else
{
addErrorMessage (
testResult,
printf (
"Note Expression getNoteExpressionInfo (%d, %d, %d) return kResultFalse!",
bus, channel, i));
return false;
}
}
if (noteExpressionPUIMapping)
{
for (uint32 i = 0; i < maxPUI; i++)
{
puiMap.map[i].noteExpressionTypeID = kInvalidTypeID;
}
if (noteExpressionPUIMapping->getPhysicalUIMapping (bus, channel, puiMap) ==
kResultFalse)
{
addMessage (
testResult,
printf (
"Note Expression getPhysicalUIMapping (%d, %d, ...) return kResultFalse!",
bus, channel));
}
else
{
for (uint32 i = 0; i < maxPUI; i++)
{
addMessage (testResult,
printf ("Note Expression PhysicalUIMapping: %d => %d",
puiMap.map[i].noteExpressionTypeID,
puiMap.map[i].physicalUITypeID));
}
}
}
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/noteexpression/noteexpression.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Note Expression.
* \ingroup TestClass
*/
class NoteExpressionTest : public TestBase
{
public:
//------------------------------------------------------------------------
NoteExpressionTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Note Expression")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,326 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/automation.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/automation.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// AutomationTest
//------------------------------------------------------------------------
//------------------------------------------------------------------------
AutomationTest::AutomationTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl,
int32 everyNSamples, int32 numParams, bool sampleAccuracy)
: ProcessTest (plugProvider, sampl)
, bypassId (kNoParamId)
, countParamChanges (0)
, everyNSamples (everyNSamples)
, numParams (numParams)
, sampleAccuracy (sampleAccuracy)
, onceExecuted (false)
{
}
//------------------------------------------------------------------------
AutomationTest::~AutomationTest ()
{
}
//------------------------------------------------------------------------
tresult PLUGIN_API AutomationTest::queryInterface (const TUID _iid, void** obj)
{
QUERY_INTERFACE (_iid, obj, FUnknown::iid, IParameterChanges);
QUERY_INTERFACE (_iid, obj, Vst::IParameterChanges::iid, IParameterChanges);
return ProcessTest::queryInterface (_iid, obj);
}
//------------------------------------------------------------------------
const char* AutomationTest::getName () const
{
static std::string text;
const char* accTxt = "Sample";
if (!sampleAccuracy)
accTxt = "Block";
text = "Accuracy: ";
text += accTxt;
if (numParams < 1)
text += ", All Parameters";
else
{
text += ", ";
text += std::to_string (numParams);
text += " Parameters";
}
text += ", Change every";
text += std::to_string (everyNSamples);
text += " Samples";
return text.data ();
}
//------------------------------------------------------------------------
bool AutomationTest::setup ()
{
onceExecuted = false;
if (!ProcessTest::setup ())
return false;
if (!controller)
return false;
if ((numParams < 1) || (numParams > controller->getParameterCount ()))
numParams = controller->getParameterCount ();
if (audioEffect && (numParams > 0))
{
ParameterInfo inf = {};
for (int32 i = 0; i < numParams; ++i)
{
paramChanges.push_back (owned (new ParamChanges));
tresult r = controller->getParameterInfo (i, inf);
if (r != kResultTrue)
return false;
if ((inf.flags & inf.kCanAutomate) != 0)
paramChanges[i]->init (inf.id, processSetup.maxSamplesPerBlock);
}
for (int32 i = 0; i < controller->getParameterCount (); ++i)
{
tresult r = controller->getParameterInfo (i, inf);
if (r != kResultTrue)
return false;
if ((inf.flags & inf.kIsBypass) != 0)
{
bypassId = inf.id;
break;
}
}
return true;
}
return numParams == 0;
}
//------------------------------------------------------------------------
bool AutomationTest::run (ITestResult* testResult)
{
if (!testResult)
return false;
printTestHeader (testResult);
if (numParams == 0)
addMessage (testResult, STR ("No Parameters present."));
bool ret = ProcessTest::run (testResult);
return ret;
}
//------------------------------------------------------------------------
bool AutomationTest::teardown ()
{
paramChanges.clear ();
return ProcessTest::teardown ();
}
//------------------------------------------------------------------------
bool AutomationTest::preProcess (ITestResult* testResult)
{
if (!testResult)
return false;
if (paramChanges.empty ())
return numParams == 0;
bool check = true;
for (int32 i = 0; i < numParams; ++i)
{
paramChanges[i]->resetPoints ();
int32 point = 0;
for (int32 pos = 0; pos < processData.numSamples; pos++)
{
bool add = (rand () % everyNSamples) == 0;
if (!onceExecuted)
{
if (pos == 0)
{
add = true;
if (!sampleAccuracy)
onceExecuted = true;
}
else if ((pos == 1) && sampleAccuracy)
{
add = true;
onceExecuted = true;
}
}
if (add)
check &= paramChanges[i]->setPoint (point++, pos,
((float)(rand () % 1000000000)) / 1000000000.0);
}
if (check)
processData.inputParameterChanges = this;
}
return check;
}
//------------------------------------------------------------------------
bool AutomationTest::postProcess (ITestResult* testResult)
{
if (!testResult)
return false;
if (paramChanges.empty ())
return numParams == 0;
for (int32 i = 0; i < numParams; ++i)
{
if ((paramChanges[i]->getPointCount () > 0) &&
!paramChanges[i]->havePointsBeenRead (!sampleAccuracy))
{
if (sampleAccuracy)
addMessage (testResult,
STR (" Not all points have been read via IParameterChanges"));
else
addMessage (testResult,
STR (" No point at all has been read via IParameterChanges"));
return true; // should not be a problem
}
}
return true;
}
//------------------------------------------------------------------------
int32 AutomationTest::getParameterCount ()
{
if (paramChanges.empty ())
return numParams;
return static_cast<int32> (paramChanges.size ());
}
//------------------------------------------------------------------------
IParamValueQueue* AutomationTest::getParameterData (int32 index)
{
if ((index >= 0) && (index < getParameterCount ()))
return paramChanges[index];
return nullptr;
}
//------------------------------------------------------------------------
IParamValueQueue* AutomationTest::addParameterData (const ParamID& /*id*/, int32& /*index*/)
{
return nullptr;
}
//------------------------------------------------------------------------
// FlushParamTest
//------------------------------------------------------------------------
FlushParamTest::FlushParamTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: AutomationTest (plugProvider, sampl, 100, 1, false)
{
}
//------------------------------------------------------------------------
void FlushParamTest::prepareProcessData ()
{
processData.numSamples = 0;
processData.numInputs = 0;
processData.numOutputs = 0;
processData.inputs = nullptr;
processData.outputs = nullptr;
}
//------------------------------------------------------------------------
bool PLUGIN_API FlushParamTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
unprepareProcessing ();
prepareProcessData ();
audioEffect->setProcessing (true);
preProcess (testResult);
tresult result = audioEffect->process (processData);
if (result != kResultOk)
{
addErrorMessage (testResult,
STR ("The component failed to process without audio buffers!"));
audioEffect->setProcessing (false);
return false;
}
postProcess (testResult);
audioEffect->setProcessing (false);
return true;
}
//------------------------------------------------------------------------
// FlushParamTest2
//------------------------------------------------------------------------
FlushParamTest2::FlushParamTest2 (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: FlushParamTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
void FlushParamTest2::prepareProcessData ()
{
prepareProcessing ();
processData.numSamples = 0;
// remember original processData config
std::swap (numInputs, processData.numInputs);
std::swap (numOutputs, processData.numOutputs);
if (processData.inputs)
std::swap (numChannelsIn, processData.inputs[0].numChannels);
if (processData.outputs)
std::swap (numChannelsOut, processData.outputs[0].numChannels);
}
//------------------------------------------------------------------------
bool FlushParamTest2::teardown ()
{
// restore original processData config for correct deallocation
std::swap (numInputs, processData.numInputs);
std::swap (numOutputs, processData.numOutputs);
if (processData.inputs)
std::swap (numChannelsIn, processData.inputs[0].numChannels);
if (processData.outputs)
std::swap (numChannelsOut, processData.outputs[0].numChannels);
return FlushParamTest::teardown ();
}
//------------------------------------------------------------------------
// FlushParamTest3
//------------------------------------------------------------------------
FlushParamTest3::FlushParamTest3 (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: FlushParamTest (plugProvider, sampl)
{
paramChanges.clear ();
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,120 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/automation.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
#include <vector>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
class ParamChanges;
//------------------------------------------------------------------------
/** Test Automation.
* \ingroup TestClass
*/
class AutomationTest : public ProcessTest, public IParameterChanges
{
public:
AutomationTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl, int32 everyNSamples,
int32 numParams, bool sampleAccuracy);
~AutomationTest () override;
const char* getName () const SMTG_OVERRIDE;
// ITest
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool PLUGIN_API teardown () SMTG_OVERRIDE;
// IParameterChanges
int32 PLUGIN_API getParameterCount () SMTG_OVERRIDE;
IParamValueQueue* PLUGIN_API getParameterData (int32 index) SMTG_OVERRIDE;
IParamValueQueue* PLUGIN_API addParameterData (const ParamID& id, int32& index) SMTG_OVERRIDE;
// FUnknown
DELEGATE_REFCOUNT (ProcessTest)
tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) override;
//------------------------------------------------------------------------
protected:
bool preProcess (ITestResult* testResult) SMTG_OVERRIDE;
bool postProcess (ITestResult* testResult) SMTG_OVERRIDE;
ParamID bypassId;
using ParamChangeVector = std::vector<IPtr<ParamChanges>>;
ParamChangeVector paramChanges;
int32 countParamChanges;
int32 everyNSamples;
int32 numParams;
bool sampleAccuracy;
bool onceExecuted;
};
//------------------------------------------------------------------------
/** Test Parameters Flush (no Buffer).
* \ingroup TestClass
*/
class FlushParamTest : public AutomationTest
{
public:
FlushParamTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Parameters Flush (no Buffer)")
protected:
virtual void prepareProcessData ();
};
//------------------------------------------------------------------------
/** Test Parameters Flush 2 (no Buffer).
* \ingroup TestClass
*/
class FlushParamTest2 : public FlushParamTest
{
public:
FlushParamTest2 (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API teardown () SMTG_OVERRIDE;
DECLARE_VSTTEST ("Parameters Flush 2 (only numChannel==0)")
protected:
void prepareProcessData () SMTG_OVERRIDE;
int32 numInputs {0};
int32 numOutputs {0};
int32 numChannelsIn {0};
int32 numChannelsOut {0};
};
//------------------------------------------------------------------------
/** Test Parameters Flush 3 (no Buffer, no parameter change).
* \ingroup TestClass
*/
class FlushParamTest3 : public FlushParamTest
{
public:
FlushParamTest3 (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
DECLARE_VSTTEST ("Parameters Flush 2 (no Buffer, no parameter change)")
protected:
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,275 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/process.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProcessTest
//------------------------------------------------------------------------
ProcessTest::ProcessTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: TestEnh (plugProvider, sampl)
{
processData.numSamples = TestDefaults::instance ().defaultBlockSize;
processData.symbolicSampleSize = sampl;
processSetup.processMode = kRealtime;
processSetup.symbolicSampleSize = sampl;
processSetup.maxSamplesPerBlock = TestDefaults::instance ().maxBlockSize;
processSetup.sampleRate = TestDefaults::instance ().defaultSampleRate;
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessTest::setup ()
{
if (!TestEnh::setup ())
return false;
if (!vstPlug || !audioEffect)
return false;
if (processSetup.symbolicSampleSize != processData.symbolicSampleSize)
return false;
if (audioEffect->canProcessSampleSize (processSetup.symbolicSampleSize) != kResultOk)
return true; // this fails in run (..)
prepareProcessing ();
if (vstPlug->setActive (true) != kResultTrue)
return false;
return true;
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessTest::run (ITestResult* testResult)
{
if (!testResult || !audioEffect)
return false;
if (processSetup.symbolicSampleSize != processData.symbolicSampleSize)
return false;
if (!canProcessSampleSize (testResult))
return true;
audioEffect->setProcessing (true);
for (int32 i = 0; i < TestDefaults::instance ().numAudioBlocksToProcess; ++i)
{
if (!preProcess (testResult))
return false;
tresult result = audioEffect->process (processData);
if (result != kResultOk)
{
if (processSetup.symbolicSampleSize == kSample32)
addErrorMessage (testResult,
STR ("IAudioProcessor::process (..with kSample32..) failed."));
else
addErrorMessage (testResult,
STR ("IAudioProcessor::process (..with kSample64..) failed."));
audioEffect->setProcessing (false);
return false;
}
if (!postProcess (testResult))
{
audioEffect->setProcessing (false);
return false;
}
}
audioEffect->setProcessing (false);
return true;
}
//------------------------------------------------------------------------
bool ProcessTest::preProcess (ITestResult* /*testResult*/)
{
return true;
}
//------------------------------------------------------------------------
bool ProcessTest::postProcess (ITestResult* /*testResult*/)
{
return true;
}
//------------------------------------------------------------------------
bool ProcessTest::canProcessSampleSize (ITestResult* testResult)
{
if (!testResult || !audioEffect)
return false;
if (processSetup.symbolicSampleSize != processData.symbolicSampleSize)
return false;
if (audioEffect->canProcessSampleSize (processSetup.symbolicSampleSize) != kResultOk)
{
if (processSetup.symbolicSampleSize == kSample32)
addMessage (testResult, STR ("32bit Audio Processing not supported."));
else
addMessage (testResult, STR ("64bit Audio Processing not supported."));
return false;
}
return true;
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessTest::teardown ()
{
unprepareProcessing ();
if (!vstPlug || (vstPlug->setActive (false) != kResultOk))
return false;
return TestEnh::teardown ();
}
//------------------------------------------------------------------------
bool ProcessTest::prepareProcessing ()
{
if (!vstPlug || !audioEffect)
return false;
if (audioEffect->setupProcessing (processSetup) == kResultOk)
{
processData.prepare (*vstPlug, 0, processSetup.symbolicSampleSize);
for (BusDirection dir = kInput; dir <= kOutput; dir++)
{
int32 numBusses = vstPlug->getBusCount (kAudio, dir);
AudioBusBuffers* audioBuffers =
dir == kInput ? processData.inputs :
processData.outputs; // new AudioBusBuffers [numBusses];
if (!setupBuffers (numBusses, audioBuffers, dir))
return false;
if (dir == kInput)
{
processData.numInputs = numBusses;
processData.inputs = audioBuffers;
}
else
{
processData.numOutputs = numBusses;
processData.outputs = audioBuffers;
}
}
return true;
}
return false;
}
//------------------------------------------------------------------------
bool ProcessTest::setupBuffers (int32 numBusses, AudioBusBuffers* audioBuffers, BusDirection dir)
{
if (((numBusses > 0) && !audioBuffers) || !vstPlug)
return false;
for (int32 busIndex = 0; busIndex < numBusses; busIndex++) // buses
{
BusInfo busInfo {};
if (vstPlug->getBusInfo (kAudio, dir, busIndex, busInfo) == kResultTrue)
{
if (!setupBuffers (audioBuffers[busIndex]))
return false;
if ((busInfo.flags & BusInfo::kDefaultActive) != 0)
{
for (int32 chIdx = 0; chIdx < busInfo.channelCount; chIdx++) // channels per bus
audioBuffers[busIndex].silenceFlags |=
(TestDefaults::instance ().channelIsSilent << chIdx);
}
}
else
return false;
}
return true;
}
//------------------------------------------------------------------------
bool ProcessTest::setupBuffers (AudioBusBuffers& audioBuffers)
{
if (processSetup.symbolicSampleSize != processData.symbolicSampleSize)
return false;
audioBuffers.silenceFlags = 0;
for (int32 chIdx = 0; chIdx < audioBuffers.numChannels; chIdx++)
{
if (processSetup.symbolicSampleSize == kSample32)
{
if (audioBuffers.channelBuffers32)
{
audioBuffers.channelBuffers32[chIdx] =
new Sample32[processSetup.maxSamplesPerBlock];
if (audioBuffers.channelBuffers32[chIdx])
memset (audioBuffers.channelBuffers32[chIdx], 0,
processSetup.maxSamplesPerBlock * sizeof (Sample32));
else
return false;
}
else
return false;
}
else if (processSetup.symbolicSampleSize == kSample64)
{
if (audioBuffers.channelBuffers64)
{
audioBuffers.channelBuffers64[chIdx] =
new Sample64[processSetup.maxSamplesPerBlock];
if (audioBuffers.channelBuffers64[chIdx])
memset (audioBuffers.channelBuffers64[chIdx], 0,
processSetup.maxSamplesPerBlock * sizeof (Sample64));
else
return false;
}
else
return false;
}
else
return false;
}
return true;
}
//------------------------------------------------------------------------
bool ProcessTest::unprepareProcessing ()
{
bool ret = true;
ret &= freeBuffers (processData.numInputs, processData.inputs);
ret &= freeBuffers (processData.numOutputs, processData.outputs);
processData.unprepare ();
return ret;
}
//------------------------------------------------------------------------
bool ProcessTest::freeBuffers (int32 numBuses, AudioBusBuffers* buses)
{
if (processSetup.symbolicSampleSize != processData.symbolicSampleSize)
return false;
for (int32 busIndex = 0; busIndex < numBuses; busIndex++)
{
for (int32 chIdx = 0; chIdx < buses[busIndex].numChannels; chIdx++)
{
if (processSetup.symbolicSampleSize == kSample32)
delete[] buses[busIndex].channelBuffers32[chIdx];
else if (processSetup.symbolicSampleSize == kSample64)
delete[] buses[busIndex].channelBuffers64[chIdx];
else
return false;
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/process.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/hosting/processdata.h"
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Process Test.
* \ingroup TestClass
*/
class ProcessTest : public TestEnh
{
public:
ProcessTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
DECLARE_VSTTEST ("Process Test")
// ITest
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool PLUGIN_API teardown () SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
virtual bool prepareProcessing (); ///< setup ProcessData and allocate buffers
virtual bool unprepareProcessing (); ///< free dynamic memory of ProcessData
virtual bool preProcess (ITestResult* testResult); ///< is called just before the process call
virtual bool postProcess (ITestResult* testResult); ///< is called right after the process call
bool setupBuffers (int32 numBusses, AudioBusBuffers* audioBuffers, BusDirection dir);
bool setupBuffers (AudioBusBuffers& audioBuffers);
bool freeBuffers (int32 numBuses, AudioBusBuffers* buses);
bool canProcessSampleSize (ITestResult* testResult); ///< audioEffect has to be available
HostProcessData processData;
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,145 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processcontextrequirements.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/processcontextrequirements.h"
#include "public.sdk/source/vst/hosting/module.h"
#include "public.sdk/source/vst/utility/processcontextrequirements.h"
#include "public.sdk/source/vst/utility/versionparser.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
namespace {
//------------------------------------------------------------------------
VST3::Optional<VST3::Version> getPluginSDKVersion (ITestPlugProvider* plugProvider,
ITestResult* testResult)
{
auto pp2 = U::cast<ITestPlugProvider2> (plugProvider);
if (!pp2)
{
addErrorMessage (testResult, STR ("Internal test Error. Expected Interface not there!"));
return {};
}
VST3::Hosting::PluginFactory pluginFactory (pp2->getPluginFactory ());
if (!pluginFactory.get ())
{
addErrorMessage (testResult,
STR ("Internal test Error. Expected PluginFactory not there!"));
return {};
}
FUID fuid;
if (pp2->getComponentUID (fuid) != kResultTrue)
{
addErrorMessage (testResult,
STR ("Internal test Error. Could not query the UID of the plug-in!"));
return {};
}
auto plugClassID = VST3::UID::fromTUID (fuid.toTUID ());
auto classInfos = pluginFactory.classInfos ();
auto it = std::find_if (classInfos.begin (), classInfos.end (),
[&] (const auto& element) { return element.ID () == plugClassID; });
if (it == classInfos.end ())
{
addErrorMessage (
testResult, STR ("Internal test Error. Could not find the class info of the plug-in!"));
return {};
}
return VST3::Version::parse (it->sdkVersion ());
}
//------------------------------------------------------------------------
} // anonymous
//------------------------------------------------------------------------
// ProcessContextRequirementsTest
//------------------------------------------------------------------------
ProcessContextRequirementsTest::ProcessContextRequirementsTest (ITestPlugProvider* plugProvider)
: TestEnh (plugProvider, kSample32)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessContextRequirementsTest::setup ()
{
return TestEnh::setup ();
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessContextRequirementsTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
printTestHeader (testResult);
// check if plug-in is build with any earlier VST SDK which does not support this interface
auto sdkVersion = getPluginSDKVersion (plugProvider, testResult);
if (!sdkVersion)
return false;
if (sdkVersion->getMajor () < 3 ||
(sdkVersion->getMajor () == 3 && sdkVersion->getMinor () < 7))
{
addMessage (testResult,
STR ("No ProcessContextRequirements required. Plug-In built with older SDK."));
return true;
}
if (auto contextRequirements = U::cast<IProcessContextRequirements> (audioEffect))
{
ProcessContextRequirements req (contextRequirements->getProcessContextRequirements ());
addMessage (testResult, STR ("ProcessContextRequirements:"));
if (req.wantsNone ())
addMessage (testResult, STR (" - None"));
else
{
if (req.wantsSystemTime ())
addMessage (testResult, STR (" - SystemTime"));
if (req.wantsContinousTimeSamples ())
addMessage (testResult, STR (" - ContinousTimeSamples"));
if (req.wantsProjectTimeMusic ())
addMessage (testResult, STR (" - ProjectTimeMusic"));
if (req.wantsBarPositionMusic ())
addMessage (testResult, STR (" - BarPosititionMusic"));
if (req.wantsCycleMusic ())
addMessage (testResult, STR (" - CycleMusic"));
if (req.wantsSamplesToNextClock ())
addMessage (testResult, STR (" - SamplesToNextClock"));
if (req.wantsTempo ())
addMessage (testResult, STR (" - Tempo"));
if (req.wantsTimeSignature ())
addMessage (testResult, STR (" - TimeSignature"));
if (req.wantsChord ())
addMessage (testResult, STR (" - Chord"));
if (req.wantsFrameRate ())
addMessage (testResult, STR (" - FrameRate"));
if (req.wantsTransportState ())
addMessage (testResult, STR (" - TransportState"));
}
return true;
}
addMessage (testResult,
STR ("Since VST SDK 3.7 you need to implement IProcessContextRequirements!"));
addErrorMessage (testResult, STR ("Missing mandatory IProcessContextRequirements extension!"));
return false;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processcontextrequirements.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Silence Flags.
* \ingroup TestClass
*/
class ProcessContextRequirementsTest : public TestEnh
{
public:
ProcessContextRequirementsTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool PLUGIN_API setup () SMTG_OVERRIDE;
DECLARE_VSTTEST ("ProcessContext Requirements")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,113 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processformat.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/processformat.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProcessFormatTest
//------------------------------------------------------------------------
ProcessFormatTest::ProcessFormatTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessFormatTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
int32 numFails = 0;
const int32 numRates = 12;
SampleRate sampleRateFormats[numRates] = {22050., 32000., 44100., 48000.,
88200., 96000., 192000., 384000.,
1234.5678, 12345.678, 123456.78, 1234567.8};
tresult result = vstPlug->setActive (false);
if (result != kResultOk)
{
addErrorMessage (testResult, STR ("IComponent::setActive (false) failed."));
return false;
}
addMessage (testResult, STR ("***Tested Sample Rates***"));
for (int32 i = 0; i < numRates; ++i)
{
processSetup.sampleRate = sampleRateFormats[i];
result = audioEffect->setupProcessing (processSetup);
if (result == kResultOk)
{
result = vstPlug->setActive (true);
if (result != kResultOk)
{
addErrorMessage (testResult, STR ("IComponent::setActive (true) failed."));
return false;
}
audioEffect->setProcessing (true);
result = audioEffect->process (processData);
audioEffect->setProcessing (false);
if (result == kResultOk)
{
addMessage (testResult,
printf (" %10.10G Hz - processed successfully!", sampleRateFormats[i]));
}
else
{
numFails++;
addErrorMessage (testResult,
printf (" %10.10G Hz - failed to process!", sampleRateFormats[i]));
}
result = vstPlug->setActive (false);
if (result != kResultOk)
{
addErrorMessage (testResult, STR ("IComponent::setActive (false) failed."));
return false;
}
}
else if (sampleRateFormats[i] > 0.)
{
addErrorMessage (
testResult,
printf ("IAudioProcessor::setupProcessing (..) failed for samplerate %.3f Hz! ",
sampleRateFormats[i]));
// return false;
}
}
result = vstPlug->setActive (true);
if (result != kResultOk)
return false;
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processformat.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Process Format.
* \ingroup TestClass
*/
class ProcessFormatTest : public ProcessTest
{
public:
ProcessFormatTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Process Format")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,177 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processinputoverwriting.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/processinputoverwriting.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProcessInputOverwritingTest
//------------------------------------------------------------------------
ProcessInputOverwritingTest::ProcessInputOverwritingTest (ITestPlugProvider* plugProvider,
ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
bool ProcessInputOverwritingTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
bool ret = ProcessTest::run (testResult);
return ret;
}
//------------------------------------------------------------------------
bool ProcessInputOverwritingTest::preProcess (ITestResult* /*testResult*/)
{
int32 min = processData.numInputs < processData.numOutputs ? processData.numInputs :
processData.numOutputs;
noNeedtoProcess = true;
for (int32 i = 0; i < min; i++)
{
if (!noNeedtoProcess)
break;
int32 minChannel = processData.inputs[i].numChannels < processData.outputs[i].numChannels ?
processData.inputs[i].numChannels :
processData.outputs[i].numChannels;
auto ptrIn = processData.inputs[i].channelBuffers32;
auto ptrOut = processData.outputs[i].channelBuffers32;
for (int32 j = 0; j < minChannel; j++)
{
if (ptrIn[j] != ptrOut[j])
{
noNeedtoProcess = false;
break;
}
}
}
if (noNeedtoProcess)
return true;
for (int32 i = 0; i < processData.numInputs; i++)
{
if (processSetup.symbolicSampleSize == kSample32)
{
auto ptr = processData.inputs[i].channelBuffers32;
if (ptr)
{
float inc = 1.f / (processData.numSamples - 1);
for (int32 c = 0; c < processData.inputs[i].numChannels; c++)
{
auto chaBuf = ptr[c];
for (int32 j = 0; j < processData.numSamples; j++)
{
*chaBuf = inc * j;
chaBuf++;
}
}
}
}
else if (processSetup.symbolicSampleSize == kSample64)
{
auto ptr = processData.inputs[i].channelBuffers64;
if (ptr)
{
double inc = 1.0 / (processData.numSamples - 1);
for (int32 c = 0; c < processData.inputs[i].numChannels; c++)
{
auto chaBuf = ptr[c];
for (int32 j = 0; j < processData.numSamples; j++)
{
*chaBuf = inc * j;
chaBuf++;
}
}
}
}
}
return true;
}
//------------------------------------------------------------------------
bool ProcessInputOverwritingTest::postProcess (ITestResult* testResult)
{
if (noNeedtoProcess)
return true;
for (int32 i = 0; i < processData.numInputs; i++)
{
if (processSetup.symbolicSampleSize == kSample32)
{
auto ptr = processData.inputs[i].channelBuffers32;
if (ptr)
{
float inc = 1.f / (processData.numSamples - 1);
for (int32 c = 0; c < processData.inputs[i].numChannels; c++)
{
auto chaBuf = ptr[c];
for (int32 j = 0; j < processData.numSamples; j++)
{
if (*chaBuf != inc * j)
{
addErrorMessage (
testResult,
STR (
"IAudioProcessor::process overwrites input buffer (..with kSample32..)!"));
return false;
}
chaBuf++;
}
}
}
}
else if (processSetup.symbolicSampleSize == kSample64)
{
auto ptr = processData.inputs[i].channelBuffers64;
if (ptr)
{
double inc = 1.0 / (processData.numSamples - 1);
for (int32 c = 0; c < processData.inputs[i].numChannels; c++)
{
auto chaBuf = ptr[c];
for (int32 j = 0; j < processData.numSamples; j++)
{
if (*chaBuf != inc * j)
{
addErrorMessage (
testResult,
STR (
"IAudioProcessor::process overwrites input buffer (..with kSample64..)!"));
return false;
}
chaBuf++;
}
}
}
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processinputoverwriting.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Input Overwriting
* \ingroup TestClass
*/
class ProcessInputOverwritingTest : public ProcessTest
{
public:
ProcessInputOverwritingTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool preProcess (ITestResult* testResult) SMTG_OVERRIDE;
bool postProcess (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Process Input Overwriting")
private:
bool noNeedtoProcess = false;
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,250 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processtail.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/processtail.h"
#include <cmath>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProcessTailTest
//------------------------------------------------------------------------
ProcessTailTest::ProcessTailTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
, mTailSamples (0)
, mInTail (0)
, dataPtrFloat (nullptr)
, dataPtrDouble (nullptr)
, mInSilenceInput (false)
, mDontTest (false) {FUNKNOWN_CTOR}
//------------------------------------------------------------------------
ProcessTailTest::~ProcessTailTest ()
{
if (dataPtrFloat)
{
delete[] dataPtrFloat;
dataPtrFloat = nullptr;
}
if (dataPtrDouble)
{
delete[] dataPtrDouble;
dataPtrDouble = nullptr;
}
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessTailTest::setup ()
{
bool result = ProcessTest::setup ();
if (result)
{
mTailSamples = audioEffect->getTailSamples ();
StringResult subCat;
plugProvider->getSubCategories (subCat);
if (subCat.get ().find ("Generator") != std::string::npos ||
subCat.get ().find ("Instrument") != std::string::npos)
{
mDontTest = true;
}
}
return result;
}
//------------------------------------------------------------------------
bool ProcessTailTest::preProcess (ITestResult* /*testResult*/)
{
if (!mInSilenceInput)
{
if (processSetup.symbolicSampleSize == kSample32)
{
if (!dataPtrFloat)
dataPtrFloat = new float[processData.numSamples];
float* ptr = dataPtrFloat;
for (int32 i = 0; i < processData.numSamples; ++i)
ptr[i] = (float)(2 * rand () / 32767.0 - 1);
}
else
{
if (!dataPtrDouble)
dataPtrDouble = new double[processData.numSamples];
double* ptr = (double*)dataPtrDouble;
for (int32 i = 0; i < processData.numSamples; ++i)
ptr[i] = (double)(2 * rand () / 32767.0 - 1);
}
for (int32 i = 0; i < processData.numOutputs; ++i)
{
for (int32 c = 0; c < processData.outputs->numChannels; ++c)
{
if (processSetup.symbolicSampleSize == kSample32)
memset (processData.outputs->channelBuffers32[c], 0,
processData.numSamples * sizeof (float));
else
memset (processData.outputs->channelBuffers64[c], 0,
processData.numSamples * sizeof (double));
}
}
for (int32 i = 0; i < processData.numInputs; ++i)
{
for (int32 c = 0; c < processData.inputs->numChannels; ++c)
{
if (processSetup.symbolicSampleSize == kSample32)
memcpy (processData.inputs->channelBuffers32[c], dataPtrFloat,
processData.numSamples * sizeof (float));
else
memcpy (processData.inputs->channelBuffers64[c], dataPtrDouble,
processData.numSamples * sizeof (double));
}
}
}
else
{
// process with silent buffers
for (int32 i = 0; i < processData.numOutputs; ++i)
{
for (int32 c = 0; c < processData.outputs->numChannels; ++c)
{
if (processSetup.symbolicSampleSize == kSample32)
memset (processData.outputs->channelBuffers32[c], 0,
processData.numSamples * sizeof (float));
else
memset (processData.outputs->channelBuffers64[c], 0,
processData.numSamples * sizeof (double));
}
}
for (int32 i = 0; i < processData.numInputs; ++i)
{
for (int32 c = 0; c < processData.inputs->numChannels; ++c)
{
if (processSetup.symbolicSampleSize == kSample32)
memset (processData.inputs->channelBuffers32[c], 0,
processData.numSamples * sizeof (float));
else
memset (processData.inputs->channelBuffers64[c], 0,
processData.numSamples * sizeof (double));
}
}
}
return true;
}
//------------------------------------------------------------------------
bool ProcessTailTest::postProcess (ITestResult* testResult)
{
if (mInSilenceInput)
{
// should be silence
if (mTailSamples < mInTail + processData.numSamples)
{
int32 start = mTailSamples > mInTail ? mTailSamples - mInTail : 0;
int32 end = processData.numSamples;
for (int32 i = 0; i < processData.numOutputs; ++i)
{
for (int32 c = 0; c < processData.outputs->numChannels; ++c)
{
if (processSetup.symbolicSampleSize == kSample32)
{
for (int32 s = start; s < end; ++s)
{
if (fabsf (processData.outputs->channelBuffers32[c][s]) >= 1e-7)
{
addErrorMessage (
testResult,
printf (
"IAudioProcessor::process (..) generates non silent output for silent input for tail above %d samples.",
mTailSamples));
return false;
}
}
}
else
{
for (int32 s = start; s < end; ++s)
{
if (fabs (processData.outputs->channelBuffers64[c][s]) >= 1e-7)
{
addErrorMessage (
testResult,
printf (
"IAudioProcessor::process (..) generates non silent output for silent input for tail above %d samples.",
mTailSamples));
return false;
}
}
}
}
}
}
mInTail += processData.numSamples;
}
return true;
}
//------------------------------------------------------------------------
bool PLUGIN_API ProcessTailTest::run (ITestResult* testResult)
{
if (!testResult || !audioEffect)
return false;
if (processSetup.symbolicSampleSize != processData.symbolicSampleSize)
return false;
if (!canProcessSampleSize (testResult))
return true;
if (mDontTest)
return true;
addMessage (testResult,
printf ("===%s == Tail=%d ======================", getName (), mTailSamples));
audioEffect->setProcessing (true);
// process with signal (noise) and silence
for (int32 i = 0; i < 20 * TestDefaults::instance ().numAudioBlocksToProcess; ++i)
{
mInSilenceInput = i > 10;
if (!preProcess (testResult))
return false;
tresult result = audioEffect->process (processData);
if (result != kResultOk)
{
addErrorMessage (testResult, STR ("IAudioProcessor::process (..) failed."));
audioEffect->setProcessing (false);
return false;
}
if (!postProcess (testResult))
{
audioEffect->setProcessing (false);
return false;
}
}
audioEffect->setProcessing (false);
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processtail.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test ProcesTail.
* \ingroup TestClass
*/
class ProcessTailTest : public ProcessTest
{
public:
ProcessTailTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
~ProcessTailTest () override;
DECLARE_VSTTEST ("Check Tail processing")
// ITest
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool preProcess (ITestResult* testResult) SMTG_OVERRIDE;
bool postProcess (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
private:
uint32 mTailSamples;
uint32 mInTail;
float* dataPtrFloat;
double* dataPtrDouble;
bool mInSilenceInput;
bool mDontTest;
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,75 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processthreaded.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/processthreaded.h"
#include <thread>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProcessTest
//------------------------------------------------------------------------
ProcessThreadTest::ProcessThreadTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
ProcessThreadTest::~ProcessThreadTest ()
{
}
//------------------------------------------------------------------------
bool ProcessThreadTest::run (ITestResult* testResult)
{
constexpr auto NUM_ITERATIONS = 9999;
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
bool result = false;
std::thread processThread ([&] () {
result = true;
audioEffect->setProcessing (true);
for (auto i = 0; i < NUM_ITERATIONS; i++)
{
tresult tr = audioEffect->process (processData);
if (tr != kResultTrue)
{
result = false;
break;
}
}
audioEffect->setProcessing (false);
});
processThread.join ();
if (!result)
testResult->addErrorMessage (STR ("Processing failed."));
return result;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/processthreaded.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProcessTest
//------------------------------------------------------------------------
class ProcessThreadTest : public ProcessTest
{
public:
//------------------------------------------------------------------------
ProcessThreadTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
~ProcessThreadTest () override;
DECLARE_VSTTEST ("Process function running in another thread")
bool PLUGIN_API run (ITestResult* testResult) override;
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/silenceflags.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/silenceflags.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// SilenceFlagsTest
//------------------------------------------------------------------------
SilenceFlagsTest::SilenceFlagsTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API SilenceFlagsTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
if (processData.inputs != nullptr)
{
audioEffect->setProcessing (true);
for (int32 inputsIndex = 0; inputsIndex < processData.numInputs; inputsIndex++)
{
int32 numSilenceFlagsCombinations =
(1 << processData.inputs[inputsIndex].numChannels) - 1;
for (int32 flagCombination = 0; flagCombination <= numSilenceFlagsCombinations;
flagCombination++)
{
processData.inputs[inputsIndex].silenceFlags = flagCombination;
tresult result = audioEffect->process (processData);
if (result != kResultOk)
{
addErrorMessage (
testResult,
printf (
"The component failed to process bus %i with silence flag combination %x!",
inputsIndex, flagCombination));
audioEffect->setProcessing (false);
return false;
}
}
}
}
else if (processData.numInputs > 0)
{
addErrorMessage (testResult,
STR ("ProcessData::inputs are 0 but ProcessData::numInputs are nonzero."));
return false;
}
audioEffect->setProcessing (false);
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/silenceflags.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Silence Flags.
* \ingroup TestClass
*/
class SilenceFlagsTest : public ProcessTest
{
public:
SilenceFlagsTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Silence Flags")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,159 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/silenceprocessing.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/silenceprocessing.h"
#include <cmath>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// SilenceProcessingTest
//------------------------------------------------------------------------
SilenceProcessingTest::SilenceProcessingTest (ITestPlugProvider* plugProvider,
ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
bool SilenceProcessingTest::isBufferSilent (void* buffer, int32 numSamples, ProcessSampleSize sampl)
{
if (sampl == kSample32)
{
const float kSilenceThreshold = 0.000132184039f;
float* floatBuffer = (float*)buffer;
while (numSamples--)
{
if (fabsf (*floatBuffer) > kSilenceThreshold)
return false;
floatBuffer++;
}
}
else if (sampl == kSample64)
{
const double kSilenceThreshold = 0.000132184039;
double* floatBuffer = (double*)buffer;
while (numSamples--)
{
if (fabs (*floatBuffer) > kSilenceThreshold)
return false;
floatBuffer++;
}
}
return true;
}
//------------------------------------------------------------------------
bool PLUGIN_API SilenceProcessingTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
if (processData.inputs != nullptr)
{
// process 20s before checking flags
int32 numPasses = int32 (20 * processSetup.sampleRate / processData.numSamples + 0.5);
audioEffect->setProcessing (true);
for (int32 pass = 0; pass < numPasses; pass++)
{
for (int32 busIndex = 0; busIndex < processData.numInputs; busIndex++)
{
processData.inputs[busIndex].silenceFlags = 0;
for (int32 channelIndex = 0;
channelIndex < processData.inputs[busIndex].numChannels; channelIndex++)
{
processData.inputs[busIndex].silenceFlags |= (uint64)1 << (uint64)channelIndex;
if (processData.symbolicSampleSize == kSample32)
memset (processData.inputs[busIndex].channelBuffers32[channelIndex], 0,
sizeof (float) * processData.numSamples);
else if (processData.symbolicSampleSize == kSample64)
memset (processData.inputs[busIndex].channelBuffers32[channelIndex], 0,
sizeof (double) * processData.numSamples);
}
}
for (int32 busIndex = 0; busIndex < processData.numOutputs; busIndex++)
{
if (processData.numInputs > busIndex)
processData.outputs[busIndex].silenceFlags =
processData.inputs[busIndex].silenceFlags;
else
{
processData.outputs[busIndex].silenceFlags = 0;
for (int32 channelIndex = 0;
channelIndex < processData.outputs[busIndex].numChannels; channelIndex++)
processData.outputs[busIndex].silenceFlags |= (uint64)1
<< (uint64)channelIndex;
}
}
tresult result = audioEffect->process (processData);
if (result != kResultOk)
{
addErrorMessage (testResult, printf ("%s", "The component failed to process!"));
audioEffect->setProcessing (false);
return false;
}
}
for (int32 busIndex = 0; busIndex < processData.numOutputs; busIndex++)
{
for (int32 channelIndex = 0; channelIndex < processData.outputs[busIndex].numChannels;
channelIndex++)
{
bool channelShouldBeSilent = (processData.outputs[busIndex].silenceFlags &
(uint64)1 << (uint64)channelIndex) != 0;
bool channelIsSilent =
isBufferSilent (processData.outputs[busIndex].channelBuffers32[channelIndex],
processData.numSamples, processData.symbolicSampleSize);
if (channelShouldBeSilent != channelIsSilent)
{
constexpr auto silentText = STR (
"The component reported a wrong silent flag for its output buffer! : output is silent but silenceFlags not set !");
constexpr auto nonSilentText = STR (
"The component reported a wrong silent flag for its output buffer! : silenceFlags is set to silence but output is not silent");
addMessage (testResult, channelIsSilent ? silentText : nonSilentText);
break;
}
}
}
}
else if (processData.numInputs > 0)
{
addErrorMessage (testResult,
STR ("ProcessData::inputs are 0 but ProcessData::numInputs are nonzero."));
return false;
}
audioEffect->setProcessing (false);
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/silenceprocessing.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Silence Processing.
* \ingroup TestClass
*/
class SilenceProcessingTest : public ProcessTest
{
public:
SilenceProcessingTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Silence Processing")
protected:
bool isBufferSilent (void* buffer, int32 numSamples, ProcessSampleSize sampl);
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,233 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/speakerarrangement.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/speakerarrangement.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// SpeakerArrangementTest
//------------------------------------------------------------------------
SpeakerArrangementTest::SpeakerArrangementTest (ITestPlugProvider* plugProvider,
ProcessSampleSize sampl, SpeakerArrangement inSpArr,
SpeakerArrangement outSpArr)
: ProcessTest (plugProvider, sampl), inSpArr (inSpArr), outSpArr (outSpArr)
{
}
//------------------------------------------------------------------------
const char* SpeakerArrangementTest::getSpeakerArrangementName (SpeakerArrangement spArr)
{
const char* saName = nullptr;
switch (spArr)
{
case SpeakerArr::kMono: saName = "Mono"; break;
case SpeakerArr::kStereo: saName = "Stereo"; break;
case SpeakerArr::kStereoSurround: saName = "StereoSurround"; break;
case SpeakerArr::kStereoCenter: saName = "StereoCenter"; break;
case SpeakerArr::kStereoSide: saName = "StereoSide"; break;
case SpeakerArr::kStereoCLfe: saName = "StereoCLfe"; break;
case SpeakerArr::k30Cine: saName = "30Cine"; break;
case SpeakerArr::k30Music: saName = "30Music"; break;
case SpeakerArr::k31Cine: saName = "31Cine"; break;
case SpeakerArr::k31Music: saName = "31Music"; break;
case SpeakerArr::k40Cine: saName = "40Cine"; break;
case SpeakerArr::k40Music: saName = "40Music"; break;
case SpeakerArr::k41Cine: saName = "41Cine"; break;
case SpeakerArr::k41Music: saName = "41Music"; break;
case SpeakerArr::k50: saName = "50"; break;
case SpeakerArr::k51: saName = "51"; break;
case SpeakerArr::k60Cine: saName = "60Cine"; break;
case SpeakerArr::k60Music: saName = "60Music"; break;
case SpeakerArr::k61Cine: saName = "61Cine"; break;
case SpeakerArr::k61Music: saName = "61Music"; break;
case SpeakerArr::k70Cine: saName = "70Cine"; break;
case SpeakerArr::k70Music: saName = "70Music"; break;
case SpeakerArr::k71Cine: saName = "71Cine"; break;
case SpeakerArr::k71Music: saName = "71Music"; break;
case SpeakerArr::k80Cine: saName = "80Cine"; break;
case SpeakerArr::k80Music: saName = "80Music"; break;
case SpeakerArr::k81Cine: saName = "81Cine"; break;
case SpeakerArr::k81Music: saName = "81Music"; break;
case SpeakerArr::k102: saName = "102"; break;
case SpeakerArr::k122: saName = "122"; break;
case SpeakerArr::k80Cube: saName = "80Cube"; break;
case SpeakerArr::k90: saName = "9.0"; break;
case SpeakerArr::k91: saName = "9.1"; break;
case SpeakerArr::k100: saName = "10.0"; break;
case SpeakerArr::k101: saName = "10.1"; break;
case SpeakerArr::k110: saName = "11.0"; break;
case SpeakerArr::k111: saName = "11.1"; break;
case SpeakerArr::k130: saName = "13.0"; break;
case SpeakerArr::k131: saName = "13.1"; break;
case SpeakerArr::k222: saName = "22.2"; break;
case SpeakerArr::kEmpty: saName = "Empty"; break;
default: saName = "Unknown"; break;
}
return saName;
}
//------------------------------------------------------------------------
const char* SpeakerArrangementTest::getName () const
{
const auto inSaName = getSpeakerArrangementName (inSpArr);
const auto outSaName = getSpeakerArrangementName (outSpArr);
if (inSaName && outSaName)
{
static std::string str;
str = "In: ";
str += inSaName;
str += ": ";
str += std::to_string (SpeakerArr::getChannelCount (inSpArr));
str += " Channels, Out: ";
str += outSaName;
str += ": ";
str += std::to_string (SpeakerArr::getChannelCount (outSpArr));
str += " Channels";
return str.data ();
}
return "error";
}
//------------------------------------------------------------------------
bool SpeakerArrangementTest::prepareProcessing ()
{
if (!vstPlug || !audioEffect)
return false;
bool ret = true;
int32 is = vstPlug->getBusCount (kAudio, kInput);
auto* inSpArrs = new SpeakerArrangement[is];
for (int32 i = 0; i < is; ++i)
inSpArrs[i] = inSpArr;
int32 os = vstPlug->getBusCount (kAudio, kOutput);
auto* outSpArrs = new SpeakerArrangement[os];
for (int32 o = 0; o < os; o++)
outSpArrs[o] = outSpArr;
if (audioEffect->setBusArrangements (inSpArrs, is, outSpArrs, os) != kResultTrue)
ret = false;
// activate only the extra IO (index > 0), the main ones (index 0) were already activated in
// TestBase::setup ()
for (int32 i = 1; i < is; i++)
vstPlug->activateBus (kAudio, kInput, i, true);
for (int32 i = 1; i < os; i++)
vstPlug->activateBus (kAudio, kOutput, i, true);
ret &= ProcessTest::prepareProcessing ();
delete[] inSpArrs;
delete[] outSpArrs;
return ret;
}
//------------------------------------------------------------------------
bool SpeakerArrangementTest::run (ITestResult* testResult)
{
if (!testResult || !audioEffect || !vstPlug)
return false;
printTestHeader (testResult);
SpeakerArrangement spArr = SpeakerArr::kEmpty;
SpeakerArrangement compareSpArr = SpeakerArr::kEmpty;
BusDirections bd = kInput;
BusInfo busInfo = {};
int32 count = 0;
do
{
count++;
int32 numBusses = 0;
if (bd == kInput)
{
numBusses = processData.numInputs;
compareSpArr = inSpArr;
}
else
{
numBusses = processData.numOutputs;
compareSpArr = outSpArr;
}
for (int32 i = 0; i < numBusses; ++i)
{
if (audioEffect->getBusArrangement (bd, i, spArr) != kResultTrue)
{
addErrorMessage (testResult,
STR ("IAudioProcessor::getBusArrangement (..) failed."));
return false;
}
if (spArr != compareSpArr)
{
addMessage (
testResult,
printf (" %s %sSpeakerArrangement is not supported. Plug-in suggests: %s.",
getSpeakerArrangementName (compareSpArr),
bd == kInput ? "Input-" : "Output-",
getSpeakerArrangementName (spArr)));
}
if (vstPlug->getBusInfo (kAudio, bd, i, busInfo) != kResultTrue)
{
addErrorMessage (testResult, STR ("IComponent::getBusInfo (..) failed."));
return false;
}
if (spArr == compareSpArr &&
SpeakerArr::getChannelCount (spArr) != busInfo.channelCount)
{
addErrorMessage (
testResult,
STR ("SpeakerArrangement mismatch (BusInfo::channelCount inconsistency)."));
return false;
}
}
bd = kOutput;
} while (count < 2);
bool ret = true;
// not a Pb ret &= verifySA (processData.numInputs, processData.inputs, inSpArr, testResult);
// not a Pb ret &= verifySA (processData.numOutputs, processData.outputs, outSpArr, testResult);
ret &= ProcessTest::run (testResult);
return ret;
}
//------------------------------------------------------------------------
bool SpeakerArrangementTest::verifySA (int32 numBusses, AudioBusBuffers* buses,
SpeakerArrangement spArr, ITestResult* testResult)
{
if (!testResult || !buses)
return false;
for (int32 i = 0; i < numBusses; ++i)
{
if (buses[i].numChannels != SpeakerArr::getChannelCount (spArr))
{
addErrorMessage (testResult, STR ("ChannelCount is not matching SpeakerArrangement."));
return false;
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,55 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/speakerarrangement.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Speaker Arrangement.
* \ingroup TestClass
*/
class SpeakerArrangementTest : public ProcessTest
{
public:
SpeakerArrangementTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl,
SpeakerArrangement inSpArr, SpeakerArrangement outSpArr);
const char* getName () const SMTG_OVERRIDE;
static const char* getSpeakerArrangementName (SpeakerArrangement spArr);
// ITest
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
bool prepareProcessing () SMTG_OVERRIDE;
bool verifySA (int32 numBusses, AudioBusBuffers* buses, SpeakerArrangement spArr,
ITestResult* testResult);
private:
SpeakerArrangement inSpArr;
SpeakerArrangement outSpArr;
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/variableblocksize.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/processing/variableblocksize.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// VariableBlockSizeTest
//------------------------------------------------------------------------
VariableBlockSizeTest::VariableBlockSizeTest (ITestPlugProvider* plugProvider,
ProcessSampleSize sampl)
: ProcessTest (plugProvider, sampl)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API VariableBlockSizeTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
audioEffect->setProcessing (true);
for (int32 i = 0; i <= TestDefaults::instance ().numIterations; ++i)
{
int32 sampleFrames = rand () % processSetup.maxSamplesPerBlock;
processData.numSamples = sampleFrames;
if (i == 0)
processData.numSamples = 0;
#if defined(TOUGHTESTS) && TOUGHTESTS
else if (i == 1)
processData.numSamples = -50000;
else if (i == 2)
processData.numSamples = processSetup.maxSamplesPerBlock * 2;
#endif // TOUGHTESTS
tresult result = audioEffect->process (processData);
if ((result != kResultOk)
#if defined(TOUGHTESTS) && TOUGHTESTS
&& (i > 1)
#else
&& (i > 0)
#endif // TOUGHTESTS
)
{
addErrorMessage (
testResult,
printf ("The component failed to process an audioblock of size %i", sampleFrames));
audioEffect->setProcessing (false);
return false;
}
}
audioEffect->setProcessing (false);
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/processing/variableblocksize.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Variable Block Size.
* \ingroup TestClass
*/
class VariableBlockSizeTest : public ProcessTest
{
public:
VariableBlockSizeTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Variable Block Size")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,148 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/bypassstate.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/state/bypasspersistence.h"
#include "public.sdk/source/common/memorystream.h"
#include "public.sdk/source/vst/vstpresetfile.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// VstBypassSaveParamTest
//------------------------------------------------------------------------
BypassPersistenceTest::BypassPersistenceTest (ITestPlugProvider* plugProvider,
ProcessSampleSize sampl)
: AutomationTest (plugProvider, sampl, 100, 1, false)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API BypassPersistenceTest::run (ITestResult* testResult)
{
if (!vstPlug || !testResult || !audioEffect)
return false;
if (!canProcessSampleSize (testResult))
return true;
printTestHeader (testResult);
if (bypassId == kNoParamId)
{
testResult->addMessage (STR ("This plugin does not have a bypass parameter!!!"));
return true;
}
unprepareProcessing ();
processData.numSamples = 0;
processData.numInputs = 0;
processData.numOutputs = 0;
processData.inputs = nullptr;
processData.outputs = nullptr;
audioEffect->setProcessing (true);
preProcess (testResult);
// set bypass on
// if (paramChanges[0].getParameterId () == bypassId)
{
paramChanges[0]->init (bypassId, 1);
paramChanges[0]->setPoint (0, 0, 1);
controller->setParamNormalized (bypassId, 1);
if (controller->getParamNormalized (bypassId) < 1)
{
testResult->addErrorMessage (STR ("The bypass parameter was not correctly set!"));
}
}
// flush
tresult result = audioEffect->process (processData);
if (result != kResultOk)
{
testResult->addErrorMessage (
STR ("The component failed to process without audio buffers!"));
audioEffect->setProcessing (false);
return false;
}
postProcess (testResult);
audioEffect->setProcessing (false);
// save State
FUID uid;
plugProvider->getComponentUID (uid);
MemoryStream stream;
PresetFile::savePreset (&stream, uid, vstPlug, controller, nullptr, 0);
audioEffect->setProcessing (true);
preProcess (testResult);
// set bypass off
if (paramChanges[0]->getParameterId () == bypassId)
{
paramChanges[0]->init (bypassId, 1);
paramChanges[0]->setPoint (0, 0, 0);
controller->setParamNormalized (bypassId, 0);
if (controller->getParamNormalized (bypassId) > 0)
{
testResult->addErrorMessage (
STR ("The bypass parameter was not correctly set in the controller!"));
}
}
// flush
result = audioEffect->process (processData);
if (result != kResultOk)
{
testResult->addErrorMessage (
STR ("The component failed to process without audio buffers!"));
audioEffect->setProcessing (false);
return false;
}
postProcess (testResult);
audioEffect->setProcessing (false);
// load previous preset
stream.seek (0, IBStream::kIBSeekSet, nullptr);
PresetFile::loadPreset (&stream, uid, vstPlug, controller);
if (controller->getParamNormalized (bypassId) < 1)
{
testResult->addErrorMessage (
STR ("The bypass parameter is not in sync in the controller!"));
return false;
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/bypassstate.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/automation.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Parameter Bypass persistence.
* \ingroup TestClass
*/
class BypassPersistenceTest : public AutomationTest
{
public:
BypassPersistenceTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) override;
DECLARE_VSTTEST ("Parameter Bypass persistence")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,96 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/invalidstatetransition.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/state/invalidstatetransition.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// InvalidStateTransitionTest
//------------------------------------------------------------------------
InvalidStateTransitionTest::InvalidStateTransitionTest (ITestPlugProvider* plugProvider)
: TestEnh (plugProvider, kSample32)
{
}
//------------------------------------------------------------------------
bool PLUGIN_API InvalidStateTransitionTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
auto plugBase = U::cast<IPluginBase> (vstPlug);
if (!plugBase)
return false;
// created
tresult result = plugBase->initialize (TestingPluginContext::get ());
if (result == kResultFalse)
return false;
// setupProcessing is missing !
/*result = audioEffect->setupProcessing (processSetup);
if (result != kResultTrue)
return false;*/
// initialized
result = vstPlug->setActive (false);
if (result == kResultOk)
return false;
result = vstPlug->setActive (true);
if (result == kResultFalse)
return false;
// allocated
result = plugBase->initialize (TestingPluginContext::get ());
if (result == kResultOk)
return false;
result = vstPlug->setActive (false);
if (result == kResultFalse)
return false;
// deallocated (initialized)
result = plugBase->initialize (TestingPluginContext::get ());
if (result == kResultOk)
return false;
result = plugBase->terminate ();
if (result == kResultFalse)
return false;
// terminated (created)
result = vstPlug->setActive (false);
if (result == kResultOk)
return false;
result = plugBase->terminate ();
if (result == kResultOk)
return false;
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/invalidstatetransition.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Invalid State Transition.
* \ingroup TestClass
*/
class InvalidStateTransitionTest : public TestEnh
{
public:
InvalidStateTransitionTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Invalid State Transition")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,87 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/repeatidenticalstatetransition.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/state/repeatidenticalstatetransition.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// RepeatIdenticalStateTransitionTest
//------------------------------------------------------------------------
RepeatIdenticalStateTransitionTest::RepeatIdenticalStateTransitionTest (
ITestPlugProvider* plugProvider)
: TestEnh (plugProvider, kSample32)
{
}
//------------------------------------------------------------------------
bool RepeatIdenticalStateTransitionTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug || !audioEffect)
return false;
printTestHeader (testResult);
auto plugBase = U::cast<IPluginBase> (vstPlug);
if (!plugBase)
return false;
tresult result = plugBase->initialize (TestingPluginContext::get ());
if (result != kResultFalse)
return false;
result = audioEffect->setupProcessing (processSetup);
if (result != kResultTrue)
return false;
result = vstPlug->setActive (true);
if (result != kResultOk)
return false;
result = vstPlug->setActive (true);
if (result != kResultFalse)
return false;
result = vstPlug->setActive (false);
if (result != kResultOk)
return false;
result = vstPlug->setActive (false);
if (result == kResultOk)
return false;
result = plugBase->terminate ();
if (result != kResultOk)
return false;
result = plugBase->terminate ();
if (result == kResultOk)
return false;
result = plugBase->initialize (TestingPluginContext::get ());
if (result != kResultOk)
return false;
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/repeatidenticalstatetransition.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Repeat Identical State Transition.
* \ingroup TestClass
*/
class RepeatIdenticalStateTransitionTest : public TestEnh
{
public:
RepeatIdenticalStateTransitionTest (ITestPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
DECLARE_VSTTEST ("Repeat Identical State Transition")
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,95 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/validstatetransition.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/state/validstatetransition.h"
#include "pluginterfaces/base/funknownimpl.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ValidStateTransitionTest
//------------------------------------------------------------------------
ValidStateTransitionTest::ValidStateTransitionTest (ITestPlugProvider* plugProvider,
ProcessSampleSize sampleSize)
: ProcessTest (plugProvider, sampleSize)
{
if (sampleSize == kSample32)
strcpy (name, "Valid State Transition 32bits");
else
strcpy (name, "Valid State Transition 64bits");
}
//------------------------------------------------------------------------
bool PLUGIN_API ValidStateTransitionTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug || !audioEffect)
return false;
printTestHeader (testResult);
if (!canProcessSampleSize (testResult))
return true;
// disable it, it was enabled in setup call
tresult result = vstPlug->setActive (false);
if (result != kResultTrue)
return false;
auto plugBase = U::cast<IPluginBase> (vstPlug);
if (!plugBase)
return false;
for (int32 i = 0; i < 4; ++i)
{
result = audioEffect->setupProcessing (processSetup);
if (result != kResultTrue)
return false;
result = vstPlug->setActive (true);
if (result != kResultTrue)
return false;
result = vstPlug->setActive (false);
if (result != kResultTrue)
return false;
if (activateMainIOBusses (false) == false)
return false;
result = plugBase->terminate ();
if (result != kResultTrue)
return false;
result = plugBase->initialize (TestingPluginContext::get ());
if (result != kResultTrue)
return false;
// for the last 2 steps we decide to not reenable the buses, see
// https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Change+History/3.0.0/Multiple+Dynamic+IO.html?highlight=kDefaultActive#information-about-busses
if (i < 2)
{
if (activateMainIOBusses (true) == false)
return false;
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/state/validstatetransition.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/processing/process.h"
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Valid State Transition.
* \ingroup TestClass
*/
class ValidStateTransitionTest : public ProcessTest
{
public:
ValidStateTransitionTest (ITestPlugProvider* plugProvider, ProcessSampleSize sampleSize);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
const char* getName () const SMTG_OVERRIDE { return name; }
protected:
char name[256];
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,298 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/testbase.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/testbase.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include <cstdarg>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// TestBase
//------------------------------------------------------------------------
TestBase::TestBase (ITestPlugProvider* plugProvider)
: plugProvider (plugProvider)
, vstPlug (nullptr)
, controller (nullptr) {FUNKNOWN_CTOR}
//------------------------------------------------------------------------
TestBase::TestBase ()
: plugProvider (nullptr)
, vstPlug (nullptr)
, controller (nullptr) {FUNKNOWN_CTOR}
//------------------------------------------------------------------------
TestBase::~TestBase () {FUNKNOWN_DTOR}
//------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (TestBase, ITest, ITest::iid);
//------------------------------------------------------------------------
bool TestBase::setup ()
{
if (plugProvider)
{
vstPlug = plugProvider->getComponent ();
if (!vstPlug)
return false;
controller = plugProvider->getController ();
return activateMainIOBusses (true);
}
return false;
}
//------------------------------------------------------------------------
bool TestBase::teardown ()
{
if (vstPlug)
{
activateMainIOBusses (false);
plugProvider->releasePlugIn (vstPlug, controller);
}
return true;
}
//------------------------------------------------------------------------
bool TestBase::activateMainIOBusses (bool val)
{
if (!vstPlug)
return false;
bool result = true;
if (auto countIn = vstPlug->getBusCount (kAudio, kInput) > 0)
{
if (vstPlug->activateBus (kAudio, kInput, 0, val) == kResultFalse)
result = false;
}
if (auto countOut = vstPlug->getBusCount (kAudio, kOutput) > 0)
{
if (vstPlug->activateBus (kAudio, kOutput, 0, val) == kResultFalse)
result = false;
}
return result;
}
//------------------------------------------------------------------------
void TestBase::printTestHeader (ITestResult* testResult)
{
using StringConvert::convert;
std::string str = "===";
str += getName ();
str += " ====================================";
addMessage (testResult, convert (str));
}
//------------------------------------------------------------------------
// Component Initialize / Terminate
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// VstTestEnh
//------------------------------------------------------------------------
TestEnh::TestEnh (ITestPlugProvider* plugProvider, ProcessSampleSize sampl)
: TestBase (plugProvider), audioEffect (nullptr)
{
// process setup defaults
memset (&processSetup, 0, sizeof (ProcessSetup));
processSetup.processMode = kRealtime;
processSetup.symbolicSampleSize = sampl;
processSetup.maxSamplesPerBlock = kMaxSamplesPerBlock;
processSetup.sampleRate = kSampleRate;
}
//------------------------------------------------------------------------
TestEnh::~TestEnh ()
{
}
//------------------------------------------------------------------------
bool TestEnh::setup ()
{
bool res = TestBase::setup ();
if (vstPlug)
{
tresult check = vstPlug->queryInterface (IAudioProcessor::iid, (void**)&audioEffect);
if (check != kResultTrue)
return false;
}
return (res && audioEffect);
}
//------------------------------------------------------------------------
bool TestEnh::teardown ()
{
if (audioEffect)
audioEffect->release ();
bool res = TestBase::teardown ();
return res && audioEffect;
}
//------------------------------------------------------------------------
void addMessage (ITestResult* testResult, const std::u16string& str)
{
testResult->addMessage (reinterpret_cast<const tchar*> (str.data ()));
}
//------------------------------------------------------------------------
void addMessage (ITestResult* testResult, const tchar* str)
{
testResult->addMessage (str);
}
//------------------------------------------------------------------------
void addErrorMessage (ITestResult* testResult, const tchar* str)
{
testResult->addErrorMessage (str);
}
//------------------------------------------------------------------------
void addErrorMessage (ITestResult* testResult, const std::u16string& str)
{
testResult->addErrorMessage (reinterpret_cast<const tchar*> (str.data ()));
}
//------------------------------------------------------------------------
std::u16string printf (const char8* format, ...)
{
using StringConvert::convert;
char8 string[1024 * 4];
va_list marker;
va_start (marker, format);
vsnprintf (string, kPrintfBufferSize, format, marker);
return convert (string);
}
IMPLEMENT_FUNKNOWN_METHODS (ParamChanges, IParamValueQueue, IParamValueQueue::iid)
//------------------------------------------------------------------------
ParamChanges::ParamChanges () {FUNKNOWN_CTOR}
//------------------------------------------------------------------------
ParamChanges::~ParamChanges ()
{
if (points)
delete[] points;
FUNKNOWN_DTOR
}
//------------------------------------------------------------------------
void ParamChanges::init (ParamID _id, int32 _numPoints)
{
id = _id;
numPoints = _numPoints;
numUsedPoints = 0;
if (points)
delete[] points;
points = new ParamPoint[numPoints];
processedFrames = 0;
}
//------------------------------------------------------------------------
bool ParamChanges::setPoint (int32 index, int32 offsetSamples, double value)
{
if (points && (index >= 0) && (index == numUsedPoints) && (index < numPoints))
{
points[index].set (offsetSamples, value);
numUsedPoints++;
return true;
}
if (!points)
return true;
return false;
}
//------------------------------------------------------------------------
void ParamChanges::resetPoints ()
{
numUsedPoints = 0;
processedFrames = 0;
}
//------------------------------------------------------------------------
int32 ParamChanges::getProcessedFrames () const
{
return processedFrames;
}
//------------------------------------------------------------------------
void ParamChanges::setProcessedFrames (int32 amount)
{
processedFrames = amount;
}
//------------------------------------------------------------------------
bool ParamChanges::havePointsBeenRead (bool atAll)
{
for (int32 i = 0; i < getPointCount (); ++i)
{
if (points[i].wasRead ())
{
if (atAll)
return true;
}
else if (!atAll)
return false;
}
return !atAll;
}
//------------------------------------------------------------------------
ParamID PLUGIN_API ParamChanges::getParameterId ()
{
return id;
}
//------------------------------------------------------------------------
int32 PLUGIN_API ParamChanges::getPointCount ()
{
return numUsedPoints;
}
//------------------------------------------------------------------------
tresult PLUGIN_API ParamChanges::getPoint (int32 index, int32& offsetSamples, double& value)
{
if (points && (index < numUsedPoints) && (index >= 0))
{
points[index].get (offsetSamples, value);
return kResultTrue;
}
return kResultFalse;
}
//------------------------------------------------------------------------
tresult PLUGIN_API ParamChanges::addPoint (int32 /*offsetSamples*/, double /*value*/,
int32& /*index*/)
{
return kResultFalse;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,229 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/testbase.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "pluginterfaces/test/itest.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include "pluginterfaces/vst/ivsttestplugprovider.h"
#include <atomic>
#include <cstdlib>
#include <string>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
void addMessage (ITestResult* testResult, const std::u16string& str);
void addMessage (ITestResult* testResult, const tchar* str);
void addErrorMessage (ITestResult* testResult, const tchar* str);
void addErrorMessage (ITestResult* testResult, const std::u16string& str);
std::u16string printf (const char8* format, ...);
//------------------------------------------------------------------------
#define DECLARE_VSTTEST(name) \
const char* getName () const SMTG_OVERRIDE { return name; }
//------------------------------------------------------------------------
struct TestingPluginContext
{
static FUnknown* get () { return instance ().context; }
static void set (FUnknown* context) { instance ().context = context; }
private:
static TestingPluginContext& instance ()
{
static TestingPluginContext gInstance;
return gInstance;
}
FUnknown* context {nullptr};
};
//------------------------------------------------------------------------
struct TestDefaults
{
int32 numIterations {20};
int32 defaultSampleRate {44100};
int32 defaultBlockSize {64};
int32 maxBlockSize {8192};
int32 buffersAreEqual {0};
int32 numAudioBlocksToProcess {3};
uint64 channelIsSilent {1};
static TestDefaults& instance ()
{
static TestDefaults gInstance;
return gInstance;
}
};
//------------------------------------------------------------------------
/** Test Helper.
* \ingroup TestClass
*/
class TestBase : public ITest
{
public:
TestBase (ITestPlugProvider* plugProvider);
virtual ~TestBase ();
virtual const char* getName () const = 0;
DECLARE_FUNKNOWN_METHODS
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* /*testResult*/) SMTG_OVERRIDE = 0;
bool PLUGIN_API teardown () SMTG_OVERRIDE;
virtual bool activateMainIOBusses (bool val);
virtual void printTestHeader (ITestResult* testResult);
//------------------------------------------------------------------------
protected:
ITestPlugProvider* plugProvider;
IComponent* vstPlug;
IEditController* controller;
private:
TestBase ();
};
using ProcessSampleSize = int32;
//------------------------------------------------------------------------
/** Test Helper.
* \ingroup TestClass
*/
class TestEnh : public TestBase
{
public:
TestEnh (ITestPlugProvider* plugProvider, ProcessSampleSize sampl);
~TestEnh () override;
enum AudioDefaults
{
kBlockSize = 64,
kMaxSamplesPerBlock = 8192,
kSampleRate = 44100,
};
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API teardown () SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
// interfaces
IAudioProcessor* audioEffect;
ProcessSetup processSetup;
};
//------------------------------------------------------------------------
/** AutomationTest helper classes.
* \ingroup TestClass
*/
class ParamPoint
{
public:
ParamPoint () : offsetSamples (-1), value (0.), read (false) {}
void set (int32 _offsetSamples, double _value)
{
offsetSamples = _offsetSamples;
value = _value;
}
void get (int32& _offsetSamples, double& _value)
{
_offsetSamples = offsetSamples;
_value = value;
read = true;
}
bool wasRead () const { return read; }
private:
int32 offsetSamples;
double value;
bool read;
};
//------------------------------------------------------------------------
/** AutomationTest helper classes: implementation of IParamValueQueue.
* \ingroup TestClass
*/
class ParamChanges : public IParamValueQueue
{
public:
DECLARE_FUNKNOWN_METHODS
ParamChanges ();
virtual ~ParamChanges ();
void init (ParamID _id, int32 _numPoints);
bool setPoint (int32 index, int32 offsetSamples, double value);
void resetPoints ();
int32 getProcessedFrames () const;
void setProcessedFrames (int32 amount);
bool havePointsBeenRead (bool atAll);
//---for IParamValueQueue-------------------------
ParamID PLUGIN_API getParameterId () SMTG_OVERRIDE;
int32 PLUGIN_API getPointCount () SMTG_OVERRIDE;
tresult PLUGIN_API getPoint (int32 index, int32& offsetSamples, double& value) SMTG_OVERRIDE;
tresult PLUGIN_API addPoint (int32 /*offsetSamples*/, double /*value*/,
int32& /*index*/) SMTG_OVERRIDE;
//---------------------------------------------------------
private:
ParamID id = kNoParamId;
int32 numPoints = 0;
int32 numUsedPoints = 0;
int32 processedFrames = 0;
ParamPoint* points = nullptr;
};
//------------------------------------------------------------------------
class StringResult final : public IStringResult
{
public:
const std::string& get () const { return data; }
void PLUGIN_API setText (const char8* text) override { data = text; }
tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) override
{
QUERY_INTERFACE (_iid, obj, FUnknown::iid, IStringResult)
QUERY_INTERFACE (_iid, obj, IStringResult::iid, IStringResult)
*obj = nullptr;
return kNoInterface;
}
uint32 PLUGIN_API addRef () override { return ++__refCount; }
uint32 PLUGIN_API release () override
{
if (--__refCount == 0)
{
delete this;
return 0;
}
return __refCount;
}
private:
std::string data;
std::atomic<uint32> __refCount {0};
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,119 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/unit/checkunitstructure.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/unit/checkunitstructure.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstunits.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// UnitStructureTest
//------------------------------------------------------------------------
UnitStructureTest::UnitStructureTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool UnitStructureTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (auto iUnitInfo = U::cast<IUnitInfo> (controller))
{
int32 unitCount = iUnitInfo->getUnitCount ();
if (unitCount <= 0)
{
addMessage (testResult,
STR ("No units found, while controller implements IUnitInfo !!!"));
}
UnitInfo unitInfo = {};
UnitInfo tmpInfo = {};
bool rootFound = false;
for (int32 unitIndex = 0; unitIndex < unitCount; unitIndex++)
{
if (iUnitInfo->getUnitInfo (unitIndex, unitInfo) == kResultOk)
{
// check parent Id
if (unitInfo.parentUnitId != kNoParentUnitId) //-1: connected to root
{
bool noParent = true;
for (int32 i = 0; i < unitCount; ++i)
{
if (iUnitInfo->getUnitInfo (i, tmpInfo) == kResultOk)
{
if (unitInfo.parentUnitId == tmpInfo.id)
{
noParent = false;
break;
}
}
}
if (noParent && unitInfo.parentUnitId != kRootUnitId)
{
addErrorMessage (
testResult, printf ("Unit %03d: Parent does not exist!!", unitInfo.id));
return false;
}
}
else if (!rootFound)
{
// root Unit have always the rootID
if (unitInfo.id != kRootUnitId)
{
// we should have a root unit id
addErrorMessage (
testResult,
printf ("Unit %03d: Should be the Root Unit => id should be %03d!!",
unitInfo.id, kRootUnitId));
return false;
}
rootFound = true;
}
else
{
addErrorMessage (
testResult,
printf ("Unit %03d: Has no parent, but there is a root already.",
unitInfo.id));
return false;
}
}
else
{
addErrorMessage (testResult, printf ("Unit %03d: No unit info.", unitInfo.id));
return false;
}
}
addMessage (testResult, STR ("All units have valid parent IDs."));
}
else
{
addMessage (testResult, STR ("This component does not support IUnitInfo!"));
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/unit/checkunitstructure.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Check Unit Structure.
* \ingroup TestClass
*/
class UnitStructureTest : public TestBase
{
public:
UnitStructureTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Check Unit Structure")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,198 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/unit/scanprograms.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/unit/scanprograms.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstunits.h"
#include "pluginterfaces/vst/vstpresetkeys.h"
#include <memory>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// ProgramInfoTest
//------------------------------------------------------------------------
ProgramInfoTest::ProgramInfoTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool ProgramInfoTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (auto iUnitInfo = U::cast<IUnitInfo> (controller))
{
int32 programListCount = iUnitInfo->getProgramListCount ();
if (programListCount == 0)
{
addMessage (testResult, STR ("This component does not export any programs."));
return true;
}
else if (programListCount < 0)
{
addErrorMessage (testResult,
STR ("IUnitInfo::getProgramListCount () returned a negative number."));
return false;
}
// used to check double IDs
auto programListIds = std::unique_ptr<int32[]> (new int32[programListCount]);
for (int32 programListIndex = 0; programListIndex < programListCount; programListIndex++)
{
// get programm list info
ProgramListInfo programListInfo;
if (iUnitInfo->getProgramListInfo (programListIndex, programListInfo) == kResultOk)
{
int32 programListId = programListInfo.id;
programListIds[programListIndex] = programListId;
if (programListId < 0)
{
addErrorMessage (testResult,
printf ("Programlist %03d: Invalid ID!!!", programListIndex));
return false;
}
// check if ID is already used by another parameter
for (int32 idIndex = 0; idIndex < programListIndex; idIndex++)
{
if (programListIds[idIndex] == programListIds[programListIndex])
{
addErrorMessage (testResult, printf ("Programlist %03d: ID already used!!!",
programListIndex));
return false;
}
}
auto programListName = StringConvert::convert (programListInfo.name);
if (programListName.empty ())
{
addErrorMessage (testResult, printf ("Programlist %03d (id=%d): No name!!!",
programListIndex, programListId));
return false;
}
int32 programCount = programListInfo.programCount;
if (programCount <= 0)
{
addMessage (
testResult,
printf (
"Programlist %03d (id=%d): \"%s\" No programs!!! (programCount is null!)",
programListIndex, programListId,
StringConvert::convert (programListName).data ()));
// return false;
}
addMessage (testResult, printf ("Programlist %03d (id=%d): \"%s\" (%d programs).",
programListIndex, programListId,
programListName.data (), programCount));
for (int32 programIndex = 0; programIndex < programCount; programIndex++)
{
TChar programName[256];
if (iUnitInfo->getProgramName (programListId, programIndex, programName) ==
kResultOk)
{
if (programName[0] == 0)
{
addErrorMessage (
testResult,
printf ("Programlist %03d->Program %03d: has no name!!!",
programListIndex, programIndex));
return false;
}
auto programNameUTF8 = StringConvert::convert (programName);
auto msg = printf ("Programlist %03d->Program %03d: \"%s\"",
programListIndex, programIndex, programNameUTF8.data ());
String128 programInfo {};
if (iUnitInfo->getProgramInfo (programListId, programIndex,
PresetAttributes::kInstrument,
programInfo) == kResultOk)
{
auto programInfoUTF8 = StringConvert::convert (programInfo);
msg += StringConvert::convert (" (instrument = \"");
msg += (const char16_t*)programInfo;
msg += StringConvert::convert ("\")");
}
addMessage (testResult, msg.data ());
if (iUnitInfo->hasProgramPitchNames (programListId, programIndex) ==
kResultOk)
{
addMessage (testResult, printf (" => \"%s\": supports PitchNames",
programNameUTF8.data ()));
String128 pitchName = {0};
for (int16 midiPitch = 0; midiPitch < 128; midiPitch++)
{
if (iUnitInfo->getProgramPitchName (programListId, programIndex,
midiPitch,
pitchName) == kResultOk)
{
msg = printf (" => MIDI Pitch %d => \"", midiPitch);
msg += (const char16_t*)pitchName;
msg += StringConvert::convert ("\"");
addMessage (testResult, msg.data ());
}
}
}
}
}
}
}
}
else
{
addMessage (testResult, STR ("This component does not export any programs."));
// check if not more than 1 program change parameter is defined
int32 numPrgChanges = 0;
for (int32 i = 0; i < controller->getParameterCount (); ++i)
{
ParameterInfo paramInfo = {};
if (controller->getParameterInfo (i, paramInfo) != kResultOk)
{
if (paramInfo.flags & ParameterInfo::kIsProgramChange)
numPrgChanges++;
}
}
if (numPrgChanges > 1)
{
addErrorMessage (
testResult,
printf ("More than 1 programChange Parameter (%d) without support of IUnitInfo!!!",
numPrgChanges));
}
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/unit/scanprograms.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Scan Programs.
* \ingroup TestClass
*/
class ProgramInfoTest : public TestBase
{
public:
ProgramInfoTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Scan Programs")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,148 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/unit/scanunits.cpp
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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/vst/testsuite/unit/scanunits.h"
#include "public.sdk/source/vst/utility/stringconvert.h"
#include "pluginterfaces/base/funknownimpl.h"
#include "pluginterfaces/vst/ivstunits.h"
#include <memory>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// UnitInfoTest
//------------------------------------------------------------------------
UnitInfoTest::UnitInfoTest (ITestPlugProvider* plugProvider) : TestBase (plugProvider)
{
}
//------------------------------------------------------------------------
bool UnitInfoTest::run (ITestResult* testResult)
{
if (!testResult || !vstPlug)
return false;
printTestHeader (testResult);
if (auto iUnitInfo = U::cast<IUnitInfo> (controller))
{
int32 unitCount = iUnitInfo->getUnitCount ();
if (unitCount <= 0)
{
addMessage (testResult,
STR ("No units found, while controller implements IUnitInfo !!!"));
}
else
{
addMessage (testResult, printf ("This component has %d unit(s).", unitCount));
}
auto unitIds = std::unique_ptr<int32[]> (new int32[unitCount]);
for (int32 unitIndex = 0; unitIndex < unitCount; unitIndex++)
{
UnitInfo unitInfo = {};
if (iUnitInfo->getUnitInfo (unitIndex, unitInfo) == kResultOk)
{
int32 unitId = unitInfo.id;
unitIds[unitIndex] = unitId;
if (unitId < 0)
{
addErrorMessage (testResult, printf ("Unit %03d: Invalid ID!", unitIndex));
return false;
}
// check if ID is already used by another unit
for (int32 idIndex = 0; idIndex < unitIndex; idIndex++)
{
if (unitIds[idIndex] == unitIds[unitIndex])
{
addErrorMessage (testResult,
printf ("Unit %03d: ID already used!!!", unitIndex));
return false;
}
}
auto unitName = StringConvert::convert (unitInfo.name);
if (unitName.empty ())
{
addErrorMessage (testResult, printf ("Unit %03d: No name!", unitIndex));
return false;
}
int32 parentUnitId = unitInfo.parentUnitId;
if (parentUnitId < -1)
{
addErrorMessage (testResult,
printf ("Unit %03d: Invalid parent ID!", unitIndex));
return false;
}
else if (parentUnitId == unitId)
{
addErrorMessage (
testResult,
printf ("Unit %03d: Parent ID is equal to Unit ID!", unitIndex));
return false;
}
int32 unitProgramListId = unitInfo.programListId;
if (unitProgramListId < -1)
{
addErrorMessage (testResult,
printf ("Unit %03d: Invalid programlist ID!", unitIndex));
return false;
}
addMessage (
testResult,
printf (" Unit%03d (ID = %d): \"%s\" (parent ID = %d, programlist ID = %d)",
unitIndex, unitId, unitName.data (), parentUnitId, unitProgramListId));
// test select Unit
if (iUnitInfo->selectUnit (unitIndex) == kResultTrue)
{
UnitID newSelected = iUnitInfo->getSelectedUnit ();
if (newSelected != unitIndex)
{
addMessage (
testResult,
printf (
"The host has selected Unit ID = %d but getSelectedUnit returns ID = %d!!!",
unitIndex, newSelected));
}
}
}
else
{
addMessage (testResult, printf ("Unit%03d: No unit info!", unitIndex));
}
}
}
else
{
addMessage (testResult, STR ("This component has no units."));
}
return true;
}
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// Flags : clang-format SMTGSequencer
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/unit/scanunits.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/testbase.h"
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
/** Test Scan Units.
* \ingroup TestClass
*/
class UnitInfoTest : public TestBase
{
public:
UnitInfoTest (ITestPlugProvider* plugProvider);
DECLARE_VSTTEST ("Scan Units")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};
//------------------------------------------------------------------------
} // Vst
} // Steinberg
@@ -0,0 +1,186 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/vststructsizecheck.h
// Created by : Steinberg, 09/2010
// Description : struct size test. Checks that struct sizes and alignments do not change after publicly released
//
//-----------------------------------------------------------------------------
// 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 "pluginterfaces/vst/ivstattributes.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivstcomponent.h"
#include "pluginterfaces/vst/ivstcontextmenu.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstevents.h"
#include "pluginterfaces/vst/ivsthostapplication.h"
#include "pluginterfaces/vst/ivstmessage.h"
#include "pluginterfaces/vst/ivstmidicontrollers.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include "pluginterfaces/vst/ivstplugview.h"
#include "pluginterfaces/vst/ivstprocesscontext.h"
#include "pluginterfaces/vst/ivstrepresentation.h"
#include "pluginterfaces/vst/ivstunits.h"
#include "pluginterfaces/vst/vstpresetkeys.h"
#include "pluginterfaces/vst/vsttypes.h"
#include "pluginterfaces/base/typesizecheck.h"
#include <cstdio>
//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
#define SMTG_VST_COMPILE_TIME_STRUCT_CHECK 1
#if SMTG_VST_COMPILE_TIME_STRUCT_CHECK
// ipluginbase.h
SMTG_TYPE_SIZE_CHECK (PFactoryInfo, 452, 452, 452, 452)
SMTG_TYPE_SIZE_CHECK (PClassInfo, 116, 116, 116, 116)
SMTG_TYPE_SIZE_CHECK (PClassInfo2, 440, 440, 440, 440)
SMTG_TYPE_SIZE_CHECK (PClassInfoW, 696, 696, 696, 696)
SMTG_TYPE_ALIGN_CHECK (PFactoryInfo, 4, 4, 4, 4)
SMTG_TYPE_ALIGN_CHECK (PClassInfo, 4, 4, 4, 4)
SMTG_TYPE_ALIGN_CHECK (PClassInfo2, 4, 4, 4, 4)
SMTG_TYPE_ALIGN_CHECK (PClassInfoW, 4, 4, 4, 4)
// ivstaudioprocessor.h
SMTG_TYPE_SIZE_CHECK (ProcessSetup, 24, 20, 24, 24)
SMTG_TYPE_SIZE_CHECK (AudioBusBuffers, 24, 16, 24, 24)
SMTG_TYPE_SIZE_CHECK (ProcessData, 80, 48, 48, 48)
SMTG_TYPE_ALIGN_CHECK (ProcessSetup, 8, 1, 8, 8)
SMTG_TYPE_ALIGN_CHECK (AudioBusBuffers, 8, 1, 8, 8)
SMTG_TYPE_ALIGN_CHECK (ProcessData, 8, 1, 4, 4)
// ivstcomponent.h
SMTG_TYPE_SIZE_CHECK (BusInfo, 276, 276, 276, 276)
SMTG_TYPE_SIZE_CHECK (RoutingInfo, 12, 12, 12, 12)
SMTG_TYPE_ALIGN_CHECK (BusInfo, 4, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (RoutingInfo, 4, 1, 4, 4)
// ivstcontextmenu.h
SMTG_TYPE_SIZE_CHECK (IContextMenuItem, 264, 264, 264, 264)
SMTG_TYPE_ALIGN_CHECK (IContextMenuItem, 4, 1, 4, 4)
// ivsteditcontroller.h
SMTG_TYPE_SIZE_CHECK (ParameterInfo, 792, 792, 792, 792)
SMTG_TYPE_ALIGN_CHECK (ParameterInfo, 8, 1, 8, 8)
// ivstevents.h
SMTG_TYPE_SIZE_CHECK (NoteOnEvent, 20, 20, 20, 20)
SMTG_TYPE_SIZE_CHECK (NoteOffEvent, 16, 16, 16, 16)
SMTG_TYPE_SIZE_CHECK (DataEvent, 16, 12, 12, 12)
SMTG_TYPE_SIZE_CHECK (PolyPressureEvent, 12, 12, 12, 12)
SMTG_TYPE_SIZE_CHECK (ChordEvent, 16, 12, 12, 12)
SMTG_TYPE_SIZE_CHECK (ScaleEvent, 16, 10, 12, 12)
SMTG_TYPE_SIZE_CHECK (LegacyMIDICCOutEvent, 4, 4, 4, 4)
SMTG_TYPE_SIZE_CHECK (Event, 48, 40, 40, 48)
SMTG_TYPE_ALIGN_CHECK (NoteOnEvent, 4, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (NoteOffEvent, 4, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (DataEvent, 8, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (PolyPressureEvent, 4, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (ChordEvent, 8, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (ScaleEvent, 8, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (LegacyMIDICCOutEvent, 1, 1, 1, 1)
SMTG_TYPE_ALIGN_CHECK (Event, 8, 1, 8, 8)
// ivstnoteexpression.h
SMTG_TYPE_SIZE_CHECK (NoteExpressionValueDescription, 32, 28, 32, 32)
SMTG_TYPE_SIZE_CHECK (NoteExpressionValueEvent, 16, 16, 16, 16)
SMTG_TYPE_SIZE_CHECK (NoteExpressionTextEvent, 24, 16, 16, 16)
SMTG_TYPE_SIZE_CHECK (NoteExpressionTypeInfo, 816, 812, 816, 816)
SMTG_TYPE_SIZE_CHECK (KeyswitchInfo, 536, 536, 536, 536)
SMTG_TYPE_ALIGN_CHECK (NoteExpressionValueDescription, 8, 1, 8, 8)
SMTG_TYPE_ALIGN_CHECK (NoteExpressionValueEvent, 8, 1, 4, 8)
SMTG_TYPE_ALIGN_CHECK (NoteExpressionTextEvent, 8, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (NoteExpressionTypeInfo, 8, 1, 8, 8)
SMTG_TYPE_ALIGN_CHECK (KeyswitchInfo, 4, 1, 4, 4)
// ivstprocesscontext.h
SMTG_TYPE_SIZE_CHECK (FrameRate, 8, 8, 8, 8)
SMTG_TYPE_SIZE_CHECK (Chord, 4, 4, 4, 4)
SMTG_TYPE_SIZE_CHECK (ProcessContext, 112, 104, 112, 112)
SMTG_TYPE_ALIGN_CHECK (FrameRate, 4, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (Chord, 2, 1, 2, 2)
SMTG_TYPE_ALIGN_CHECK (ProcessContext, 8, 1, 8, 8)
// ivstrepresentation.h
SMTG_TYPE_SIZE_CHECK (RepresentationInfo, 256, 256, 256, 256)
SMTG_TYPE_ALIGN_CHECK (RepresentationInfo, 1, 1, 1, 1)
// ivstunits.h
SMTG_TYPE_SIZE_CHECK (UnitInfo, 268, 268, 268, 268)
SMTG_TYPE_SIZE_CHECK (ProgramListInfo, 264, 264, 264, 264)
SMTG_TYPE_ALIGN_CHECK (UnitInfo, 4, 1, 4, 4)
SMTG_TYPE_ALIGN_CHECK (ProgramListInfo, 4, 1, 4, 4)
#endif // SMTG_VST_COMPILE_TIME_STRUCT_CHECK
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
#define SMTG_PRINT_TYPE_SIZE_ALIGN(T) \
{ \
auto len = strlen (#T); \
std::printf (#T); \
for (auto i = len; i < 35; ++i) \
std::printf (" "); \
std::printf ("size = %3zu | align = %2zu\n", sizeof (T), alignof (T)); \
}
//------------------------------------------------------------------------
inline void printStructSizes ()
{
// ipluginbase.h
SMTG_PRINT_TYPE_SIZE_ALIGN (PFactoryInfo);
SMTG_PRINT_TYPE_SIZE_ALIGN (PClassInfo);
SMTG_PRINT_TYPE_SIZE_ALIGN (PClassInfo2);
SMTG_PRINT_TYPE_SIZE_ALIGN (PClassInfoW);
// ivstaudioprocessor.h
SMTG_PRINT_TYPE_SIZE_ALIGN (ProcessSetup);
SMTG_PRINT_TYPE_SIZE_ALIGN (AudioBusBuffers);
SMTG_PRINT_TYPE_SIZE_ALIGN (ProcessData);
// ivstcomponent.h
SMTG_PRINT_TYPE_SIZE_ALIGN (BusInfo);
SMTG_PRINT_TYPE_SIZE_ALIGN (RoutingInfo);
// ivstcontextmenu.h
SMTG_PRINT_TYPE_SIZE_ALIGN (IContextMenuItem);
// ivsteditcontroller.h
SMTG_PRINT_TYPE_SIZE_ALIGN (ParameterInfo);
// ivstevents.h
SMTG_PRINT_TYPE_SIZE_ALIGN (NoteOnEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (NoteOffEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (DataEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (PolyPressureEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (ChordEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (ScaleEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (LegacyMIDICCOutEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (Event);
// ivstnoteexpression.h
SMTG_PRINT_TYPE_SIZE_ALIGN (NoteExpressionValueDescription);
SMTG_PRINT_TYPE_SIZE_ALIGN (NoteExpressionValueEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (NoteExpressionTextEvent);
SMTG_PRINT_TYPE_SIZE_ALIGN (NoteExpressionTypeInfo);
SMTG_PRINT_TYPE_SIZE_ALIGN (KeyswitchInfo);
// ivstprocesscontext.h
SMTG_PRINT_TYPE_SIZE_ALIGN (FrameRate);
SMTG_PRINT_TYPE_SIZE_ALIGN (Chord);
SMTG_PRINT_TYPE_SIZE_ALIGN (ProcessContext);
// ivstrepresentation.h
SMTG_PRINT_TYPE_SIZE_ALIGN (RepresentationInfo);
// ivstunits.h
SMTG_PRINT_TYPE_SIZE_ALIGN (UnitInfo);
SMTG_PRINT_TYPE_SIZE_ALIGN (ProgramListInfo);
}
//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg
@@ -0,0 +1,15 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/vsttestsuite.cpp
// Created by : Steinberg, 10/2005
// Description : VST Hosting Utilities
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
@@ -0,0 +1,51 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/testsuite/vsttestsuite.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#pragma once
#include "public.sdk/source/vst/testsuite/bus/busactivation.h"
#include "public.sdk/source/vst/testsuite/bus/busconsistency.h"
#include "public.sdk/source/vst/testsuite/bus/businvalidindex.h"
#include "public.sdk/source/vst/testsuite/bus/checkaudiobusarrangement.h"
#include "public.sdk/source/vst/testsuite/bus/scanbusses.h"
#include "public.sdk/source/vst/testsuite/bus/sidechainarrangement.h"
#include "public.sdk/source/vst/testsuite/general/editorclasses.h"
#include "public.sdk/source/vst/testsuite/general/midilearn.h"
#include "public.sdk/source/vst/testsuite/general/midimapping.h"
#include "public.sdk/source/vst/testsuite/general/parameterfunctionname.h"
#include "public.sdk/source/vst/testsuite/general/scanparameters.h"
#include "public.sdk/source/vst/testsuite/general/suspendresume.h"
#include "public.sdk/source/vst/testsuite/general/terminit.h"
#include "public.sdk/source/vst/testsuite/noteexpression/keyswitch.h"
#include "public.sdk/source/vst/testsuite/noteexpression/noteexpression.h"
#include "public.sdk/source/vst/testsuite/processing/automation.h"
#include "public.sdk/source/vst/testsuite/processing/process.h"
#include "public.sdk/source/vst/testsuite/processing/processcontextrequirements.h"
#include "public.sdk/source/vst/testsuite/processing/processformat.h"
#include "public.sdk/source/vst/testsuite/processing/processinputoverwriting.h"
#include "public.sdk/source/vst/testsuite/processing/processtail.h"
#include "public.sdk/source/vst/testsuite/processing/processthreaded.h"
#include "public.sdk/source/vst/testsuite/processing/silenceflags.h"
#include "public.sdk/source/vst/testsuite/processing/silenceprocessing.h"
#include "public.sdk/source/vst/testsuite/processing/speakerarrangement.h"
#include "public.sdk/source/vst/testsuite/processing/variableblocksize.h"
#include "public.sdk/source/vst/testsuite/state/bypasspersistence.h"
#include "public.sdk/source/vst/testsuite/state/invalidstatetransition.h"
#include "public.sdk/source/vst/testsuite/state/repeatidenticalstatetransition.h"
#include "public.sdk/source/vst/testsuite/state/validstatetransition.h"
#include "public.sdk/source/vst/testsuite/unit/checkunitstructure.h"
#include "public.sdk/source/vst/testsuite/unit/scanprograms.h"
#include "public.sdk/source/vst/testsuite/unit/scanunits.h"