Quick Sign In:  

Forum: VirtualDJ Plugins

Topic: Mapper Plugin example and a question

This topic is old and might contain outdated or incorrect information.

Hi all,

Just managed to get my first (propper) plugin for V-DJ going. It's a couple of small extensions to the Numark Total Control mapper:
i) Disable the pitch sliders and use one as a mic volume control instead
ii) Disable jog on a playing deck

I learnt a lot in this process - most of which you don't need to repeat if you copy the right stuff out of the source code below :-)

One thing that is a bit odd though: DLL naming is important if V-DJ is going to pick up mapping plugins. For Total Control I had to name the plugin "KC0.dll" and put it in the "My Documents/Virtual DJ/Plugins/Control Device" directory. (KC0 is the old code-name for Total Control and also the name of the .h file from the SDK).

I am using Visual Studio .NET 2003 as a development environment and V-DJ V5.0 rev 6.

So here is the question:
It all works fine, except that if I use the plugin in Debug mode and run the program from the Visual Studio dubug command then all works until I quit V-DJ and then I get an exception in the V-DJ code (not my code!) just before V-DJ quits. Any ideas on this?

With V-DJ running on its own I don't get any error indications at all.


#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE

#include <windows.h>
#include "vdjPlugin.h"
#include "vdjDevice.h"
#include "KC0Mapper.h"


//---------------------------------------------------------------------------
// Class definition
//---------------------------------------------------------------------------
class CVDJsharpieFM : public IVdjPluginDevice
{
public:
HRESULT __stdcall OnLoad();
HRESULT __stdcall OnGetPluginInfo(TVdjPluginInfo *infos) ;
HRESULT __stdcall OnButton(int chan,int button,int down);
HRESULT __stdcall OnSlider(int chan,int slider,int absvalue,int relvalue);
HRESULT __stdcall OnTimer();
HRESULT __stdcall GetDeviceType(int *type);


int pitch_is_mic;
int no_scratch_on_play;

private:
};
//---------------------------------------------------------------------------
// Initialisation
//---------------------------------------------------------------------------
HRESULT __stdcall DllGetClassObject(const GUID &rclsid,const GUID &riid,void** ppObject)
{
// You don't need to change anything here
// Just leave it like that
if(memcmp(&rclsid,&CLSID_VdjPlugin,sizeof(GUID)) != 0) return CLASS_E_CLASSNOTAVAILABLE;
if(memcmp(&riid,&IID_IVdjPluginDevice,sizeof(GUID))!=0) return CLASS_E_CLASSNOTAVAILABLE;
*ppObject=new CVDJsharpieFM();
return NO_ERROR;
}
//---------------------------------------------------------------------------



char _strparam[128];
inline char *strparam(char* s, int v) {wsprintf(_strparam,s,v);return _strparam;};


HRESULT __stdcall CVDJsharpieFM::OnLoad()
{
DeclareParameter(&pitch_is_mic,VDJPARAM_SWITCH,1,"Use pitch for mic control",1);
DeclareParameter(&no_scratch_on_play,VDJPARAM_SWITCH,2,"No scratch on play",1);
return S_OK;
}

HRESULT __stdcall CVDJsharpieFM::OnGetPluginInfo(TVdjPluginInfo *infos)
{
infos->PluginName="KC0 VDJsharpieFM";
infos->Author="Iain Sharp";
infos->Description="SharpieFM Total Control extentions";
// Replace the files "BITMAP.BMP" and "SELECTED.BMP" in your directory with your own.
infos->Bitmap=LoadBitmap(hInstance,MAKEINTRESOURCE(100));
infos->Flag=0;
return S_OK;
}



HRESULT __stdcall CVDJsharpieFM::OnButton(int chan,int button,int down)
{
return E_NOTIMPL;
}


HRESULT __stdcall CVDJsharpieFM::OnSlider(int chan,int slider,int absvalue,int relvalue)
{
if (pitch_is_mic && slider==KC0_SLID_PITCH_A)
{
SendCommand(strparam("mic_volume %i",absvalue),0);
return S_OK;
}
if (pitch_is_mic && slider==KC0_SLID_PITCH_B)
return S_OK;

if (no_scratch_on_play && (slider == KC0_SLID_JOG_A) && (DeckInfo[0]->Playing) )
return S_OK;

if (no_scratch_on_play && (slider == KC0_SLID_JOG_B) && (DeckInfo[1]->Playing) )
return S_OK;

return E_NOTIMPL;
}



HRESULT __stdcall CVDJsharpieFM::OnTimer()
{
return E_NOTIMPL;
}

HRESULT __stdcall CVDJsharpieFM::GetDeviceType(int *type)
{
* type=PLUGINDEVICE_TOTALCONTROL;
return S_OK;
}


//---------------------------------------------------------------------------
// Add any private functions that you need here



BTW the rather odd class name is in honour of my radio show over at www.purple-radio.co.uk.

Hope this is useful to some people and also any help with the odd error would be nice!
 

Posted Sat 05 Jan 08 @ 3:48 pm
djcelPRO InfinityModeratorMember since 2004
Could you give us more information about the exception: heap?

I think it's this part of the code:
char _strparam[128];

It's declared as a global variable and it would be better to use a pointer and allocate the memory inside the class.


You can also use the function:

//Plugin exit (opposite of OnLoad() ) 

ULONG Release()
{
// your code
delete this;
return 0;
}
 

Posted Sat 05 Jan 08 @ 5:28 pm
Quote :

I think it's this part of the code:
char _strparam[128];



Good thought, but I've just tried commenting out that global variable and function (and the one place that calls that function) and still get the same error.

I traced the flow in my class. Release() and the class destructor and these are both called and exit OK before the error - so the error is after my class has been deleted.

The message on the Debug output is "HEAP[virtualdj.exe]: HEAP: Free Heap block 21bb000 modified at 21bb074 after it was freed". Possibly Virtualdj is trying to do something with the class after it's deleted?

Actually it's worth looking at more of the debug ouput - here are the last few lines:
'virtualdj.exe': Unloaded 'C:\Documents and Settings\Iain\My Documents\VirtualDJ\Plugins\SoundEffect\vocals+.dll'
'virtualdj.exe': Unloaded 'C:\Documents and Settings\Iain\My Documents\VirtualDJ\Plugins\SoundEffect\flanger.dll'
'virtualdj.exe': Unloaded 'C:\Documents and Settings\Iain\My Documents\VirtualDJ\Plugins\VideoTransition\default.dll'
'virtualdj.exe': Unloaded 'C:\Documents and Settings\Iain\My Documents\VirtualDJ\Plugins\ControlDevice\KC0.dll'
The thread 'Win32 Thread' (0xf88) has exited with code 1 (0x1).
The thread 'Win32 Thread' (0xbc4) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0xf44) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0xf74) has exited with code 1 (0x1).
The thread 'Win32 Thread' (0x100) has exited with code 1 (0x1).
'virtualdj.exe': Unloaded 'C:\WINDOWS\system32\cscui.dll'
'virtualdj.exe': Unloaded 'C:\WINDOWS\system32\cscdll.dll'
HEAP[virtualdj.exe]: HEAP: Free Heap block 21bb000 modified at 21bb074 after it was freed
Unhandled exception at 0x7c901230 in virtualdj.exe: User breakpoint.

So V-DJ is obviously fairly far though it's deinitialisation before the error.
 

Posted Sun 06 Jan 08 @ 2:13 am
OK - one last test. This is the simplest mapper possible from the headers. It doesn't do anything except for declaring itself and overriding the one abstract function in its parent class. I still get the same error if I debug this:


#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE

#include <windows.h>
#include "vdjPlugin.h"
#include "vdjDevice.h"
#include "KC0Mapper.h"

//---------------------------------------------------------------------------
// Class definition
//---------------------------------------------------------------------------
class CVDJsharpieFM : public IVdjPluginDevice
{
public:
HRESULT __stdcall GetDeviceType(int *type);

private:
};
//---------------------------------------------------------------------------
// Initialisation
//---------------------------------------------------------------------------
HRESULT __stdcall DllGetClassObject(const GUID &rclsid,const GUID &riid,void** ppObject)
{
if(memcmp(&rclsid,&CLSID_VdjPlugin,sizeof(GUID)) != 0) return CLASS_E_CLASSNOTAVAILABLE;
if(memcmp(&riid,&IID_IVdjPluginDevice,sizeof(GUID))!=0) return CLASS_E_CLASSNOTAVAILABLE;
*ppObject=new CVDJsharpieFM();
return NO_ERROR;
}
//---------------------------------------------------------------------------

HRESULT __stdcall CVDJsharpieFM::GetDeviceType(int *type)
{
* type=PLUGINDEVICE_TOTALCONTROL;
return S_OK;
}
 

Posted Sun 06 Jan 08 @ 3:26 am
SBDJPRO Infinity Member since 2006
I've always got this error when exiting VDJ in debug mode with any type of plugin.

Regards,

Scott
 

Posted Thu 10 Jan 08 @ 11:28 pm
How i must do to do a plug-in in visualbasic6?
 

Posted Sat 29 Mar 08 @ 7:49 am


(Old topics and forums are automatically closed)