1 //-----------------------------------------------------------------------------
2 // Project     : VST SDK
3 //
4 // Category    : Examples
5 // Filename    : public.sdk/samples/vst/hostchecker/source/hostcheck.cpp
6 // Created by  : Steinberg, 04/2012
7 // Description :
8 //
9 //-----------------------------------------------------------------------------
10 // LICENSE
11 // (c) 2020, Steinberg Media Technologies GmbH, All Rights Reserved
12 //-----------------------------------------------------------------------------
13 // Redistribution and use in source and binary forms, with or without modification,
14 // are permitted provided that the following conditions are met:
15 //
16 //   * Redistributions of source code must retain the above copyright notice,
17 //     this list of conditions and the following disclaimer.
18 //   * Redistributions in binary form must reproduce the above copyright notice,
19 //     this list of conditions and the following disclaimer in the documentation
20 //     and/or other materials provided with the distribution.
21 //   * Neither the name of the Steinberg Media Technologies nor the names of its
22 //     contributors may be used to endorse or promote products derived from this
23 //     software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 // OF THE POSSIBILITY OF SUCH DAMAGE.
35 //-----------------------------------------------------------------------------
36 
37 #include "hostcheck.h"
38 #include "logevents.h"
39 #include "pluginterfaces/vst/ivstaudioprocessor.h"
40 #include "pluginterfaces/vst/ivstevents.h"
41 #include "pluginterfaces/vst/ivstnoteexpression.h"
42 #include "pluginterfaces/vst/ivstparameterchanges.h"
43 
44 //------------------------------------------------------------------------
HostCheck()45 HostCheck::HostCheck ()
46 {
47 	mProcessSetupCheck.setEventLogger (&mEventLogger);
48 	mProcessContextCheck.setEventLogger (&mEventLogger);
49 	mEventListCheck.setEventLogger (&mEventLogger);
50 	mParamChangesCheck.setEventLogger (&mEventLogger);
51 	mParamChangesCheck.setParamIDs (&mParameterIds);
52 }
53 
54 //------------------------------------------------------------------------
addParameter(Steinberg::Vst::ParamID paramId)55 void HostCheck::addParameter (Steinberg::Vst::ParamID paramId)
56 {
57 	mParameterIds.insert (paramId);
58 }
59 
60 //------------------------------------------------------------------------
addLogEvent(Steinberg::int32 logId)61 void HostCheck::addLogEvent (Steinberg::int32 logId)
62 {
63 	mEventLogger.addLogEvent (logId);
64 }
65 
66 //------------------------------------------------------------------------
validate(Steinberg::Vst::ProcessData & data,Steinberg::int32 minInputBufferCount,Steinberg::int32 minOutputBufferCount)67 bool HostCheck::validate (Steinberg::Vst::ProcessData& data, Steinberg::int32 minInputBufferCount,
68                           Steinberg::int32 minOutputBufferCount)
69 {
70 	mProcessSetupCheck.check (data);
71 	mProcessContextCheck.check (data.processContext);
72 	mEventListCheck.check (data.inputEvents);
73 	mParamChangesCheck.checkParameterChanges (data.inputParameterChanges);
74 
75 	checkAudioBuffers (data.inputs, data.numInputs, Steinberg::Vst::kInput, data.symbolicSampleSize, minInputBufferCount);
76 	checkAudioBuffers (data.outputs, data.numOutputs, Steinberg::Vst::kOutput, data.symbolicSampleSize, minOutputBufferCount);
77 
78 	return mEventLogger.empty ();
79 }
80 
81 //------------------------------------------------------------------------
checkAudioBuffers(Steinberg::Vst::AudioBusBuffers * buffers,Steinberg::int32 numBuffers,Steinberg::Vst::BusDirection dir,Steinberg::int32 symbolicSampleSize,Steinberg::int32 minBufferCount)82 void HostCheck::checkAudioBuffers (Steinberg::Vst::AudioBusBuffers* buffers,
83                                    Steinberg::int32 numBuffers, Steinberg::Vst::BusDirection dir,
84                                    Steinberg::int32 symbolicSampleSize, Steinberg::int32 minBufferCount)
85 {
86 	if (mComponent)
87 	{
88 		if (numBuffers > 0)
89 		{
90 			//Steinberg::int32 audioBusCount = mComponent->getBusCount (Steinberg::Vst::kAudio, dir);
91 			bool isValid = minBufferCount <= numBuffers;
92 			if (!isValid)
93 			{
94 				addLogEvent (kLogIdAudioBufNotMatchComponentBusCount);
95 			}
96 		}
97 	}
98 
99 	if (numBuffers > 0)
100 	{
101 		if (!buffers)
102 		{
103 			addLogEvent (kLogIdNullPointerToAudioBusBuffer);
104 			return;
105 		}
106 
107 		for (Steinberg::int32 bufferIdx = 0; bufferIdx < numBuffers; ++bufferIdx)
108 		{
109 			Steinberg::Vst::BusInfo busInfo = {};
110 			mComponent->getBusInfo (Steinberg::Vst::kAudio, dir, bufferIdx, busInfo);
111 			Steinberg::Vst::AudioBusBuffers& tmpBuffers = buffers[bufferIdx];
112 			if (tmpBuffers.numChannels != busInfo.channelCount)
113 			{
114 				addLogEvent (kLogIdInvalidAudioBufNumOfChannels);
115 			}
116 
117 			if (symbolicSampleSize == Steinberg::Vst::kSample32)
118 			{
119 				for (Steinberg::int32 chIdx = 0; chIdx < tmpBuffers.numChannels; ++chIdx)
120 				{
121 					if (!tmpBuffers.channelBuffers32 || !tmpBuffers.channelBuffers32[chIdx])
122 					{
123 						if (busInfo.busType == Steinberg::Vst::kAux)
124 							addLogEvent (kLogIdNullPointerToAuxChannelBuf);
125 						else
126 							addLogEvent (kLogIdNullPointerToChannelBuf);
127 					}
128 				}
129 			}
130 			else
131 			{
132 				for (Steinberg::int32 chIdx = 0; chIdx < tmpBuffers.numChannels; ++chIdx)
133 				{
134 					if (!tmpBuffers.channelBuffers64 || !tmpBuffers.channelBuffers64[chIdx])
135 					{
136 						if (busInfo.busType == Steinberg::Vst::kAux)
137 							addLogEvent (kLogIdNullPointerToAuxChannelBuf);
138 						else
139 							addLogEvent (kLogIdNullPointerToChannelBuf);
140 					}
141 				}
142 			}
143 		}
144 	}
145 }
146 
147 //------------------------------------------------------------------------
setComponent(Steinberg::Vst::IComponent * component)148 void HostCheck::setComponent (Steinberg::Vst::IComponent* component)
149 {
150 	mEventListCheck.setComponent (component);
151 	mComponent = component;
152 }
153 
154 //------------------------------------------------------------------------
setProcessSetup(Steinberg::Vst::ProcessSetup & setup)155 void HostCheck::setProcessSetup (Steinberg::Vst::ProcessSetup& setup)
156 {
157 	mProcessSetupCheck.setProcessSetup (setup);
158 	mEventListCheck.setProcessSetup (setup);
159 	mProcessContextCheck.setSampleRate (setup.sampleRate);
160 }
161