It is currently Sun May 19, 2019 9:33 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 42 posts ]  Go to page Previous  1, 2, 3
Author Message
 Post subject: Re: VST SDK plugin example
PostPosted: Mon Apr 22, 2019 2:05 pm 
Offline
User
User

Joined: Mon Dec 24, 2012 9:07 am
Posts: 33
Location: Ukraine, Donetck
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.

_________________
Sory my bad english


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Mon Apr 22, 2019 4:33 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jun 24, 2006 3:29 am
Posts: 175
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!

_________________
Proud supporter of PB! * Musician * C64/6502 Freak


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Mon Apr 22, 2019 11:58 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jun 24, 2006 3:29 am
Posts: 175
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:
    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 :D

Code:
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:
    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* :D

_________________
Proud supporter of PB! * Musician * C64/6502 Freak


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Tue Apr 23, 2019 10:46 pm 
Offline
User
User

Joined: Wed Feb 26, 2014 3:16 pm
Posts: 63
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:
          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.


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Wed Apr 24, 2019 4:04 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jun 24, 2006 3:29 am
Posts: 175
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.

_________________
Proud supporter of PB! * Musician * C64/6502 Freak


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Wed Apr 24, 2019 1:15 pm 
Offline
User
User

Joined: Mon Dec 24, 2012 9:07 am
Posts: 33
Location: Ukraine, Donetck
I try to write with WinApi, this not work properly...
Bad idea with this plug's...

Ups... I was late, Sq4 already answered.
Code:
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


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Mon May 06, 2019 8:36 am 
Offline
Enthusiast
Enthusiast

Joined: Fri Oct 16, 2009 10:12 am
Posts: 560
Location: BE
@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.

_________________
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Wed May 08, 2019 10:46 am 
Offline
User
User

Joined: Wed Feb 26, 2014 3:16 pm
Posts: 63
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...


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Wed May 08, 2019 4:55 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Oct 16, 2009 10:12 am
Posts: 560
Location: BE
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..."
;-)

_________________
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Thu May 09, 2019 9:28 am 
Offline
User
User

Joined: Wed Feb 26, 2014 3:16 pm
Posts: 63
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Wed May 15, 2019 5:28 pm 
Offline
User
User

Joined: Mon Dec 24, 2012 9:07 am
Posts: 33
Location: Ukraine, Donetck
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:
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


Top
 Profile  
Reply with quote  
 Post subject: Re: VST SDK plugin example
PostPosted: Thu May 16, 2019 8:59 am 
Offline
Enthusiast
Enthusiast

Joined: Fri Oct 16, 2009 10:12 am
Posts: 560
Location: BE
@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.

_________________
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 42 posts ]  Go to page Previous  1, 2, 3

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye