Problem with 32bit and 64bit plugin in 64bit host (Cubase)

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hello!

Can anyone help me, please?

I don't have any problem with my vst-plugin on Windows 7 32bit platform. It's actually very simple, the sdk as it is, just with one dummy parameter controlled by a CAnimKnob (potentiometer), no audio-processing, no event-processing.
VST sdk 2.4 rev2 and vstgui 3.0, Cubase 6.5.5 for testing. For testing I just made a automation-curve for the dummy parameter, the potentiometer moves as expected ...

When I switch to my 64bit Windows everything seems to work fine as well with the 32bit dll at first, but when I reload the song the potentiometer vanishes after a while. After closing the editor window I get a message like "Connection to VST-Bridge lost, reload the previous version of the project to establish the connection. Deactivate non-compatible plugins".

When I compile as 64bit dll it behaves similarly. The plugin works as expected, but when I reload the song Cubase crashes (without the above message of course).

In a fairly old mail from the mailing list Admiral Quality wrote:
Not sure if this is related, but I put a critical section around the
body of editor::close() and and editor::setParameter(). This was to
stop a crash in eXT, which was sending editor::setParameter() calls
DURING the call to editor::close() But maybe C5 is doing the same
thing now? Just a guess.

- AQ
http://lists.steinberg.net:8100/Lists/v ... 21686.html

I tried this as well, but it didn't help. Nevertheless editor::setparameter() seems to be the problem: When I remove that code it wouldn't crash ...

Maybe the two problems (crash of 32bit dll and the crash of the 64bit dll) aren't related?

Audio

Code: Select all

#include "effect.h"
#include "editor.h"
#include "midi.h"

//-----------------------------------------------------------------------------
AudioEffect* createEffectInstance(audioMasterCallback audioMaster)
{
	return new CEffect(audioMaster);
}
//-----------------------------------------------------------------------------
CEffect::CEffect(audioMasterCallback audioMaster)
	:AudioEffectX(audioMaster, kNumPrograms, kNumParams)
{
	setUniqueID(1234);
	isSynth(true);

	setNumInputs((VstInt32)2);
	setNumOutputs((VstInt32)2);

	m_volume = 0.0f;

	editor = new CEditor(this);
}
//-----------------------------------------------------------------------------
CEffect::~CEffect()
{
	
}
//-----------------------------------------------------------------------------
void CEffect::processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames)
{
	float* outputLeft = outputs[(VstInt32)0];
	float* outputRight = outputs[(VstInt32)1];

	// Audio processing
	while(--sampleFrames >= (VstInt32)0)
	{
		
		*outputLeft++ = 0.0f * m_volume;	// (*inputLeft++);
		*outputRight++ = 0.0f * m_volume;	// (*inputRight++);		
	}
}
//-------------------------------------------------------------------------------------------------
void CEffect::setParameter(VstInt32 index, float value)
{
	switch(index)
	{
	case kVolume:
		m_volume = value;
		break;
	}

	if(editor)
		((AEffGUIEditor*)editor)->setParameter(index, value);
}
//-------------------------------------------------------------------------------------------------
float CEffect::getParameter(VstInt32 index)
{
	float value = 0;

	switch(index)
	{
	case kVolume:
		value = m_volume;
		break;
	}
		
	return value;
}
//-----------------------------------------------------------------------------
VstInt32 CEffect::canDo(char* text)
{
	if(!strcmp(text, "receiveVstEvents"))
		return (VstInt32)1;
	if(!strcmp(text, "receiveVstMidiEvent"))
		return (VstInt32)1;
	if(!strcmp(text, "receiveVstTimeInfo"))
	 	return (VstInt32)1;
	return (VstInt32)-1;	// explicitly can't do; 0 => don't know
}
//-----------------------------------------------------------------------------
bool CEffect::getEffectName(char* name)
{
	if(strcpy(name, "VSTTemplateEffectName"))
		return true;
	return false;
}
//-----------------------------------------------------------------------------
bool CEffect::getProductString(char* text)
{
	if(strcpy(text, "VSTTemplateProductString"))
		return true;
	return false;
}
//-----------------------------------------------------------------------------
bool CEffect::getVendorString(char* text)
{
	if(strcpy(text, "Ingisoft"))
		return true;
	return false;
}
//-----------------------------------------------------------------------------
void CEffect::getParameterName(VstInt32 index, char* text)
{
	switch(index)
	{
	case kVolume:
		strcpy(text, "Volume");
		break;
	}
}
//-----------------------------------------------------------------------------
Editor:

Code: Select all

#include "editor.h"
#include "effect.h"
#include <string>

// resource id's
enum {
	// bitmaps (png)
	kBackgroundId						= 104,
	kVolumeId
};

//-------------------------------------------------------------------------------------------------
CEditor::CEditor(AudioEffect* effect)
	:AEffGUIEditor(effect)
{
	hBackground = new CBitmap(kBackgroundId);
	rect.left   = (VstInt16)0;
	rect.top    = (VstInt16)0;
	rect.right  = (VstInt16)hBackground->getWidth();
	rect.bottom = (VstInt16)hBackground->getHeight();
}
//-------------------------------------------------------------------------------------------------
CEditor::~CEditor()
{
	if(hBackground)
		hBackground->forget();
	hBackground = 0;
}
//-------------------------------------------------------------------------------------------------
bool CEditor::open(void* ptr)
{
	AEffGUIEditor::open(ptr);

	CBitmap* hVolume = new CBitmap(kVolumeId);

	// Point
	CPoint point(0, 0);
	CPoint offset(1, 0);

	// Background
	CRect size(0, 0, hBackground->getWidth(), hBackground->getHeight());
	CFrame* lFrame = new CFrame(size, ptr, this);
	lFrame->setBackground(hBackground);

	VstInt32 numberOfSubBitmaps = hVolume->getHeight() / hVolume->getWidth();
	size(100, 100, 100 + hVolume->getWidth(), 100 + hVolume->getHeight() / numberOfSubBitmaps);
	m_volume = new CAnimKnob(size, this, kVolume, hVolume, point);
	m_volume->setValue(effect->getParameter(kVolume));
	lFrame->addView(m_volume);

	hVolume->forget();

	frame = lFrame;

	return true;
}
//-------------------------------------------------------------------------------------------------
void CEditor::close()
{
}
//-------------------------------------------------------------------------------------------------
void CEditor::idle()
{
	if(m_volume->isDirty())
		m_volume->redraw();
}
//-------------------------------------------------------------------------------------------------
void CEditor::setParameter(VstInt32 index, float value)
{
	switch(index)
	{
	case kVolume:
		m_volume->setValue(effect->getParameter(index));
		m_volume->setDirty();
		break;
	}
}
//-------------------------------------------------------------------------------------------------
void CEditor::valueChanged(CDrawContext* context, CControl* control)
{
	VstInt32 tag = control->getTag();

	switch(tag)
	{
	case kVolume:
		effect->setParameterAutomated(tag, control->getValue());
		control->setDirty();
		break;
	}
}
//-------------------------------------------------------------------------------------------------
This really drives me nuts ...
How can I build a working 32bit or (even better) 64bit dll?
Any help & criticism is much appreciated!
Thanks!
Thomas
Image

Post

Make sure you initialize your control pointers to zero before creating the controls. (i.e. in the editor constructor)

Zero them when you delete the control.

And test that they're not zero before you call anything on the control. (As editor::setParameter is doing. Which is probably causing your crash.)

Code: Select all

if (m_volume)
    m_volume->setValue(effect->getParameter(index)); 
And VSTGUI 3.0 is ancient. Use VSTGUI 3.6 RC2 from here http://sourceforge.net/projects/vstgui/ ... GUI%203.6/

Let us know if that helps.

Oh, and might I recommend using the debugger?

Post

OMG :dog:

It works better now (32bit). Sorry, I'm an idiot ...
Anyway: I don't understand why I never came across this problem on the 32bit host?
I'll give a try for VSTGUI 3.6 ...

Thank you very much AQ!

Thomas
Image

Post

EagleEye wrote:OMG :dog:

It works better now (32bit). Sorry, I'm an idiot ...
Anyway: I don't understand why I never came across this problem on the 32bit host?
I'll give a try for VSTGUI 3.6 ...

Thank you very much AQ!

Thomas
Not sure, it should be a bug in 32 bit too.

By the way, that critical section thing I'm doing in my post you quoted, on editor::close, is exactly to avoid this problem. It prevents a race condition between setParameter() and close() deleting the control before it can zero the pointer. By not letting setParameter and close run at the same time, we avoid that problem.

When you move to 3.6, you can take out the setDirty line.

Glad I could help. Cheers!

Post

Thanks for elaborating.
x64 works as well now ;-)

Thomas
Image

Post

EagleEye wrote:Thanks for elaborating.
x64 works as well now ;-)

Thomas
The other great thing about VSTGUI 3.6 RC2 is it'll compile for x64 on the Mac. See the turorial1 example.

Post Reply

Return to “DSP and Plugin Development”