VST SDK plugin example
-
- User
- Posts: 59
- Joined: Mon Dec 24, 2012 9:07 am
- Location: Germany, Munich
Re: VST SDK plugin example
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.
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.
Sory my bad english
Re: VST SDK plugin example
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!
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!
Proud supporter of PB! * Musician * C64/6502 Freak
Re: VST SDK plugin example
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...
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
and
in dispatcher proc:
It's awful hacky... but it does *something*
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()
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
in dispatcher proc:
Code: Select all
Case #effEditOpen
CreateThread(@uiEventThread(), *ptr)
Delay(100)
result = uiWindowHandle
Case #effEditClose
threadrunninng = #False
Delay(100)
CloseWindow(uiWindowHandle)
Proud supporter of PB! * Musician * C64/6502 Freak
Re: VST SDK plugin example
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 :
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.
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
In #WM_Paint do a Bitblt_() of your editors image.
Re: VST SDK plugin example
That's too bad... i thought CanvasGagdet would be great to make it cross platform (graphically).sq4 wrote:The use of PB's window functions is a no go[...]
sq4 wrote:So you need to use WinApi[...]
Ok, I'll try it. Thanx a lot for the tips.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.
Proud supporter of PB! * Musician * C64/6502 Freak
-
- User
- Posts: 59
- Joined: Mon Dec 24, 2012 9:07 am
- Location: Germany, Munich
Re: VST SDK plugin example
I try to write with WinApi, this not work properly...
Bad idea with this plug's...
Ups... I was late, Sq4 already answered.
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
Sory my bad english
Re: VST SDK plugin example
@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.
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.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: VST SDK plugin example
For a midiplugin: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.
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
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..."
To me it all looks more like 'why making it easy, while it can be made difficult..."
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: VST SDK plugin example
Perhaps easier alternatives :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..."
- 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!
-
- User
- Posts: 59
- Joined: Mon Dec 24, 2012 9:07 am
- Location: Germany, Munich
Re: VST SDK plugin example
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.
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;
}
Sory my bad english
Re: VST SDK plugin example
@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.
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.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
-
- User
- Posts: 59
- Joined: Mon Dec 24, 2012 9:07 am
- Location: Germany, Munich
Re: VST SDK plugin example
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
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
Sory my bad english
-
- Enthusiast
- Posts: 142
- Joined: Mon Sep 17, 2007 10:28 am
- Location: P.O.P
- Contact:
Re: VST SDK plugin example
hello! link is deadAleks_Longard wrote: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
POiNT.OF.PRESENCE group
-
- User
- Posts: 59
- Joined: Mon Dec 24, 2012 9:07 am
- Location: Germany, Munich
Re: VST SDK plugin example
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!
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!
Sory my bad english