Page 3 of 4
Re: VST SDK plugin example
Posted: Mon Apr 22, 2019 2:05 pm
by Aleks_Longard
I don’t understand some things in PB or simply don’t know. My experiments with the plugin window are very bad, it turns out the window on top of the host instead of the client area inside the host window.
Canvas gadget is attached to the window pane after OpenWindow (), and without the main window it is not working.
Sorry guys, I use screenreader software for watching the screen and for me the plug-in window is almost useless, for this reason I did not pay attention to how the GUI works in plug-ins.
I will try to write a window using WinApi, I already did this when I studied VST on C++, so it will be easier to understand how it works.
Re: VST SDK plugin example
Posted: Mon Apr 22, 2019 4:33 pm
by oreopa
Hey Aleks.
Too bad about your experiments with the native stuff... I assumed there would be some way to create a canvas gadget and just use the handle of that (or a borderless window with canvas gadget that docks seamlessly in the host vst "container")... I tried myself but i cannot work it out... I also can only get a floating window that does not dock/attach to host gui... (I'm still kinda hopeful this canvasgadget approach could work tho...)
I'd like to know how sq4 does it also, maybe he has some hints...
Cheers all!
Re: VST SDK plugin example
Posted: Mon Apr 22, 2019 11:58 pm
by oreopa
Ok. I am hacking around like crazy, and finally I got somewhere...
This seems to open and attach a window with gadgets to the host gui in dispatcher...
Code: Select all
Case #effEditOpen
result = OpenWindow(#PB_Any, 0, 0, 500, 500, "!", #WS_CHILD, *ptr)
ButtonGadget(#PB_Any, 0, 0, 64, 64, "PRESS ME", #PB_Button_Toggle)
Global g_CANVAS = CanvasGadget(#PB_Any, 100,100,250,250)
StartDrawing(CanvasOutput(g_CANVAS))
Box(100, 100, 50, 50, #Red)
StopDrawing()
Now the mission is to find a place to put some waitwindowevent or similar... I want to mousedown and move the red square now!
edit;
Ok. terrible code... probably already running into the cross-thread variable problems ive seen sq4 mentioning.... but what the heck
Code: Select all
Procedure uiEventThread(*ptr)
Protected ev.l
Protected x,y ,z
Global uiWindowHandle = OpenWindow(#PB_Any, 0, 0, 500, 500, "", #WS_CHILD, *ptr)
Global threadrunninng = #True
Global result
Global g_BUTTON = ButtonGadget(#PB_Any, 0, 0, 64, 64, "PRESS ME", #PB_Button_Toggle)
Global g_CANVAS = CanvasGadget(#PB_Any, 100,100,250,250)
StartDrawing(CanvasOutput(g_CANVAS))
Box(100, 100, 50, 50, RGB(128+Random(127), 128+Random(127), 128+Random(127)))
StopDrawing()
Repeat
ev = WaitWindowEvent()
Select ev
Case #PB_Event_Gadget
Select EventGadget()
Case g_CANVAS
Select EventType()
Case #PB_EventType_MouseMove
If GetGadgetAttribute(g_CANVAS, #PB_Canvas_Buttons) = #PB_Canvas_LeftButton
x = GetGadgetAttribute(g_CANVAS, #PB_Canvas_MouseX)
y = GetGadgetAttribute(g_CANVAS, #PB_Canvas_MouseY)
StartDrawing(CanvasOutput(g_CANVAS))
Box(x, y, 50, 50, RGB(128+Random(127), 128+Random(127), 128+Random(127)))
StopDrawing()
EndIf
EndSelect
EndSelect
EndSelect
Until threadrunninng = #False
EndProcedure
and
in dispatcher proc:
Code: Select all
Case #effEditOpen
CreateThread(@uiEventThread(), *ptr)
Delay(100)
result = uiWindowHandle
Case #effEditClose
threadrunninng = #False
Delay(100)
CloseWindow(uiWindowHandle)
It's awful hacky... but it does *something*

Re: VST SDK plugin example
Posted: Tue Apr 23, 2019 10:46 pm
by sq4
The use of PB's window functions is a no go. I know that p.e. Reaper will crash when reopening the editor window.
So you need to use WinApi.
But first you have to register the window class in AttachProcess and unregister in DetachProcess.
To create the window, you could do with something like this :
Code: Select all
lStyle.l=#WS_CHILD | #WS_VISIBLE | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN | #WS_EX_ACCEPTFILES
hPluginWin = CreateWindowEx_(#WS_EX_ACCEPTFILES, @g_szClassName, 0, lStyle, 0, 0, #Plugin_Width, #Plugin_Height, *AEffect\Editor\ParentId, 0, gInstance, 0)
If hPluginWin
*AEffect\Editor\Gadget=hPluginWin
SetProp_(*AEffect\Editor\Gadget,"oldproc",SetWindowLongPtr_(*AEffect\Editor\Gadget,#GWL_WNDPROC, @EditorCallback()))
SetProp_(*AEffect\Editor\Gadget,"ptrAEffect",*AEffect)
ShowWindow_(*AEffect\Editor\Gadget,#SW_SHOW)
UpdateWindow_(*AEffect\Editor\Gadget)
VST_EditOpenClose(*AEffect, #Open)
endif
No need to create an extra thread for event handling, just do everything in the callback (in this case EditorCallback().
In #WM_Paint do a Bitblt_() of your editors image.
Re: VST SDK plugin example
Posted: Wed Apr 24, 2019 4:04 am
by oreopa
sq4 wrote:The use of PB's window functions is a no go[...]
That's too bad... i thought CanvasGagdet would be great to make it cross platform (graphically).
sq4 wrote:So you need to use WinApi[...]
sq4 wrote:No need to create an extra thread for event handling, just do everything in the callback (in this case EditorCallback().
In #WM_Paint do a Bitblt_() of your editors image.
Ok, I'll try it. Thanx a lot for the tips.
Re: VST SDK plugin example
Posted: Wed Apr 24, 2019 1:15 pm
by Aleks_Longard
I try to write with WinApi, this not work properly...
Bad idea with this plug's...
Ups... I was late, Sq4 already answered.
Code: Select all
EnableExplicit
IncludeFile "aeffect.pbi"
IncludeFile "aeffectx.pbi"
Global handle ; for VST window
Global channels.l = 2
Global paramvolume.f = 1.0
; VST-plugin window
Procedure WinProcCallback(handle, message, wparam, lparam)
Protected r
Select message
Case #WM_CLOSE
DestroyWindow_(handle)
Case #WM_DESTROY
PostQuitMessage_(0)
r = 0
Default
r = DefWindowProc_(handle, message, wparam, lparam)
EndSelect
ProcedureReturn r
EndProcedure
Procedure OpenVSTWindow(hosthandle.i)
Protected text.s = "Hello World for VST plugin"
Protected THandle
Protected wc.WNDCLASS
Protected WinVSTClass.s = "VSTPluginClass"
wc\style = #CS_GLOBALCLASS
wc\lpfnWndProc = @WinProcCallback()
wc\lpszClassName = @WinVSTClass
If RegisterClass_(@wc)
handle = CreateWindowEx_(0, @WinVSTClass, "Hello! Plugin", #WS_CHILD | #WS_VISIBLE | #WS_CLIPCHILDREN, 0, 0, 300, 500, hosthandle, 0, 0, 0)
THandle = CreateWindowEx_(0, "Static", text, #WS_CHILD | #WS_VISIBLE, 5, 5, 150, 50, handle, 0, 0, 0)
SendMessage_(THandle, #WM_SETFONT, #DEFAULT_GUI_FONT, 1)
ShowWindow_(handle, #SW_SHOWDEFAULT)
UpdateWindow_(handle)
Else
MessageRequester("Error", "Can not create window", 0)
EndIf
EndProcedure
Procedure CloseVSTWindow()
SendMessage_(handle, #WM_CLOSE, 0, 0)
EndProcedure
; other procedures
Procedure getParameterName(index.l, *text)
Select index
Case 0
PokeS(*text, "Volume", #kVstMaxParamStrLen, #PB_Ascii)
EndSelect
EndProcedure
Procedure getParameterDisplay(index.l, *text)
Select index
Case 0
PokeS(*text, StrF(paramvolume, 4), 4, #PB_Ascii)
EndSelect
EndProcedure
; procedures for VST sdk
ProcedureC.i DispatcherProc(*d.AEffect, opcode.l, index.l, Value.i, *ptr, opt.f)
Protected result.i
Select opcode
Case #effClose
FreeStructure(*d)
Case #effGetParamDisplay
getParameterDisplay(index, *ptr)
Case #effGetParamName
getParameterName(index, *ptr)
Case #effGetPlugCategory
result = #kPlugCategEffect | #kPlugCategAnalysis
Case #effGetEffectName
PokeS(*ptr, "test plugin", #kVstMaxEffectNameLen, #PB_Ascii)
Case #effGetVendorString
PokeS(*ptr, "Alex Longard", #kVstMaxVendorStrLen, #PB_Ascii)
Case #effEditOpen
OpenVSTWindow(PeekI(*ptr))
Case #effEditClose
CloseVSTWindow()
Default
EndSelect
ProcedureReturn result
EndProcedure
ProcedureC ProcessReplacingProc(*ap.AEffect, *inputs, *outputs, sampleframes.l)
Protected *In1, *In2, *Out1, *Out2, i.l
*In1 = PeekI(*inputs)
*Out1 = PeekI(*outputs)
If channels = 2
*In2 = PeekI(*inputs + SizeOf(integer))
*Out2 = PeekI(*outputs + SizeOf(integer))
EndIf
For i = 0 To sampleframes - 1
PokeF(*Out1 + i * SizeOf(float), PeekF(*In1 + i * SizeOf(float)) * paramvolume)
If channels = 2
PokeF(*Out2 + i * SizeOf(float), PeekF(*In2 + i * SizeOf(float)) * paramvolume)
EndIf
Next i
EndProcedure
ProcedureC ProcessDoubleReplacingProc(*ap.AEffect, *inputs, *outputs, sampleframes.l)
EndProcedure
ProcedureC SetParameterProc(*asp.AEffect, index.l, value.f)
paramvolume = value
EndProcedure
ProcedureC.f GetParameterProc(*agp.AEffect, index.l)
ProcedureReturn paramvolume
EndProcedure
ProcedureCDLL VSTPluginMain(*audioMaster)
Protected *Aef.AEffect = AllocateStructure(AEffect)
*aef\magic = #kEffectMagic
*aef\dispatcher = @DispatcherProc()
*aef\setParameter = @SetParameterProc()
*aef\getParameter = @GetParameterProc()
*aef\numParams = 1
*aef\numInputs = channels
*aef\numOutputs = channels
*aef\flags = #effFlagsHasEditor | #effFlagsCanReplacing
*aef\processReplacing = @ProcessReplacingProc()
; *aef\processDoubleReplacing = @ProcessDoubleReplacingProc()
*aef\uniqueID = 02081987
*aef\version = 1
*aef\Object = 0
ProcedureReturn *aef
EndProcedure
Re: VST SDK plugin example
Posted: Mon May 06, 2019 8:36 am
by Joris
@Aleks_Longard and others.
Hi
To me this is still (a bit or a lot) above my experiences, aside I wonder if this code is also ment to handle midi-vst's ? And if so how ?
The terms used in the code here are about effect's (AE) etc. nothing that would link to MIDI, which for me is a simpler thing then audio programming.
Are you intended to work on that too or just on audio vst's (vsti) ?
Thanks.
Re: VST SDK plugin example
Posted: Wed May 08, 2019 10:46 am
by sq4
Joris wrote:@Aleks_Longard and others.
Hi
To me this is still (a bit or a lot) above my experiences, aside I wonder if this code is also ment to handle midi-vst's ? And if so how ?
The terms used in the code here are about effect's (AE) etc. nothing that would link to MIDI, which for me is a simpler thing then audio programming.
Are you intended to work on that too or just on audio vst's (vsti) ?
Thanks.
For a midiplugin:
You need to set the flags to include effFlagsIsSynth
In cando you need to expose following :
-canDoSendVstEvents
-canDoSendVstMidiEvent
In process/processreplacing you need to queue your midievents ( p.e. in a list) and at the end call audiomaster with "audioMasterProcessEvents" and the array of pointers to MidiEvent structures...
Re: VST SDK plugin example
Posted: Wed May 08, 2019 4:55 pm
by Joris
Thanks sq4, I hope I'll grow a bit more into this very complicated stuff.
To me it all looks more like 'why making it easy, while it can be made difficult..."

Re: VST SDK plugin example
Posted: Thu May 09, 2019 9:28 am
by sq4
Joris wrote:Thanks sq4, I hope I'll grow a bit more into this very complicated stuff.
To me it all looks more like 'why making it easy, while it can be made difficult..."

Perhaps easier alternatives :
- Synthedit
- Flowstone
- Blue Cat plug 'n script
- ...
I've started with PB (v 3.81) to create
RnT2 which is a VST experimental HOST.
TBH it took me over 4 years to finish it.
Once you know the inner workings of a HOST it's naturally much easier to develop VST-plugins.
But you are right :
it's quite complex!
Re: VST SDK plugin example
Posted: Wed May 15, 2019 5:28 pm
by Aleks_Longard
Hi Joris!
I do not have free time to experiment with PB VST. I can show you my C function for you to get information about all VstEvents, with this function you can manipulate midi.
Code: Select all
VstInt32 processEvents(VstEvents* ev) {
for (int i = 0; i < ev->numEvents; i++)
{
VstEvent* event = ev->events[i];
if (event->type == kVstMidiType)
{
VstMidiEvent* midiEvent = (VstMidiEvent*) event;
VstInt8 status = midiEvent->midiData[0];
VstInt8 data1 = midiEvent->midiData[0];
VstInt8 data2 = midiEvent->midiData[0];
printf("MIDI: %02x %02x %02x\n", status, data1, data2);
}
}
return 0;
}
Re: VST SDK plugin example
Posted: Thu May 16, 2019 8:59 am
by Joris
@Aleks_Longard thanks.
I'm still busy with a 'Drum-DAW' and would later on be able to build a midi-vst in which the data form that 'Drum-DAW' can be played. So, I need to read the clock from the host and be able to send the data out.
Your code looks close to be going that way...
Nice.
Re: VST SDK plugin example
Posted: Sun Dec 29, 2019 9:43 am
by Aleks_Longard
Hello all!
I write new example with window (not controls)
Please compile to test code in file: vst_window.pb
All sdk files there:
https://www.dropbox.com/sh/j0vun0sg751f ... drVEa?dl=0
Re: VST SDK plugin example
Posted: Tue Oct 27, 2020 11:37 am
by SofT MANiAC
hello! link is dead

Re: VST SDK plugin example
Posted: Thu Jan 28, 2021 7:48 am
by Aleks_Longard
Hello SofT MANiAC and all!
Sorry for bad link, my notebook is dead and i not have new full plugin code, i post dropbox link for last worked code
https://www.dropbox.com/sh/sz1dgj2d08dr ... UJBWa?dl=0
If you have questions for this - i will can to ask.
Cheers!