aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--EditorThread.cpp59
-rw-r--r--EditorThread.h57
-rw-r--r--PopupWindow.cpp116
-rw-r--r--PopupWindow.h55
-rw-r--r--ReadMe.txt57
-rw-r--r--Resource.h16
-rw-r--r--StdAfx.cpp8
-rw-r--r--StdAfx.h42
-rw-r--r--Vst/AEffEditor.h44
-rw-r--r--Vst/AEffect.h172
-rw-r--r--Vst/AEffectx.h534
-rw-r--r--Vst/AudioEffect.hpp109
-rw-r--r--Vst/audioeffectx.h185
-rw-r--r--VstHost.cpp581
-rw-r--r--VstHost.h145
-rw-r--r--crazy.pd16
-rw-r--r--export.h9
-rw-r--r--neontest.pd14
-rw-r--r--res/vst.rc213
-rw-r--r--vst.apsbin0 -> 17844 bytes
-rw-r--r--vst.clw37
-rw-r--r--vst.cpp111
-rw-r--r--vst.def7
-rw-r--r--vst.dsp176
-rw-r--r--vst.dsw29
-rw-r--r--vst.h46
-rw-r--r--vst.ncbbin0 -> 199680 bytes
-rw-r--r--vst.optbin0 -> 54784 bytes
-rw-r--r--vst.plg53
-rw-r--r--vst.rc124
-rw-r--r--vst.sln21
-rw-r--r--vst.suobin0 -> 12288 bytes
-rw-r--r--vst.vcproj224
-rw-r--r--vsttest.pd32
-rw-r--r--vst~.cpp579
-rw-r--r--vst~.h63
-rw-r--r--vst~.pdfbin0 -> 192748 bytes
37 files changed, 3734 insertions, 0 deletions
diff --git a/EditorThread.cpp b/EditorThread.cpp
new file mode 100644
index 0000000..5030f5a
--- /dev/null
+++ b/EditorThread.cpp
@@ -0,0 +1,59 @@
+// EditorThread.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "vst.h"
+#include "EditorThread.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditorThread
+
+IMPLEMENT_DYNCREATE(CEditorThread, CWinThread)
+
+CEditorThread::CEditorThread()
+{
+ pop = NULL;
+}
+
+CEditorThread::~CEditorThread()
+{
+}
+
+BOOL CEditorThread::InitInstance()
+{
+ pop = new CPopupWindow();
+ m_pMainWnd = pop;
+ pop->CreateEx( WS_EX_DLGMODALFRAME , AfxRegisterWndClass( CS_DBLCLKS) ," VST window" , WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU , 10 , 10 , 300 , 300 , NULL , NULL , NULL);
+ pop->SetPlugin( plug );
+ pop->DoInit();
+ pop->ShowWindow( SW_SHOW );
+ pop->BringWindowToTop();
+ pop->SetFocus();
+ return TRUE;
+}
+
+int CEditorThread::ExitInstance()
+{
+ // TODO: perform any per-thread cleanup here
+ return CWinThread::ExitInstance();
+}
+
+BEGIN_MESSAGE_MAP(CEditorThread, CWinThread)
+ //{{AFX_MSG_MAP(CEditorThread)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditorThread message handlers
+
+void CEditorThread::SetPlugin(VSTPlugin *p)
+{
+ plug = p;
+}
diff --git a/EditorThread.h b/EditorThread.h
new file mode 100644
index 0000000..5c2c182
--- /dev/null
+++ b/EditorThread.h
@@ -0,0 +1,57 @@
+#if !defined(AFX_EDITORTHREAD_H__9F3ACE98_7522_400D_9404_DFD67E3D721B__INCLUDED_)
+#define AFX_EDITORTHREAD_H__9F3ACE98_7522_400D_9404_DFD67E3D721B__INCLUDED_
+
+#include "PopupWindow.h" // Added by ClassView
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// EditorThread.h : header file
+//
+
+class VSTPLugin;
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditorThread thread
+
+class CEditorThread : public CWinThread
+{
+ DECLARE_DYNCREATE(CEditorThread)
+protected:
+
+
+// Attributes
+public:
+ CEditorThread(); // protected constructor used by dynamic creation
+
+// Operations
+public:
+ VSTPlugin* plug;
+ void SetPlugin( VSTPlugin *);
+ CPopupWindow *pop;
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CEditorThread)
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ virtual ~CEditorThread();
+
+ // Generated message map functions
+ //{{AFX_MSG(CEditorThread)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ //}}AFX_MSG
+
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_EDITORTHREAD_H__9F3ACE98_7522_400D_9404_DFD67E3D721B__INCLUDED_)
diff --git a/PopupWindow.cpp b/PopupWindow.cpp
new file mode 100644
index 0000000..5a96bdc
--- /dev/null
+++ b/PopupWindow.cpp
@@ -0,0 +1,116 @@
+// PopupWindow.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "m_pd.h"
+#include "vst.h"
+#include "PopupWindow.h"
+#include "EditorThread.h"
+#include "VstHost.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+extern CVstApp theApp;
+
+/////////////////////////////////////////////////////////////////////////////
+// CPopupWindow
+
+IMPLEMENT_DYNCREATE(CPopupWindow, CFrameWnd)
+
+CPopupWindow::CPopupWindow()
+{
+ plug = NULL;
+}
+
+CPopupWindow::~CPopupWindow()
+{
+ plug->OnEditorCLose();
+ plug = NULL;
+}
+
+
+BEGIN_MESSAGE_MAP(CPopupWindow, CFrameWnd)
+ //{{AFX_MSG_MAP(CPopupWindow)
+ ON_WM_ENTERIDLE()
+ ON_WM_TIMER()
+ ON_WM_MOVE()
+ ON_WM_CLOSE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CPopupWindow message handlers
+
+void CPopupWindow::OnEnterIdle(UINT nWhy, CWnd* pWho)
+{
+ CFrameWnd::OnEnterIdle(nWhy, pWho);
+
+ // TODO: Add your message handler code here
+ if (plug != NULL )
+ {
+ plug->EditorIdle();
+ }
+}
+
+void CPopupWindow::SetPlugin(VSTPlugin *p)
+{
+ plug = p;
+ plug->Dispatch(effEditOpen , 0 , 0 , m_hWnd , 0.0f );
+ RECT r = plug->GetEditorRect();
+ CString str = theApp.GetProfileString( "VSTPos" , plug->GetName() , "10,10");
+ int idx = str.Find(",");
+ CString x = str.Left( idx );
+ CString y = str.Right( idx );
+ printf(" index is %d left is %s and right is %s" , idx , x , y);
+ SetWindowPos( &wndTopMost , atoi( x ) , atoi( y ) , (r.right - r.left) + 10 , r.bottom - r.top + 30 , SWP_SHOWWINDOW );
+}
+
+BOOL CPopupWindow::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
+{
+ // TODO: Add your specialized code here and/or call the base class
+
+ return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
+}
+
+void CPopupWindow::DoInit()
+{
+ printf("DoInit\n");
+ plug->Dispatch(effEditTop,0,0, 0,0.0f);
+ printf("Dispatched to the top\n");
+ SetTimer(0,25,NULL);
+}
+
+void CPopupWindow::OnTimer(UINT nIDEvent)
+{
+ plug->Dispatch(effEditIdle, 0, 0, NULL, 0.0f);
+ CFrameWnd::OnTimer(nIDEvent);
+}
+
+void CPopupWindow::OnMove(int x, int y)
+{
+ CFrameWnd::OnMove(x, y);
+ if ( plug != NULL )
+ {
+ char buf[100];
+ sprintf( buf , "%d,%d" , x , y );
+ theApp.WriteProfileString( "VSTPos" , plug->GetName() , buf );
+ }
+}
+
+
+void CPopupWindow::OnFinalRelease()
+{
+ //
+ CFrameWnd::OnFinalRelease();
+}
+
+void CPopupWindow::OnClose()
+{
+ // TODO: Add your message handler code here and/or call default
+ plug->StopEditing();
+ CFrameWnd::OnClose();
+}
diff --git a/PopupWindow.h b/PopupWindow.h
new file mode 100644
index 0000000..32d9ea5
--- /dev/null
+++ b/PopupWindow.h
@@ -0,0 +1,55 @@
+#if !defined(AFX_POPUPWINDOW_H__7B1E2281_5085_4F60_8002_5F79B2CAFFE3__INCLUDED_)
+#define AFX_POPUPWINDOW_H__7B1E2281_5085_4F60_8002_5F79B2CAFFE3__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// PopupWindow.h : header file
+//
+
+class VSTPlugin;
+
+/////////////////////////////////////////////////////////////////////////////
+// CPopupWindow frame
+
+class CPopupWindow : public CFrameWnd
+{
+ DECLARE_DYNCREATE(CPopupWindow)
+// Attributes
+public:
+ CPopupWindow();
+ virtual ~CPopupWindow();
+// Operations
+public:
+ void DoInit();
+ void SetPlugin( VSTPlugin *p);
+ VSTPlugin * plug;
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CPopupWindow)
+ public:
+ virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
+ virtual void OnFinalRelease();
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+
+ // Generated message map functions
+ //{{AFX_MSG(CPopupWindow)
+ afx_msg void OnEnterIdle(UINT nWhy, CWnd* pWho);
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnMove(int x, int y);
+ afx_msg void OnClose();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_POPUPWINDOW_H__7B1E2281_5085_4F60_8002_5F79B2CAFFE3__INCLUDED_)
diff --git a/ReadMe.txt b/ReadMe.txt
new file mode 100644
index 0000000..e144350
--- /dev/null
+++ b/ReadMe.txt
@@ -0,0 +1,57 @@
+VST~
+
+reference: http://iem.kug.ac.at/~jams/
+this plugin uses a tiny amount of code from the plugin~
+object mentioned above. It also tries to replicate the
+syntax
+
+setup
+
+Set environment var to locate your plugins:
+
+set VST_PATH=C:\Program Files\Steinberg\Vstplugins\Plugins archive;C:\Program Files\Steinberg\Vstplugins\VSTPlugs;C:\audio\Cubase5\Vstplugins\VstPlugins;C:\Program Files\Steinberg\Vstplugins
+
+add the following line to your PD startup (editing the path to
+suit)
+
+-lib \VST\Debug\vst
+
+There are three example patches - using Waldorf D-pole, Pro-52
+(helpfully called neontest) and Crazy Diamond http://rumpelrausch.de.vu/
+
+notes:
+
+In order to support plugins with spaces in the name it takes all
+the parameters it is given and assumes they are parts of the
+name with spaces in between. Thus
+
+ vst~ waldorf d-pole
+
+loads the d-pole plugin because it looks for "waldorf d-pole". The
+VST_PATH environment variable is use just like for "Plugin~".
+The two right most inputs are for midi note and velocity and
+work just like the "noteout" object.
+
+There is not currently any support for:
+
+ programs
+ other midi messages
+ help file
+
+ I am in the process of adding all of these. The editor does
+actually work but the window it is in breaks PD so it is disabled
+at present. There are no plans for a graphical interface for
+plugins with no supplied editor - what do you think PD is for ;-)
+
+I have discovered that not all VST plugins behave properly
+- for example I found one called VST_Chopper that crashes
+PD if you print its parameters.
+
+New Stuff:
+
+There are a number of "plugins" that come with Cubase (truetape, double delay etc).
+Despite being in a folder called VSTPLugins these are NOT VST plugins but
+Cubase extentsions. Steinberg themselves told me this.
+
+There is now support for the built in editor. Send an Edit message to the
+plugin to see the graphical editor.
diff --git a/Resource.h b/Resource.h
new file mode 100644
index 0000000..7fe29ce
--- /dev/null
+++ b/Resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by VST.RC
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE 4000
+#define _APS_NEXT_CONTROL_VALUE 4000
+#define _APS_NEXT_SYMED_VALUE 4000
+#define _APS_NEXT_COMMAND_VALUE 32771
+#endif
+#endif
diff --git a/StdAfx.cpp b/StdAfx.cpp
new file mode 100644
index 0000000..5a3a91f
--- /dev/null
+++ b/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// vst.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
+
diff --git a/StdAfx.h b/StdAfx.h
new file mode 100644
index 0000000..ec2d51f
--- /dev/null
+++ b/StdAfx.h
@@ -0,0 +1,42 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__694C13F1_369D_446F_992D_3F454A0993C6__INCLUDED_)
+#define AFX_STDAFX_H__694C13F1_369D_446F_992D_3F454A0993C6__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxole.h> // MFC OLE classes
+#include <afxodlgs.h> // MFC OLE dialog classes
+#include <afxdisp.h> // MFC Automation classes
+#endif // _AFX_NO_OLE_SUPPORT
+
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include <afxdb.h> // MFC ODBC database classes
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include <afxdao.h> // MFC DAO database classes
+#endif // _AFX_NO_DAO_SUPPORT
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__694C13F1_369D_446F_992D_3F454A0993C6__INCLUDED_)
diff --git a/Vst/AEffEditor.h b/Vst/AEffEditor.h
new file mode 100644
index 0000000..16d5fa1
--- /dev/null
+++ b/Vst/AEffEditor.h
@@ -0,0 +1,44 @@
+#ifndef __AEffEditor__
+#define __AEffEditor__
+
+class AudioEffect;
+
+struct ERect
+{
+ short top;
+ short left;
+ short bottom;
+ short right;
+};
+
+class AEffEditor
+{
+public:
+ AEffEditor (AudioEffect *effect) {this->effect = effect; updateFlag = 0; }
+ virtual ~AEffEditor() {}
+
+ virtual long getRect(ERect **rect) {*rect = 0; return 0;}
+ virtual long open(void *ptr) {systemWindow = ptr; return 0;}
+ virtual void close() {}
+ virtual void idle() { if(updateFlag) {updateFlag = 0; update();} }
+
+#if MAC
+ virtual void draw(ERect *rect) {rect = rect;}
+ virtual long mouse(long x, long y) {x = x; y = y; return 0;}
+ virtual long key(long keyCode) {keyCode = keyCode; return 0;}
+ virtual void top() {}
+ virtual void sleep() {}
+#endif
+ virtual void update() {}
+ virtual void postUpdate() {updateFlag = 1;}
+
+protected:
+ AEffEditor () {};
+
+ AudioEffect *effect;
+ void *systemWindow;
+ long updateFlag;
+};
+
+#endif
+
diff --git a/Vst/AEffect.h b/Vst/AEffect.h
new file mode 100644
index 0000000..c6c9557
--- /dev/null
+++ b/Vst/AEffect.h
@@ -0,0 +1,172 @@
+#ifndef __AEffect__
+#define __AEffect__
+
+/*
+ to create an Audio Effect for power pc's, create a
+ code resource
+ file type: 'aPcs'
+ resource type: 'aEff'
+ ppc header: none (raw pef)
+
+ for windows, it's a .dll
+
+ the only symbol searched for is:
+ AEffect *main(float (*audioMaster)(AEffect *effect, long opcode, long index,
+ long value, void *ptr, float opt));
+*/
+
+#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
+ #pragma options align=mac68k
+#elif defined CBUILDER
+ #pragma -a8
+#elif defined(WIN32) || defined(__FLAT__)
+ #pragma pack(push)
+ #pragma pack(8)
+#endif
+
+#if defined(WIN32) || defined(__FLAT__) || defined CBUILDER
+ #define VSTCALLBACK __cdecl
+#else
+ #define VSTCALLBACK
+#endif
+
+//---------------------------------------------------------------------------------------------
+// misc def's
+//---------------------------------------------------------------------------------------------
+
+typedef struct AEffect AEffect;
+typedef long (VSTCALLBACK *audioMasterCallback)(AEffect *effect, long opcode, long index,
+ long value, void *ptr, float opt);
+
+// prototype for plug-in main
+// AEffect *main(audioMasterCallback audioMaster);
+
+#ifdef CBUILDER
+ #define kEffectMagic 'PtsV'
+#else
+ #define kEffectMagic 'VstP'
+#endif
+
+//---------------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------------
+
+struct AEffect
+{
+ long magic; // must be kEffectMagic ('VstP')
+ long (VSTCALLBACK *dispatcher)(AEffect *effect, long opCode, long index, long value,
+ void *ptr, float opt);
+ void (VSTCALLBACK *process)(AEffect *effect, float **inputs, float **outputs, long sampleframes);
+ void (VSTCALLBACK *setParameter)(AEffect *effect, long index, float parameter);
+ float (VSTCALLBACK *getParameter)(AEffect *effect, long index);
+
+ long numPrograms;
+ long numParams; // all programs are assumed to have numParams parameters
+ long numInputs; //
+ long numOutputs; //
+ long flags; // see constants
+ long resvd1; // reserved, must be 0
+ long resvd2; // reserved, must be 0
+ long initialDelay; // for algorithms which need input in the first place
+ long realQualities; // number of realtime qualities (0: realtime)
+ long offQualities; // number of offline qualities (0: realtime only)
+ float ioRatio; // input samplerate to output samplerate ratio, not used yet
+ void *object; // for class access (see AudioEffect.hpp), MUST be 0 else!
+ void *user; // user access
+ long uniqueID; // pls choose 4 character as unique as possible.
+ // this is used to identify an effect for save+load
+ long version; //
+ void (VSTCALLBACK *processReplacing)(AEffect *effect, float **inputs, float **outputs, long sampleframes);
+ char future[60]; // pls zero
+};
+
+
+//---------------------------------------------------------------------------------------------
+// flags bits
+//---------------------------------------------------------------------------------------------
+
+#define effFlagsHasEditor 1 // if set, is expected to react to editor messages
+#define effFlagsHasClip 2 // return > 1. in getVu() if clipped
+#define effFlagsHasVu 4 // return vu value in getVu(); > 1. means clipped
+#define effFlagsCanMono 8 // if numInputs == 2, makes sense to be used for mono in
+#define effFlagsCanReplacing 16 // supports in place output (processReplacing() exsists)
+#define effFlagsProgramChunks 32 // program data are handled in formatless chunks
+
+//---------------------------------------------------------------------------------------------
+// dispatcher opCodes
+//---------------------------------------------------------------------------------------------
+
+enum
+{
+ effOpen = 0, // initialise
+ effClose, // exit, release all memory and other resources!
+
+ effSetProgram, // program no in <value>
+ effGetProgram, // return current program no.
+ effSetProgramName, // user changed program name (max 24 char + 0) to as passed in string
+ effGetProgramName, // stuff program name (max 24 char + 0) into string
+
+ effGetParamLabel, // stuff parameter <index> label (max 8 char + 0) into string
+ // (examples: sec, dB, type)
+ effGetParamDisplay, // stuff parameter <index> textual representation into string
+ // (examples: 0.5, -3, PLATE)
+ effGetParamName, // stuff parameter <index> label (max 8 char + 0) into string
+ // (examples: Time, Gain, RoomType)
+ effGetVu, // called if (flags & (effFlagsHasClip | effFlagsHasVu))
+
+ // system
+
+ effSetSampleRate, // in opt (float)
+ effSetBlockSize, // in value
+ effMainsChanged, // the user has switched the 'power on' button to
+ // value (0 off, else on). This only switches audio
+ // processing; you should flush delay buffers etc.
+ // editor
+
+ effEditGetRect, // stuff rect (top, left, bottom, right) into ptr
+ effEditOpen, // system dependant Window pointer in ptr
+ effEditClose, // no arguments
+ effEditDraw, // draw method, ptr points to rect
+ effEditMouse, // index: x, value: y
+ effEditKey, // system keycode in value
+ effEditIdle, // no arguments. Be gentle!
+ effEditTop, // window has topped, no arguments
+ effEditSleep, // window goes to background
+
+ // new
+
+ effIdentify, // returns 'NvEf'
+ effGetChunk, // host requests pointer to chunk into (void**)ptr, byteSize returned
+ effSetChunk, // plug-in receives saved chunk, byteSize passed
+
+ effNumOpcodes
+};
+
+//---------------------------------------------------------------------------------------------
+// audioMaster opCodes
+//---------------------------------------------------------------------------------------------
+
+enum
+{
+ audioMasterAutomate = 0, // index, value, returns 0
+ audioMasterVersion, // vst version, currently 2 (0 for older)
+ audioMasterCurrentId, // returns the unique id of a plug that's currently
+ // loading
+ audioMasterIdle, // call application idle routine (this will
+ // call effEditIdle for all open editors too)
+ audioMasterPinConnected // inquire if an input or output is beeing connected;
+ // index enumerates input or output counting from zero,
+ // value is 0 for input and != 0 otherwise. note: the
+ // return value is 0 for <true> such that older versions
+ // will always return true.
+
+};
+
+#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
+ #pragma options align=reset
+#elif defined(WIN32) || defined(__FLAT__)
+ #pragma pack(pop)
+#elif defined CBUILDER
+ #pragma -a-
+#endif
+
+#endif // __AEffect__
diff --git a/Vst/AEffectx.h b/Vst/AEffectx.h
new file mode 100644
index 0000000..7dfefbd
--- /dev/null
+++ b/Vst/AEffectx.h
@@ -0,0 +1,534 @@
+#ifndef __aeffectx__
+#define __aeffectx__
+
+#ifndef __AEffect__
+#include "AEffect.h"
+#endif
+
+//-------------------------------------------------------------------------------------------------------
+// VST Plug-Ins SDK
+// version 2.0 extension
+// (c)1999 Steinberg Soft+Hardware GmbH
+//-------------------------------------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------------------------------------
+// VstEvent
+//-------------------------------------------------------------------------------------------------------
+
+typedef struct VstEvent VstEvent;
+typedef struct VstMidiEvent VstMidiEvent;
+typedef struct VstEvents VstEvents;
+
+struct VstEvent // a generic timestamped event
+{
+ long type; // see enum below
+ long byteSize; // of this event, excl. type and byteSize
+ long deltaFrames; // sample frames related to the current block start sample position
+ long flags; // generic flags, none defined yet (0)
+
+ char data[16]; // size may vary but is usually 16
+};
+
+enum // VstEvent types
+{
+ kVstMidiType = 1, // midi event, can be cast as VstMidiEvent (see below)
+ kVstAudioType, // audio
+ kVstVideoType, // video
+ kVstParameterType, // parameter
+ kVstTriggerType // trigger
+ // ...etc
+};
+
+struct VstMidiEvent // to be casted from a VstEvent
+{
+ long type; // kVstMidiType
+ long byteSize; // 24
+ long deltaFrames; // sample frames related to the current block start sample position
+ long flags; // none defined yet
+
+ long noteLength; // (in sample frames) of entire note, if available, else 0
+ long noteOffset; // offset into note from note start if available, else 0
+
+ char midiData[4]; // 1 thru 3 midi bytes; midiData[3] is reserved (zero)
+ char detune; // -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')
+ char noteOffVelocity;
+ char reserved1; // zero
+ char reserved2; // zero
+};
+
+struct VstEvents // a block of events for the current audio block
+{
+ long numEvents;
+ long reserved; // zero
+ VstEvent* events[2]; // variable
+};
+
+//-------------------------------------------------------------------------------------------------------
+// VstTimeInfo
+//-------------------------------------------------------------------------------------------------------
+
+typedef struct VstTimeInfo VstTimeInfo;
+
+// VstTimeInfo as requested via audioMasterGetTime (getTimeInfo())
+// refers to the current time slice. note the new slice is
+// already started when processEvents() is called
+
+struct VstTimeInfo
+{
+ double samplePos; // current location
+ double sampleRate;
+ double nanoSeconds; // system time
+ double ppqPos; // 1 ppq
+ double tempo; // in bpm
+ double barStartPos; // last bar start, in 1 ppq
+ double cycleStartPos; // 1 ppq
+ double cycleEndPos; // 1 ppq
+ long timeSigNumerator; // time signature
+ long timeSigDenominator;
+ long smpteOffset;
+ long smpteFrameRate; // 0:24, 1:25, 2:29.97, 3:30, 4:29.97 df, 5:30 df
+ long samplesToNextClock; // midi clock resolution (24 ppq), can be negative
+ long flags; // see below
+};
+
+enum
+{
+ kVstTransportChanged = 1,
+ kVstTransportPlaying = 1 << 1,
+ kVstTransportCycleActive = 1 << 2,
+
+ kVstAutomationWriting = 1 << 6,
+ kVstAutomationReading = 1 << 7,
+
+ // flags which indicate which of the fields in this VstTimeInfo
+ // are valid; samplePos and sampleRate are always valid
+ kVstNanosValid = 1 << 8,
+ kVstPpqPosValid = 1 << 9,
+ kVstTempoValid = 1 << 10,
+ kVstBarsValid = 1 << 11,
+ kVstCyclePosValid = 1 << 12, // start and end
+ kVstTimeSigValid = 1 << 13,
+ kVstSmpteValid = 1 << 14,
+ kVstClockValid = 1 << 15
+};
+
+//-------------------------------------------------------------------------------------------------------
+// VarIo
+//-------------------------------------------------------------------------------------------------------
+
+typedef struct VstVariableIo VstVariableIo;
+
+struct VstVariableIo
+{
+ float **inputs;
+ float **outputs;
+ long numSamplesInput;
+ long numSamplesOutput;
+ long *numSamplesInputProcessed;
+ long *numSamplesOutputProcessed;
+};
+
+//---------------------------------------------------------------------------------------------
+// new audioMaster opCodes
+//---------------------------------------------------------------------------------------------
+
+enum
+{
+ // VstEvents + VstTimeInfo
+ audioMasterWantMidi = audioMasterPinConnected + 2, // <value> is a filter which is currently ignored
+ audioMasterGetTime, // returns const VstTimeInfo* (or 0 if not supported)
+ // <value> should contain a mask indicating which fields are required
+ // (see valid masks above), as some items may require extensive
+ // conversions
+ audioMasterProcessEvents, // VstEvents* in <ptr>
+ audioMasterSetTime, // VstTimenfo* in <ptr>, filter in <value>, not supported
+ audioMasterTempoAt, // returns tempo (in bpm * 10000) at sample frame location passed in <value>
+
+ // parameters
+ audioMasterGetNumAutomatableParameters,
+ audioMasterGetParameterQuantization, // returns the integer value for +1.0 representation,
+ // or 1 if full single float precision is maintained
+ // in automation. parameter index in <value> (-1: all, any)
+ // connections, configuration
+ audioMasterIOChanged, // numInputs and/or numOutputs has changed
+ audioMasterNeedIdle, // plug needs idle calls (outside its editor window)
+ audioMasterSizeWindow, // index: width, value: height
+ audioMasterGetSampleRate,
+ audioMasterGetBlockSize,
+ audioMasterGetInputLatency,
+ audioMasterGetOutputLatency,
+ audioMasterGetPreviousPlug, // input pin in <value> (-1: first to come), returns cEffect*
+ audioMasterGetNextPlug, // output pin in <value> (-1: first to come), returns cEffect*
+
+ // realtime info
+ audioMasterWillReplaceOrAccumulate, // returns: 0: not supported, 1: replace, 2: accumulate
+ audioMasterGetCurrentProcessLevel, // returns: 0: not supported,
+ // 1: currently in user thread (gui)
+ // 2: currently in audio thread (where process is called)
+ // 3: currently in 'sequencer' thread (midi, timer etc)
+ // 4: currently offline processing and thus in user thread
+ // other: not defined, but probably pre-empting user thread.
+ audioMasterGetAutomationState, // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
+
+ // offline
+ audioMasterOfflineStart,
+ audioMasterOfflineRead, // ptr points to offline structure, see below. return 0: error, 1 ok
+ audioMasterOfflineWrite, // same as read
+ audioMasterOfflineGetCurrentPass,
+ audioMasterOfflineGetCurrentMetaPass,
+
+ // other
+ audioMasterSetOutputSampleRate, // for variable i/o, sample rate in <opt>
+ audioMasterGetSpeakerArrangement, // (long)input in <value>, output in <ptr>
+ audioMasterGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char)
+ audioMasterGetProductString, // fills <ptr> with a string with product name (max 64 char)
+ audioMasterGetVendorVersion, // returns vendor-specific version
+ audioMasterVendorSpecific, // no definition, vendor specific handling
+ audioMasterSetIcon, // void* in <ptr>, format not defined yet
+ audioMasterCanDo, // string in ptr, see below
+ audioMasterGetLanguage, // see enum
+ audioMasterOpenWindow, // returns platform specific ptr
+ audioMasterCloseWindow, // close window, platform specific handle in <ptr>
+ audioMasterGetDirectory, // get plug directory, FSSpec on MAC, else char*
+ audioMasterUpdateDisplay // something has changed, update 'multi-fx' display
+};
+
+enum VstHostLanguage
+{
+ kVstLangEnglish = 1,
+ kVstLangGerman,
+ kVstLangFrench,
+ kVstLangItalian,
+ kVstLangSpanish,
+ kVstLangJapanese
+};
+
+//---------------------------------------------------------------------------------------------
+// dispatcher opCodes
+//---------------------------------------------------------------------------------------------
+
+enum
+{
+ // VstEvents
+ effProcessEvents = effSetChunk + 1, // VstEvents* in <ptr>
+
+ // parameters and programs
+ effCanBeAutomated, // parameter index in <index>
+ effString2Parameter, // parameter index in <index>, string in <ptr>
+ effGetNumProgramCategories, // no arguments. this is for dividing programs into groups (like GM)
+ effGetProgramNameIndexed, // get program name of category <value>, program <index> into <ptr>.
+ // category (that is, <value>) may be -1, in which case program indices
+ // are enumerated linearily (as usual); otherwise, each category starts
+ // over with index 0.
+ effCopyProgram, // copy current program to destination <index>
+ // note: implies setParameter
+ // connections, configuration
+ effConnectInput, // input at <index> has been (dis-)connected;
+ // <value> == 0: disconnected, else connected
+ effConnectOutput, // same as input
+ effGetInputProperties, // <index>, VstPinProperties* in ptr, return != 0 => true
+ effGetOutputProperties, // dto
+ effGetPlugCategory, // no parameter, return value is category
+
+ // realtime
+ effGetCurrentPosition, // for external dsp, see flag bits below
+ effGetDestinationBuffer, // for external dsp, see flag bits below. returns float*
+
+ // offline
+ effOfflineNotify, // ptr = VstAudioFile array, value = count, index = start flag
+ effOfflinePrepare, // ptr = VstOfflineTask array, value = count
+ effOfflineRun, // dto
+
+ // other
+ effProcessVarIo, // VstVariableIo* in <ptr>
+ effSetSpeakerArrangement, // VstSpeakerArrangement* pluginInput in <value>
+ // VstSpeakerArrangement* pluginOutput in <ptr>
+ effSetBlockSizeAndSampleRate, // block size in <value>, sampleRate in <opt>
+ effSetBypass, // onOff in <value> (0 = off)
+ effGetEffectName, // char* name (max 32 bytes) in <ptr>
+ effGetErrorText, // char* text (max 256 bytes) in <ptr>
+ effGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char)
+ effGetProductString, // fills <ptr> with a string with product name (max 64 char)
+ effGetVendorVersion, // returns vendor-specific version
+ effVendorSpecific, // no definition, vendor specific handling
+ effCanDo, // <ptr>
+ effGetTailSize, // returns tail size; 0 is default (return 1 for 'no tail')
+ effIdle, // idle call in response to audioMasterneedIdle. must
+ // return 1 to keep idle calls beeing issued
+
+ // gui
+ effGetIcon, // void* in <ptr>, not yet defined
+ effSetViewPosition, // set view position (in window) to x <index> y <value>
+
+ // and...
+ effGetParameterProperties, // of param <index>, VstParameterProperties* in <ptr>
+ effKeysRequired, // returns 0: needs keys (default for 1.0 plugs), 1: don't need
+ effGetVstVersion, // returns 2; older versions return 0
+
+ effNumV2Opcodes
+ // note that effNumOpcodes doesn't apply anymore
+};
+
+typedef struct VstParameterProperties VstParameterProperties;
+typedef struct VstPinProperties VstPinProperties;
+
+struct VstParameterProperties
+{
+ float stepFloat;
+ float smallStepFloat;
+ float largeStepFloat;
+ char label[64];
+ long flags;
+ long minInteger;
+ long maxInteger;
+ long stepInteger;
+ long largeStepInteger;
+ char shortLabel[8]; // recommended: 6 + delimiter
+ char future[48];
+};
+
+// parameter properties flags
+enum
+{
+ kVstParameterIsSwitch = 1 << 0,
+ kVstParameterUsesIntegerMinMax = 1 << 1,
+ kVstParameterUsesFloatStep = 1 << 2,
+ kVstParameterUsesIntStep = 1 << 3
+};
+
+struct VstPinProperties
+{
+ char label[64];
+ long flags;
+ long reserved;
+ char shortLabel[8]; // recommended: 6 + delimiter
+ char future[48];
+};
+
+// pin properties flags
+enum
+{
+ kVstPinIsActive = 1 << 0,
+ kVstPinIsStereo = 1 << 1
+};
+
+// category
+enum VstPlugCategory
+{
+ kPlugCategUnknown = 0,
+ kPlugCategEffect,
+ kPlugCategSynth,
+ kPlugCategAnalysis,
+ kPlugCategMastering,
+ kPlugCategSpacializer, // 'panners'
+ kPlugCategRoomFx, // delays and reverbs
+ kPlugSurroundFx // dedicated surround processor
+};
+
+//---------------------------------------------------------------------------------------------
+// flags bits
+//---------------------------------------------------------------------------------------------
+
+enum
+{
+ effFlagsIsSynth = 1 << 8, // host may assign mixer channels for its outputs
+ effFlagsNoSoundInStop = 1 << 9, // does not produce sound when input is all silence
+ effFlagsExtIsAsync = 1 << 10, // for external dsp; plug returns immedeately from process()
+ // host polls plug position (current block) via effGetCurrentPosition
+ effFlagsExtHasBuffer = 1 << 11 // external dsp, may have their own output buffe (32 bit float)
+ // host then requests this via effGetDestinationBuffer
+};
+
+//---------------------------------------------------------------------------------------------
+// surround setup
+//---------------------------------------------------------------------------------------------
+
+typedef struct VstSpeakerProperties VstSpeakerProperties;
+typedef struct VstSpeakerArrangement VstSpeakerArrangement;
+
+struct VstSpeakerProperties
+{ // units: range: except:
+ float azimuth; // rad -PI...PI 10.f for LFE channel
+ float elevation; // rad -PI/2...PI/2 10.f for LFE channel
+ float radius; // meter 0.f for LFE channel
+ float reserved; // 0.
+ char name[64]; // for new setups, new names should be given (L/R/C... won't do)
+ char future[32];
+};
+
+// note: the origin for azimuth is right (as by math conventions dealing with radians);
+// the elevation origin is also right, visualizing a rotation of a circle across the
+// -pi/pi axis of the horizontal circle. thus, an elevation of -pi/2 corresponds
+// to bottom, and a speaker standing on the left, and 'beaming' upwards would have
+// an azimuth of -pi, and an elevation of pi/2.
+// for user interface representation, grads are more likely to be used, and the
+// origins will obviously 'shift' accordingly.
+
+struct VstSpeakerArrangement
+{
+ float lfeGain; // LFE channel gain is adjusted [dB] higher than other channels
+ long numChannels; // number of channels in this speaker arrangement
+ VstSpeakerProperties speakers[8]; // variable
+};
+
+//---------------------------------------------------------------------------------------------
+// offline
+//---------------------------------------------------------------------------------------------
+
+typedef struct VstOfflineTask VstOfflineTask;
+typedef struct VstAudioFile VstAudioFile;
+typedef struct VstAudioFileMarker VstAudioFileMarker;
+
+struct VstOfflineTask
+{
+ char processName[96]; // set by plug
+
+ // audio access
+ double readPosition; // set by plug/host
+ double writePosition; // set by plug/host
+ long readCount; // set by plug/host
+ long writeCount; // set by plug
+ long sizeInputBuffer; // set by host
+ long sizeOutputBuffer; // set by host
+ void* inputBuffer; // set by host
+ void* outputBuffer; // set by host
+ double positionToProcessFrom; // set by host
+ double numFramesToProcess; // set by host
+ double maxFramesToWrite; // set by plug
+
+ // other data access
+ void* extraBuffer; // set by plug
+ long value; // set by host or plug
+ long index; // set by host or plug
+
+ // file attributes
+ double numFramesInSourceFile; // set by host
+ double sourceSampleRate; // set by host or plug
+ double destinationSampleRate; // set by host or plug
+ long numSourceChannels; // set by host or plug
+ long numDestinationChannels; // set by host or plug
+ long sourceFormat; // set by host
+ long destinationFormat; // set by plug
+ char outputText[512]; // set by plug or host
+
+ // progress notification
+ double progress; // set by plug
+ long progressMode; // reserved for future
+ char progressText[100]; // set by plug
+
+ long flags; // set by host and plug; see VstOfflineTaskFlags
+ long returnValue; // reserved for future
+ void* hostOwned; // set by host
+ void* plugOwned; // set by plug
+
+ char future[1024];
+};
+
+enum VstOfflineTaskFlags
+{
+ // set by host
+ kVstOfflineUnvalidParameter = 1 << 0,
+ kVstOfflineNewFile = 1 << 1,
+
+ // set by plug
+ kVstOfflinePlugError = 1 << 10,
+ kVstOfflineInterleavedAudio = 1 << 11,
+ kVstOfflineTempOutputFile = 1 << 12,
+ kVstOfflineFloatOutputFile = 1 << 13,
+ kVstOfflineRandomWrite = 1 << 14,
+ kVstOfflineStretch = 1 << 15,
+ kVstOfflineNoThread = 1 << 16
+};
+
+// option passed to offlineRead/offlineWrite
+
+enum VstOfflineOption
+{
+ kVstOfflineAudio, // reading/writing audio samples
+ kVstOfflinePeaks, // reading graphic representation
+ kVstOfflineParameter, // reading/writing parameters
+ kVstOfflineMarker, // reading/writing marker
+ kVstOfflineCursor, // reading/moving edit cursor
+ kVstOfflineSelection, // reading/changing selection
+ kVstOfflineQueryFiles // to request the host to call asynchronously offlineNotify
+};
+
+// structure passed to offlineNotify and offlineStart
+
+struct VstAudioFile
+{
+ long flags; // see enum VstAudioFileFlags
+ void* hostOwned; // any data private to host
+ void* plugOwned; // any data private to plugin
+ char name[100]; // file title
+ long uniqueId; // uniquely identify a file during a session
+ double sampleRate; // file sample rate
+ long numChannels; // number of channels (1 for mono, 2 for stereo...)
+ double numFrames; // number of frames in the audio file
+ long format; // reserved for future
+ double editCursorPosition; // -1 if no such cursor
+ double selectionStart; // frame index of first selected frame, or -1
+ double selectionSize; // number of frames in selection, or 0
+ long selectedChannelsMask; // 1 bit per channel
+ long numMarkers; // number of markers in the file
+ long timeRulerUnit; // see doc for possible values
+ double timeRulerOffset; // offset in time ruler (positive or negative)
+ double tempo; // as bpm
+ long timeSigNumerator; // time signature numerator
+ long timeSigDenominator; // time signature denominator
+ long ticksPerBlackNote; // resolution
+ long smpteFrameRate; // smpte rate (set as in VstTimeInfo)
+
+ char future[64];
+};
+
+enum VstAudioFileFlags
+{
+ // set by host (in call offlineNotify)
+ kVstOfflineReadOnly = 1 << 0,
+ kVstOfflineNoRateConversion = 1 << 1,
+ kVstOfflineNoChannelChange = 1 << 2,
+
+ // Set by plug (in function offlineStart)
+ kVstOfflineCanProcessSelection = 1 << 10,
+ kVstOfflineNoCrossfade = 1 << 11,
+ kVstOfflineWantRead = 1 << 12,
+ kVstOfflineWantWrite = 1 << 13,
+ kVstOfflineWantWriteMarker = 1 << 14,
+ kVstOfflineWantMoveCursor = 1 << 15,
+ kVstOfflineWantSelect = 1 << 16
+};
+
+struct VstAudioFileMarker
+{
+ double position;
+ char name[32];
+ long type;
+ long id;
+ long reserved;
+};
+
+//---------------------------------------------------------------------------------------------
+// others
+//---------------------------------------------------------------------------------------------
+
+// structure passed to openWindow and closeWindow
+
+struct VstWindow
+{
+ char title[128]; // title
+ short xPos; // position and size
+ short yPos;
+ short width;
+ short height;
+ long style; // 0: with title, 1: without title
+
+ void *parent; // parent of this window
+ void *userHandle; // reserved
+ void *winHandle; // reserved
+
+ char future[104];
+};
+
+#endif
+
diff --git a/Vst/AudioEffect.hpp b/Vst/AudioEffect.hpp
new file mode 100644
index 0000000..08eb6d1
--- /dev/null
+++ b/Vst/AudioEffect.hpp
@@ -0,0 +1,109 @@
+#ifndef __AudioEffect__
+#define __AudioEffect__
+
+#include "AEffect.h" // "c" interface
+#include <string.h>
+
+class AEffEditor;
+class AudioEffect;
+
+// Needs to be defined by the audio effect and is
+// called to create the audio effect object instance.
+AudioEffect* createEffectInstance (audioMasterCallback audioMaster);
+
+long dispatchEffectClass(AEffect *e,
+ long opCode, long index, long value, void *ptr, float opt);
+float getParameterClass(long index);
+void setParameterClass(long index, float value);
+void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames);
+void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames);
+
+class AudioEffect
+{
+friend class AEffEditor;
+friend long dispatchEffectClass(AEffect *e, long opCode, long index, long value, void *ptr, float opt);
+friend float getParameterClass(AEffect *e, long index);
+friend void setParameterClass(AEffect *e, long index, float value);
+friend void processClass(AEffect *e, float **inputs, float **outputs, long sampleFrames);
+friend void processClassReplacing(AEffect *e, float **inputs, float **outputs, long sampleFrames);
+
+public:
+ AudioEffect(audioMasterCallback audioMaster, long numPrograms, long numParams);
+ virtual ~AudioEffect();
+
+ virtual void setParameter(long index, float value) {index = index; value = value;}
+ virtual float getParameter(long index) {index = index; return 0;}
+ virtual void setParameterAutomated(long index, float value);
+
+ AEffect *getAeffect() {return &cEffect;}
+ void setEditor(AEffEditor *editor)
+ { this->editor = editor;
+ if(editor) cEffect.flags |= effFlagsHasEditor;
+ else cEffect.flags &= ~effFlagsHasEditor;}
+
+ // called from audio master
+ virtual void process(float **inputs, float **outputs, long sampleFrames) = 0;
+ virtual void processReplacing(float **inputs, float **outputs, long sampleFrames)
+ {inputs = inputs; outputs = outputs; sampleFrames = sampleFrames;}
+ virtual long dispatcher(long opCode, long index, long value, void *ptr, float opt);
+ virtual void open() {}
+ virtual void close() {}
+ virtual long getProgram() {return curProgram;}
+ virtual void setProgram(long program) {curProgram = program;} // don't forget to set curProgram
+ virtual void setProgramName(char *name) {*name = 0;} // all following refer to curProgram
+ virtual void getProgramName(char *name) {*name = 0;}
+ virtual void getParameterLabel(long index, char *label) {index = index; *label = 0;}
+ virtual void getParameterDisplay(long index, char *text) {index = index; *text = 0;}
+ virtual void getParameterName(long index, char *text) {index = index; *text = 0;}
+ virtual float getVu() {return 0;}
+ virtual long getChunk(void** data, bool isPreset = false) {return 0;} // returns byteSize
+ virtual long setChunk(void* data, long byteSize, bool isPreset = false) {return 0;}
+ virtual void setSampleRate(float sampleRate) {this->sampleRate = sampleRate;}
+ virtual void setBlockSize(long blockSize) {this->blockSize = blockSize;}
+ virtual void suspend() {}
+ virtual void resume() {}
+
+ // setup
+ virtual void setUniqueID(long iD) {cEffect.uniqueID = iD;} // must call this!
+ virtual void setNumInputs(long inputs) {cEffect.numInputs = inputs;}
+ virtual void setNumOutputs(long outputs) {cEffect.numOutputs = outputs;}
+ virtual void hasVu(bool state = true);
+ virtual void hasClip(bool state = true);
+ virtual void canMono(bool state = true);
+ virtual void canProcessReplacing(bool state = true);
+ virtual void programsAreChunks(bool state = true);
+ virtual void setRealtimeQualities(long qualities);
+ virtual void setOfflineQualities(long qualities);
+ virtual void setInitialDelay(long delay);
+
+ // inquiry
+ virtual float getSampleRate() {return sampleRate;}
+ virtual long getBlockSize() {return blockSize;}
+
+ // host communication
+ virtual long getMasterVersion();
+ virtual long getCurrentUniqueId();
+ virtual void masterIdle();
+ virtual bool isInputConnected(long input);
+ virtual bool isOutputConnected(long output);
+
+ // tools
+ virtual void dB2string(float value, char *text);
+ virtual void Hz2string(float samples, char *text);
+ virtual void ms2string(float samples, char *text);
+ virtual void float2string(float value, char *string);
+ virtual void long2string(long value, char *text);
+
+protected:
+ // members
+ float sampleRate;
+ AEffEditor *editor;
+ audioMasterCallback audioMaster;
+ long numPrograms;
+ long numParams;
+ long curProgram;
+ long blockSize;
+ AEffect cEffect;
+};
+
+#endif
diff --git a/Vst/audioeffectx.h b/Vst/audioeffectx.h
new file mode 100644
index 0000000..435a63e
--- /dev/null
+++ b/Vst/audioeffectx.h
@@ -0,0 +1,185 @@
+#ifndef __audioeffectx__
+#define __audioeffectx__
+
+//----------------------------------------------------------------------------------------------------------------------------
+// VST Plug-Ins SDK
+// version 2.0 extension
+// (c)1999 Steinberg Soft+Hardware GmbH
+//----------------------------------------------------------------------------------------------------------------------------
+
+#ifndef __AudioEffect__
+#include "AudioEffect.hpp" // version 1.0 base class AudioEffect
+#endif
+
+#ifndef __aeffectx__
+#include "aeffectx.h" // version 2.0 'C' extensions and structures
+#endif
+
+//----------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------------
+// AudioEffectX extends AudioEffect with the new features. so you should derive
+// your plug from AudioEffectX
+//----------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------------
+
+class AudioEffectX : public AudioEffect
+{
+public:
+ AudioEffectX (audioMasterCallback audioMaster, long numPrograms, long numParams);
+ virtual ~AudioEffectX ();
+
+ virtual long dispatcher (long opCode, long index, long value, void *ptr, float opt);
+
+ // 'host' are methods which go from plug to host, and are usually not overridden
+ // 'plug' are methods which you may override to implement the according functionality (to host)
+
+//----------------------------------------------------------------------------------------------------------------------------
+// events + time
+//----------------------------------------------------------------------------------------------------------------------------
+
+ // host
+ virtual void wantEvents (long filter = 1); // filter is currently ignored, midi channel data only (default)
+ virtual VstTimeInfo* getTimeInfo (long filter);
+ // returns const VstTimeInfo* (or 0 if not supported)
+ // filter should contain a mask indicating which fields are requested
+ // (see valid masks in aeffectx.h), as some items may require extensive
+ // conversions
+ virtual long tempoAt (long pos); // returns tempo (in bpm * 10000) at sample frame location <pos>
+ bool sendVstEventsToHost (VstEvents* events); // true:success
+
+ // plug
+ virtual long processEvents (VstEvents* events) {return 0;} // wants no more...else return 1!
+ // VstEvents and VstMidiEvents are declared in aeffectx.h
+
+//----------------------------------------------------------------------------------------------------------------------------
+// parameters and programs
+//----------------------------------------------------------------------------------------------------------------------------
+
+ // host
+ virtual long getNumAutomatableParameters ();
+ virtual long getParameterQuantization (); // returns the integer value for +1.0 representation,
+ // or 1 if full single float precision is maintained
+ // in automation. parameter index in <value> (-1: all, any)
+ // plug
+ virtual bool canParameterBeAutomated (long index) { return true; }
+ virtual bool string2parameter (long index, char* text) {return false;} // note: implies setParameter. text==0 is to be
+ // expected to check the capability (returns true).
+ virtual float getChannelParameter (long channel, long index) {return 0;}
+ virtual long getNumCategories () {return 1L;}
+ virtual bool getProgramNameIndexed (long category, long index, char* text) {return false;}
+ virtual bool copyProgram (long destination) {return false;}
+
+//----------------------------------------------------------------------------------------------------------------------------
+// connections, configuration
+//----------------------------------------------------------------------------------------------------------------------------
+
+ // host
+ virtual bool ioChanged (); // tell host numInputs and/or numOutputs and/or numParameters has changed
+ virtual bool needIdle (); // plug needs idle calls (outside its editor window)
+ virtual bool sizeWindow (long width, long height);
+ virtual double updateSampleRate (); // gets and returns sample rate from host (may issue setSampleRate() )
+ virtual long updateBlockSize (); // same for block size
+ virtual long getInputLatency ();
+ virtual long getOutputLatency ();
+ virtual AEffect* getPreviousPlug (long input); // input can be -1 in which case the first found is returned
+ virtual AEffect* getNextPlug (long output); // output can be -1 in which case the first found is returned
+
+ // plug
+ virtual void inputConnected (long index, bool state) {} // input at <index> has been (dis-)connected,
+ virtual void outputConnected (long index, bool state) {} // same as input; state == true: connected
+ virtual bool getInputProperties (long index, VstPinProperties* properties) {return false;}
+ virtual bool getOutputProperties (long index, VstPinProperties* properties) {return false;}
+ virtual VstPlugCategory getPlugCategory()
+ { if (cEffect.flags & effFlagsIsSynth) return kPlugCategSynth; return kPlugCategUnknown; }
+
+//----------------------------------------------------------------------------------------------------------------------------
+// realtime
+//----------------------------------------------------------------------------------------------------------------------------
+
+ // host
+ virtual long willProcessReplacing (); // returns 0: not implemented, 1: replacing, 2: accumulating
+ virtual long getCurrentProcessLevel (); // returns: 0: not supported,
+ // 1: currently in user thread (gui)
+ // 2: currently in audio thread or irq (where process is called)
+ // 3: currently in 'sequencer' thread or irq (midi, timer etc)
+ // 4: currently offline processing and thus in user thread
+ // other: not defined, but probably pre-empting user thread.
+ virtual long getAutomationState (); // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
+ virtual void wantAsyncOperation (bool state = true); // notify host that we want to operate asynchronously.
+ // process() will return immedeately; host will poll getCurrentPosition
+ // to see if data are available in time.
+ virtual void hasExternalBuffer (bool state = true); // external dsp, may have their own output buffe (32 bit float)
+ // host then requests this via effGetDestinationBuffer
+
+ // plug
+ virtual long reportCurrentPosition () {return 0;} // for external dsp, see wantAsyncOperation ()
+ virtual float* reportDestinationBuffer () {return 0;} // for external dsp (dma option)
+
+//----------------------------------------------------------------------------------------------------------------------------
+// offline
+//----------------------------------------------------------------------------------------------------------------------------
+
+ // host
+ virtual bool offlineRead (VstOfflineTask* offline, VstOfflineOption option, bool readSource = true);
+ virtual bool offlineWrite (VstOfflineTask* offline, VstOfflineOption option);
+ virtual bool offlineStart (VstAudioFile* ptr, long numAudioFiles, long numNewAudioFiles);
+ virtual long offlineGetCurrentPass ();
+ virtual long offlineGetCurrentMetaPass ();
+
+ // plug
+ virtual bool offlineNotify (VstAudioFile* ptr, long numAudioFiles, bool start) { return false; }
+ virtual bool offlinePrepare (VstOfflineTask* offline, long count) {return false;}
+ virtual bool offlineRun (VstOfflineTask* offline, long count) {return false;}
+
+ virtual long offlineGetNumPasses () {return 0;}
+ virtual long offlineGetNumMetaPasses () {return 0;}
+
+//----------------------------------------------------------------------------------------------------------------------------
+// other
+//----------------------------------------------------------------------------------------------------------------------------
+
+ // host
+ virtual void setOutputSamplerate (float samplerate);
+ virtual bool getSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput);
+ virtual bool getHostVendorString (char* text); // fills <text> with a string identifying the vendor (max 64 char)
+ virtual bool getHostProductString (char* text); // fills <text> with a string with product name (max 64 char)
+ virtual long getHostVendorVersion (); // returns vendor-specific version
+ virtual long hostVendorSpecific (long lArg1, long lArg2, void* ptrArg, float floatArg); // no definition
+ virtual long canHostDo (char* text); // see 'hostCanDos' in audioeffectx.cpp
+ // returns 0: don't know (default), 1: yes, -1: no
+ virtual void isSynth (bool state = true); // will call wantEvents if true
+ virtual void noTail (bool state = true); // true: tells host we produce no output when silence comes in
+ // enables host to omit process() when no data are present
+ // on any one input.
+ virtual long getHostLanguage (); // returns VstHostLanguage
+ virtual void* openWindow (VstWindow*); // create new window
+ virtual bool closeWindow (VstWindow*); // close a newly created window
+ virtual void* getDirectory (); // get the plug's directory, FSSpec on mac, else char*
+ virtual bool updateDisplay(); // something has changed, update 'multi-fx' display
+ // returns true if supported
+
+ // plug
+ virtual bool processVariableIo (VstVariableIo* varIo) {return false;}
+ virtual bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput, VstSpeakerArrangement* pluginOutput) {return false;}
+ virtual void setBlockSizeAndSampleRate (long blockSize, float sampleRate)
+ {this->blockSize = blockSize; this->sampleRate = sampleRate;}
+ virtual bool setBypass(bool onOff) {return false;} // for 'soft-bypass; process() still called
+ virtual bool getEffectName (char* name) {return false;} // name max 32 char
+ virtual bool getErrorText (char* text) {return false;} // max 256 char
+ virtual bool getVendorString (char* text) {return false;} // fill text with a string identifying the vendor (max 64 char)
+ virtual bool getProductString (char* text) {return false;} // fill text with a string identifying the product name (max 64 char) // fills <ptr> with a string with product name (max 64 char)
+ virtual long getVendorVersion () {return 0;} // return vendor-specific version
+ virtual long vendorSpecific (long lArg, long lArg2, void* ptrArg, float floatArg) {return 0;}
+ // no definition, vendor specific handling
+ virtual long canDo (char* text) {return 0;} // see 'plugCanDos' in audioeffectx.cpp. return values:
+ // 0: don't know (default), 1: yes, -1: no
+ virtual void* getIcon () {return 0;} // not yet defined
+ virtual bool setViewPosition (long x, long y) {return false;}
+ virtual long getGetTailSize () {return 0; }
+ virtual long fxIdle () {return 0;}
+ virtual bool getParameterProperties (long index, VstParameterProperties* p) {return false;}
+ virtual bool keysRequired () {return false;} // version 1 plugs will return true
+ virtual long getVstVersion () {return 2;}
+};
+
+#endif
diff --git a/VstHost.cpp b/VstHost.cpp
new file mode 100644
index 0000000..d93f7f9
--- /dev/null
+++ b/VstHost.cpp
@@ -0,0 +1,581 @@
+#include "stdafx.h"
+#include "m_pd.h"
+#include "EditorThread.h"
+#include "VstHost.h"
+#include "PopupWindow.h"
+#include "vst\aeffeditor.h"
+#include "vst\aeffectx.h"
+
+
+VstTimeInfo VSTPlugin::_timeInfo;
+
+float VSTPlugin::sample_rate = 44100;
+
+
+////////////////////
+//
+/////////////////////
+VSTPlugin::VSTPlugin()
+{
+ queue_size=0;
+ _sDllName = NULL;
+ h_dll=NULL;
+ instantiated=false; // Constructin' with no instance
+ overwrite = false;
+ w = GetForegroundWindow();
+ show_params = false;
+ _midichannel = 0;
+ edited = false;
+}
+
+VSTPlugin::~VSTPlugin()
+{
+ Free(); // Call free
+ delete _sDllName; // if _sDllName = NULL , the operation does nothing -> it's safe.
+}
+
+int VSTPlugin::Instance( const char *dllname)
+{
+ h_dll=LoadLibrary(dllname);
+
+ if(h_dll==NULL)
+ {
+ return VSTINSTANCE_ERR_NO_VALID_FILE;
+ }
+ post("Loaded library %s" , dllname);
+ PVSTMAIN main = (PVSTMAIN)GetProcAddress(h_dll,"main");
+ if(!main)
+ {
+ FreeLibrary(h_dll);
+ _pEffect=NULL;
+ instantiated=false;
+ return VSTINSTANCE_ERR_NO_VST_PLUGIN;
+ }
+ //post("Found main function - about to call it");
+ //This calls the "main" function and receives the pointer to the AEffect structure.
+ _pEffect = main((audioMasterCallback)&(this->Master));
+
+ if(!_pEffect)
+ {
+ post("VST plugin : unable to create effect");
+ FreeLibrary(h_dll);
+ _pEffect=NULL;
+ instantiated=false;
+ return VSTINSTANCE_ERR_REJECTED;
+ }
+
+ if( _pEffect->magic!=kEffectMagic)
+ {
+ post("VST plugin : Instance query rejected by 0x%.8X\n",(int)_pEffect);
+ FreeLibrary(h_dll);
+ _pEffect=NULL;
+ instantiated=false;
+ return VSTINSTANCE_ERR_REJECTED;
+ }
+
+ //post("VST plugin : Instanced at (Effect*): %.8X\n",(int)_pEffect);
+
+ //init plugin
+ _pEffect->user = this;
+ Dispatch( effOpen , 0, 0, NULL, 0.0f);
+ Dispatch( effSetProgram , 0, 0, NULL, 0.0f);
+// Dispatch( effMainsChanged, 0, 1, NULL, 0.0f);
+
+ //************************************set samplerate and stream size here
+ // we get it when we init our DSP
+
+// Dispatch( effSetSampleRate, 0, 0, NULL, (float)Global::pConfig->_pOutputDriver->_samplesPerSec);
+// Dispatch( effSetBlockSize, 0, STREAM_SIZE, NULL, 0.0f);
+
+
+ if (!Dispatch( effGetProductString, 0, 0, &_sProductName, 0.0f))
+ {
+ CString str1(dllname);
+ CString str2 = str1.Mid(str1.ReverseFind('\\')+1);
+ int snip = str2.Find('.');
+ if ( snip != -1 )
+ {
+ str1 = str2.Left( snip );
+ }
+ else
+ {
+ str1 = str2;
+ }
+ strcpy(_sProductName,str1);
+
+ }
+
+ if (!_pEffect->dispatcher(_pEffect, effGetVendorString, 0, 0, &_sVendorName, 0.0f))
+ {
+ strcpy(_sVendorName, "Unknown vendor");
+ }
+ _version = _pEffect->version;
+ _isSynth = (_pEffect->flags & effFlagsIsSynth)?true:false;
+ overwrite = (_pEffect->flags & effFlagsCanReplacing)?true:false;
+ editor = (_pEffect->flags & effFlagsHasEditor)?true:false;
+
+ if ( _sDllName != NULL ) delete _sDllName;
+ _sDllName = new char[strlen(dllname)+1];
+ sprintf(_sDllName,dllname);
+
+
+
+
+ //keep plugin name
+ instantiated=true;
+
+ return VSTINSTANCE_NO_ERROR;
+}
+
+int VSTPlugin::getNumInputs( void )
+{
+ return _pEffect->numInputs;
+}
+
+int VSTPlugin::getNumOutputs( void )
+{
+ return _pEffect->numOutputs;
+}
+
+
+void VSTPlugin::Create(VSTPlugin *plug)
+{
+ h_dll=plug->h_dll;
+ _pEffect=plug->_pEffect;
+ _pEffect->user=this;
+ Dispatch( effMainsChanged, 0, 1, NULL, 0.0f);
+// strcpy(_editName,plug->_editName); On current implementation, this replaces the right one.
+ strcpy(_sProductName,plug->_sProductName);
+ strcpy(_sVendorName,plug->_sVendorName);
+
+ _sDllName = new char[strlen(plug->_sDllName)+1];
+ strcpy(_sDllName,plug->_sDllName);
+
+ _isSynth=plug->_isSynth;
+ _version=plug->_version;
+
+ plug->instantiated=false; // We are "stoling" the plugin from the "plug" object so this
+ // is just a "trick" so that when destructing the "plug", it
+ // doesn't unload the Dll.
+ instantiated=true;
+}
+
+void VSTPlugin::Free() // Called also in destruction
+{
+ if(instantiated)
+ {
+ instantiated=false;
+ post("VST plugin : Free query 0x%.8X\n",(int)_pEffect);
+ _pEffect->user = NULL;
+ Dispatch( effMainsChanged, 0, 0, NULL, 0.0f);
+ Dispatch( effClose, 0, 0, NULL, 0.0f);
+// delete _pEffect; // <- Should check for the necessity of this command.
+ _pEffect=NULL;
+ FreeLibrary(h_dll);
+ }
+}
+
+void VSTPlugin::Init( float samplerate , float blocksize )
+{
+ sample_rate = samplerate;
+ Dispatch(effOpen , 0, 0, NULL, 0.f);
+ Dispatch(effMainsChanged, 0, 1, NULL, 0.f);
+ Dispatch(effSetSampleRate, 0, 0, 0, (float) sample_rate );
+ Dispatch(effSetBlockSize, 0, blocksize, NULL, 0.f );
+}
+
+
+bool VSTPlugin::DescribeValue(int p,char* psTxt)
+{
+ int parameter = p;
+ if(instantiated)
+ {
+ if(parameter<_pEffect->numParams)
+ {
+// char par_name[64];
+ char par_display[64];
+ char par_label[64];
+
+// Dispatch(effGetParamName,parameter,0,par_name,0.0f);
+ Dispatch(effGetParamDisplay,parameter,0,par_display,0.0f);
+ Dispatch(effGetParamLabel,parameter,0,par_label,0.0f);
+// sprintf(psTxt,"%s:%s%s",par_name,par_display,par_label);
+ sprintf(psTxt,"%s%s",par_display,par_label);
+ return true;
+ }
+ else sprintf(psTxt,"NumParams Exeeded");
+ }
+ else sprintf(psTxt,"Not loaded");
+
+ return false;
+}
+
+bool VSTPlugin::SetParameter(int parameter, float value)
+{
+ if(instantiated)
+ {
+ if (( parameter >= 0 ) && (parameter<=_pEffect->numParams))
+ {
+ _pEffect->setParameter(_pEffect,parameter,value);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool VSTPlugin::SetParameter(int parameter, int value)
+{
+ return SetParameter(parameter,value/65535.0f);
+}
+
+int VSTPlugin::GetCurrentProgram()
+{
+ if(instantiated)
+ return Dispatch(effGetProgram,0,0,NULL,0.0f);
+ else
+ return 0;
+}
+
+void VSTPlugin::SetCurrentProgram(int prg)
+{
+ if(instantiated)
+ Dispatch(effSetProgram,0,prg,NULL,0.0f);
+}
+
+bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2)
+{
+ if (instantiated)
+ {
+ VstMidiEvent* pevent=&midievent[queue_size];
+
+ pevent->type = kVstMidiType;
+ pevent->byteSize = 24;
+ pevent->deltaFrames = 0;
+ pevent->flags = 0;
+ pevent->detune = 0;
+ pevent->noteLength = 0;
+ pevent->noteOffset = 0;
+ pevent->reserved1 = 0;
+ pevent->reserved2 = 0;
+ pevent->noteOffVelocity = 0;
+ pevent->midiData[0] = data0;
+ pevent->midiData[1] = data1;
+ pevent->midiData[2] = data2;
+ pevent->midiData[3] = 0;
+
+ if ( queue_size < MAX_EVENTS ) queue_size++;
+ SendMidi();
+ return true;
+ }
+ else return false;
+}
+
+
+void VSTPlugin::SendMidi()
+{
+ if(/*instantiated &&*/ queue_size>0)
+ {
+ // Prepare MIDI events and free queue dispatching all events
+ events.numEvents = queue_size;
+ events.reserved = 0;
+ for(int q=0;q<queue_size;q++) events.events[q] = (VstEvent*)&midievent[q];
+
+ Dispatch(effProcessEvents, 0, 0, &events, 0.0f);
+ queue_size=0;
+ }
+}
+
+
+void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes )
+{
+ _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes );
+
+}
+
+void VSTPlugin::process( float **inputs, float **outputs, long sampleframes )
+{
+ _pEffect->process( _pEffect , inputs , outputs , sampleframes );
+}
+
+
+// Host callback dispatcher
+long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+{
+ //post("VST plugin call to host dispatcher: Eff: 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
+ //st( "audioMasterWantMidi %d " , audioMasterWantMidi);
+
+ // Support opcodes
+ switch(opcode)
+ {
+ case audioMasterAutomate:
+ return 0; // index, value, returns 0
+
+ case audioMasterVersion:
+ return 9; // vst version, currently 7 (0 for older)
+
+ case audioMasterCurrentId:
+ return 'AASH'; // returns the unique id of a plug that's currently loading
+
+ case audioMasterIdle:
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0; // call application idle routine (this will call effEditIdle for all open editors too)
+
+ case audioMasterPinConnected:
+ return false; // inquire if an input or output is beeing connected;
+
+ case audioMasterWantMidi:
+ return 0;
+
+ case audioMasterProcessEvents:
+ return 0; // Support of vst events to host is not available
+
+ case audioMasterGetTime:
+ memset(&_timeInfo, 0, sizeof(_timeInfo));
+ _timeInfo.samplePos = 0;
+ _timeInfo.sampleRate = sample_rate;
+ return (long)&_timeInfo;
+
+
+ case audioMasterTempoAt:
+ return 0;
+
+ case audioMasterNeedIdle:
+ effect->dispatcher(effect, effIdle, 0, 0, NULL, 0.0f);
+ return 1;
+
+ case audioMasterGetSampleRate:
+ return sample_rate;
+
+ case audioMasterGetVendorString: // Just fooling version string
+ strcpy((char*)ptr,"Steinberg");
+ return 0;
+
+ case audioMasterGetVendorVersion:
+ return 5000; // HOST version 5000
+
+ case audioMasterGetProductString: // Just fooling product string
+ strcpy((char*)ptr,"Cubase 5.0");
+ return 0;
+
+ case audioMasterVendorSpecific:
+ {
+ return 0;
+ }
+
+
+ case audioMasterGetLanguage:
+ return kVstLangEnglish;
+
+ case audioMasterUpdateDisplay:
+ post("audioMasterUpdateDisplay");
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+
+ case audioMasterSetTime: post("VST master dispatcher: Set Time");break;
+ case audioMasterGetNumAutomatableParameters: post("VST master dispatcher: GetNumAutPar");break;
+ case audioMasterGetParameterQuantization: post("VST master dispatcher: ParamQuant");break;
+ case audioMasterIOChanged: post("VST master dispatcher: IOchanged");break;
+ case audioMasterSizeWindow: post("VST master dispatcher: Size Window");break;
+ case audioMasterGetBlockSize: post("VST master dispatcher: GetBlockSize");break;
+ case audioMasterGetInputLatency: post("VST master dispatcher: GetInLatency");break;
+ case audioMasterGetOutputLatency: post("VST master dispatcher: GetOutLatency");break;
+ case audioMasterGetPreviousPlug: post("VST master dispatcher: PrevPlug");break;
+ case audioMasterGetNextPlug: post("VST master dispatcher: NextPlug");break;
+ case audioMasterWillReplaceOrAccumulate: post("VST master dispatcher: WillReplace"); break;
+ case audioMasterGetCurrentProcessLevel: return 0; break;
+ case audioMasterGetAutomationState: post("VST master dispatcher: GetAutState");break;
+ case audioMasterOfflineStart: post("VST master dispatcher: Offlinestart");break;
+ case audioMasterOfflineRead: post("VST master dispatcher: Offlineread");break;
+ case audioMasterOfflineWrite: post("VST master dispatcher: Offlinewrite");break;
+ case audioMasterOfflineGetCurrentPass: post("VST master dispatcher: OfflineGetcurrentpass");break;
+ case audioMasterOfflineGetCurrentMetaPass: post("VST master dispatcher: GetGetCurrentMetapass");break;
+ case audioMasterSetOutputSampleRate: post("VST master dispatcher: Setsamplerate");break;
+ case audioMasterGetSpeakerArrangement: post("VST master dispatcher: Getspeaker");break;
+ case audioMasterSetIcon: post("VST master dispatcher: seticon");break;
+ case audioMasterCanDo: post("VST master dispatcher: Can Do");break;
+ case audioMasterOpenWindow: post("VST master dispatcher: OpenWindow");break;
+ case audioMasterCloseWindow: post("VST master dispatcher: CloseWindow");break;
+ case audioMasterGetDirectory: post("VST master dispatcher: GetDirectory");break;
+// case audioMasterUpdateDisplay: post("VST master dispatcher: audioMasterUpdateDisplay");break;
+
+ default: post("VST master dispatcher: undefed: %d , %d",opcode , effKeysRequired ) ;break;
+ }
+
+
+ return 0;
+}
+
+bool VSTPlugin::AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel)
+{
+ if(instantiated)
+ {
+ VstMidiEvent* pevent=&midievent[queue_size];
+
+ pevent->type = kVstMidiType;
+ pevent->byteSize = 24;
+ pevent->deltaFrames = 0;
+ pevent->flags = 0;
+ pevent->detune = 0;
+ pevent->noteLength = 0;
+ pevent->noteOffset = 0;
+ pevent->reserved1 = 0;
+ pevent->reserved2 = 0;
+ pevent->noteOffVelocity = 0;
+ pevent->midiData[0] = (char)MIDI_NOTEON | midichannel; // Midi On
+ pevent->midiData[1] = note;
+ pevent->midiData[2] = speed;
+ pevent->midiData[3] = 0;
+
+ if ( queue_size < MAX_EVENTS ) queue_size++;
+ SendMidi();
+ return true;
+ }
+ else return false;
+
+
+}
+
+bool VSTPlugin::AddNoteOff( unsigned char note,unsigned char midichannel)
+{
+ if (instantiated)
+ {
+
+ VstMidiEvent* pevent=&midievent[queue_size];
+
+ pevent->type = kVstMidiType;
+ pevent->byteSize = 24;
+ pevent->deltaFrames = 0;
+ pevent->flags = 0;
+ pevent->detune = 0;
+ pevent->noteLength = 0;
+ pevent->noteOffset = 0;
+ pevent->reserved1 = 0;
+ pevent->reserved2 = 0;
+ pevent->noteOffVelocity = 0;
+ pevent->midiData[0] = (char)MIDI_NOTEOFF | midichannel; // Midi Off
+ pevent->midiData[1] = note;
+ pevent->midiData[2] = 0;
+ pevent->midiData[3] = 0;
+
+ if ( queue_size < MAX_EVENTS ) queue_size++;
+
+ SendMidi();
+ return true;
+
+ }
+ else return false;
+}
+
+
+bool VSTPlugin::replace()
+{
+ return overwrite;
+}
+
+
+void VSTPlugin::edit()
+{
+ if(instantiated)
+ {
+ if ( ( editor ) && (!edited))
+ {
+ edited = true;
+ //b = (CEditorThread*) AfxBeginThread(RUNTIME_CLASS( CEditorThread ) );
+ b = new CEditorThread();
+ b->SetPlugin( this );
+ b->CreateThread();
+ }
+ }
+}
+
+void VSTPlugin::EditorIdle()
+{
+ Dispatch(effEditIdle,0,0, w,0.0f);
+}
+
+RECT VSTPlugin::GetEditorRect()
+{
+ RECT ret;
+ ERect *r;
+ Dispatch(effEditGetRect,0,0, &r,0.0f);
+ ret.top = r->top;
+ ret.bottom = r->bottom;
+ ret.left = r->left;
+ ret.right = r->right;
+ return ret;
+}
+
+void VSTPlugin::SetEditWindow(HWND h)
+{
+ w = h;
+ Dispatch(effEditOpen,0,0, w,0.0f);
+}
+
+void VSTPlugin::OnEditorCLose()
+{
+ Dispatch(effEditClose,0,0, w,0.0f);
+}
+
+void VSTPlugin::SetShowParameters(bool s)
+{
+ show_params = s;
+}
+
+bool VSTPlugin::ShowParams()
+{
+ return show_params;
+}
+
+void VSTPlugin::AddAftertouch(int value)
+{
+ if (value < 0) value = 0; else if (value > 127) value = 127;
+ AddMIDI( (char)MIDI_NOTEOFF | _midichannel , value );
+}
+
+void VSTPlugin::AddPitchBend(int value)
+{
+ AddMIDI( MIDI_PITCHBEND + (_midichannel & 0xf) , ((value>>7) & 127), (value & 127));
+}
+
+void VSTPlugin::AddProgramChange(int value)
+{
+ if (value < 0) value = 0; else if (value > 127) value = 127;
+ AddMIDI( MIDI_PROGRAMCHANGE + (_midichannel & 0xf), value, 0);
+}
+
+void VSTPlugin::AddControlChange(int control, int value)
+{
+ if (control < 0) control = 0; else if (control > 127) control = 127;
+ if (value < 0) value = 0; else if (value > 127) value = 127;
+ AddMIDI( MIDI_CONTROLCHANGE + (_midichannel & 0xf), control, value);
+}
+
+
+bool VSTPlugin::GetProgramName( int cat , int p, char *buf)
+{
+ int parameter = p;
+ if(instantiated)
+ {
+ if(parameter<NumPrograms())
+ {
+ Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f);
+ return true;
+ }
+ }
+ return false;
+}
+
+int VSTPlugin::GetNumCategories()
+{
+ if(instantiated)
+ return Dispatch(effGetNumProgramCategories,0,0,NULL,0.0f);
+ else
+ return 0;
+}
+
+void VSTPlugin::StopEditing()
+{
+ edited = false;
+}
diff --git a/VstHost.h b/VstHost.h
new file mode 100644
index 0000000..5039667
--- /dev/null
+++ b/VstHost.h
@@ -0,0 +1,145 @@
+#ifndef _VSTPLUGIN_HOST
+#define _VSTPLUGIN_HOST
+
+#include "Vst\AEffectx.h"
+#include <afxcoll.h>
+#define MAX_EVENTS 64
+#define MAX_INOUTS 8
+
+#define VSTINSTANCE_ERR_NO_VALID_FILE -1
+#define VSTINSTANCE_ERR_NO_VST_PLUGIN -2
+#define VSTINSTANCE_ERR_REJECTED -3
+#define VSTINSTANCE_NO_ERROR 0
+
+#define MIDI_NOTEON 144
+#define MIDI_NOTEOFF 128
+#define MIDI_POLYAFTERTOUCH 160
+#define MIDI_CONTROLCHANGE 176
+#define MIDI_PROGRAMCHANGE 192
+#define MIDI_AFTERTOUCH 208
+#define MIDI_PITCHBEND 224
+
+typedef AEffect* (*PVSTMAIN)(audioMasterCallback audioMaster);
+typedef HWND (*POPWIN)(void);
+typedef HWND (*GETWIN)(void);
+
+class VSTPlugin
+{
+public:
+ void StopEditing();
+ int GetNumCategories();
+ bool GetProgramName( int cat, int p , char* buf);
+ void AddControlChange( int control , int value );
+ void AddProgramChange( int value );
+ void AddPitchBend( int value );
+ void AddAftertouch( int value );
+ bool editor;
+ bool ShowParams();
+ void SetShowParameters( bool s);
+ void OnEditorCLose();
+ void SetEditWindow( HWND h );
+ CEditorThread* b;
+ RECT GetEditorRect();
+ void EditorIdle();
+ void edit(void);
+ bool replace( );
+ VSTPlugin();
+ ~VSTPlugin();
+
+ void Free();
+ int Instance( const char *dllname);
+ void Create(VSTPlugin *plug);
+ void Init( float samplerate , float blocksize );
+
+ virtual int GetNumParams(void) { return _pEffect->numParams; }
+ virtual void GetParamName(int numparam,char* name)
+ {
+ if ( numparam < _pEffect->numParams ) Dispatch(effGetParamName,numparam,0,name,0.0f);
+ else strcpy(name,"Out of Range");
+
+ }
+ virtual void GetParamValue(int numparam,char* parval)
+ {
+ if ( numparam < _pEffect->numParams ) DescribeValue(numparam,parval);
+ else strcpy(parval,"Out of Range");
+ }
+ virtual float GetParamValue(int numparam)
+ {
+ if ( numparam < _pEffect->numParams ) return (_pEffect->getParameter(_pEffect, numparam));
+ else return -1.0;
+ }
+
+ int getNumInputs( void );
+ int getNumOutputs( void );
+
+ virtual char* GetName(void) { return _sProductName; }
+ unsigned long GetVersion() { return _version; }
+ char* GetVendorName(void) { return _sVendorName; }
+ char* GetDllName(void) { return _sDllName; }
+
+ long NumParameters(void) { return _pEffect->numParams; }
+ float GetParameter(long parameter) { return _pEffect->getParameter(_pEffect, parameter); }
+ bool DescribeValue(int parameter,char* psTxt);
+ bool SetParameter(int parameter, float value);
+ bool SetParameter(int parameter, int value);
+ void SetCurrentProgram(int prg);
+ int GetCurrentProgram();
+ int NumPrograms() { return _pEffect->numPrograms; }
+ bool IsSynth() { return _isSynth; }
+
+ bool AddMIDI(unsigned char data0,unsigned char data1=0,unsigned char data2=0);
+ void SendMidi();
+
+
+ void processReplacing( float **inputs, float **outputs, long sampleframes );
+ void process( float **inputs, float **outputs, long sampleframes );
+
+ AEffect *_pEffect;
+ long Dispatch(long opCode, long index, long value, void *ptr, float opt)
+ {
+ return _pEffect->dispatcher(_pEffect, opCode, index, value, ptr, opt);
+ }
+
+ static long Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt);
+
+ bool AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel=0);
+ bool AddNoteOff( unsigned char note,unsigned char midichannel=0);
+
+
+ char _midichannel;
+ bool instantiated;
+ int _instance; // Remove when Changing the FileFormat.
+
+ HWND w;
+
+protected:
+
+ HMODULE h_dll;
+ HMODULE h_winddll;
+
+ char _sProductName[64];
+ char _sVendorName[64];
+ char *_sDllName; // Contains dll name
+ ULONG _version;
+ bool _isSynth;
+
+ float * inputs[MAX_INOUTS];
+ float * outputs[MAX_INOUTS];
+ float junk[256];
+
+ static VstTimeInfo _timeInfo;
+ VstMidiEvent midievent[MAX_EVENTS];
+ VstEvents events;
+ int queue_size;
+ bool overwrite;
+
+
+
+private:
+ bool edited;
+ bool show_params;
+ static float sample_rate;
+};
+
+
+#endif // _VSTPLUGIN_HOST \ No newline at end of file
diff --git a/crazy.pd b/crazy.pd
new file mode 100644
index 0000000..370149f
--- /dev/null
+++ b/crazy.pd
@@ -0,0 +1,16 @@
+#N canvas 297 500 460 310 12;
+#X msg 152 115 print;
+#X floatatom 236 37 5 0 0;
+#X obj 243 129 makenote 100 1000;
+#X obj 211 260 dac~;
+#X obj 190 198 vst~ craxzy diamonds;
+#X floatatom 363 29 5 0 0;
+#X msg 96 140 edit;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 4 1;
+#X connect 2 1 4 2;
+#X connect 4 1 3 0;
+#X connect 4 2 3 1;
+#X connect 5 0 2 2;
+#X connect 6 0 4 0;
diff --git a/export.h b/export.h
new file mode 100644
index 0000000..404bec1
--- /dev/null
+++ b/export.h
@@ -0,0 +1,9 @@
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+ __declspec(dllexport) void vst_setup( void );
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
diff --git a/neontest.pd b/neontest.pd
new file mode 100644
index 0000000..c1e0544
--- /dev/null
+++ b/neontest.pd
@@ -0,0 +1,14 @@
+#N canvas 297 500 458 308 12;
+#X msg 152 115 print;
+#X floatatom 235 37 5 0 0;
+#X obj 189 196 vst~ pro-52;
+#X obj 243 129 makenote 100 1000;
+#X obj 211 260 dac~;
+#X msg 89 138 edit;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 2 1 4 0;
+#X connect 2 2 4 1;
+#X connect 3 0 2 1;
+#X connect 3 1 2 2;
+#X connect 5 0 2 0;
diff --git a/res/vst.rc2 b/res/vst.rc2
new file mode 100644
index 0000000..a87ea63
--- /dev/null
+++ b/res/vst.rc2
@@ -0,0 +1,13 @@
+//
+// VST.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/vst.aps b/vst.aps
new file mode 100644
index 0000000..4b2a9e2
--- /dev/null
+++ b/vst.aps
Binary files differ
diff --git a/vst.clw b/vst.clw
new file mode 100644
index 0000000..5e1b73f
--- /dev/null
+++ b/vst.clw
@@ -0,0 +1,37 @@
+; CLW file contains information for the MFC ClassWizard
+
+[General Info]
+Version=1
+ClassCount=3
+Class1=CVstApp
+LastClass=CPopupWindow
+NewFileInclude2=#include "vst.h"
+ResourceCount=0
+NewFileInclude1=#include "stdafx.h"
+Class2=CEditorThread
+LastTemplate=CFrameWnd
+Class3=CPopupWindow
+
+[CLS:CVstApp]
+Type=0
+HeaderFile=vst.h
+ImplementationFile=vst.cpp
+Filter=N
+
+[CLS:CEditorThread]
+Type=0
+HeaderFile=EditorThread.h
+ImplementationFile=EditorThread.cpp
+BaseClass=CWinThread
+Filter=N
+LastObject=CEditorThread
+
+[CLS:CPopupWindow]
+Type=0
+HeaderFile=PopupWindow.h
+ImplementationFile=PopupWindow.cpp
+BaseClass=CFrameWnd
+Filter=T
+VirtualFilter=fWC
+LastObject=CPopupWindow
+
diff --git a/vst.cpp b/vst.cpp
new file mode 100644
index 0000000..e5bda65
--- /dev/null
+++ b/vst.cpp
@@ -0,0 +1,111 @@
+// vst.cpp : Defines the initialization routines for the DLL.
+//
+
+#include "stdafx.h"
+#include "vst.h"
+#include "m_pd.h"
+#include "EditorThread.h"
+#include "VstHost.h"
+#include "Popupwindow.h"
+#include "vst~.h"
+#include "export.h"
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//
+// Note!
+//
+// If this DLL is dynamically linked against the MFC
+// DLLs, any functions exported from this DLL which
+// call into MFC must have the AFX_MANAGE_STATE macro
+// added at the very beginning of the function.
+//
+// For example:
+//
+// extern "C" BOOL PASCAL EXPORT ExportedFunction()
+// {
+// AFX_MANAGE_STATE(AfxGetStaticModuleState());
+// // normal function body here
+// }
+//
+// It is very important that this macro appear in each
+// function, prior to any calls into MFC. This means that
+// it must appear as the first statement within the
+// function, even before any object variable declarations
+// as their constructors may generate calls into the MFC
+// DLL.
+//
+// Please see MFC Technical Notes 33 and 58 for additional
+// details.
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CVstApp
+
+BEGIN_MESSAGE_MAP(CVstApp, CWinApp)
+ //{{AFX_MSG_MAP(CVstApp)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CVstApp construction
+
+CVstApp::CVstApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CVstApp object
+
+CVstApp theApp;
+
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef struct _vstlib
+{
+ t_object x_obj;
+} t_vstLib;
+
+static t_class* vstLib_class;
+
+static void* vstLib_new(t_symbol* s) {
+ t_vstLib *x = (t_vstLib *)pd_new( vstLib_class);
+ return (x);
+}
+
+ void vst_setup(void)
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ vstLib_class = class_new(gensym("vstLib"), (t_newmethod)vstLib_new, 0,
+ sizeof(t_vstLib), 0, (t_atomtype)0);
+
+ AfxOleInit( );
+
+
+ // call setups here
+
+ vst_tilde_setup();
+
+ post("VST host by mark williamson");
+ post("contains source code from the Psycle tracker");
+
+ post("Contact: mark@junklight.com . website: http://www.junklight.com");
+ post("VSTLib: version: 0.1 ");
+ post("VSTLib: compiled: "__DATE__);
+ post("");
+}
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif \ No newline at end of file
diff --git a/vst.def b/vst.def
new file mode 100644
index 0000000..86f8503
--- /dev/null
+++ b/vst.def
@@ -0,0 +1,7 @@
+; vst.def : Declares the module parameters for the DLL.
+
+LIBRARY "vst"
+DESCRIPTION 'vst Windows Dynamic Link Library'
+
+EXPORTS
+ vst_setup
diff --git a/vst.dsp b/vst.dsp
new file mode 100644
index 0000000..32f71e4
--- /dev/null
+++ b/vst.dsp
@@ -0,0 +1,176 @@
+# Microsoft Developer Studio Project File - Name="vst" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=vst - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vst.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vst.mak" CFG="vst - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vst - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "vst - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vst - Win32 Release"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 5
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\src" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "NT" /D "__GNUC__" /D "_WINDLL" /FR /Yu"stdafx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 ..\bin\pd.lib /nologo /subsystem:windows /dll /machine:I386
+
+!ELSEIF "$(CFG)" == "vst - Win32 Debug"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 5
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\src" /D "_DEBUG" /D "PD" /D "NT" /D "__GNUC__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_WINDLL" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\bin\pd.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "vst - Win32 Release"
+# Name "vst - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\EditorThread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PopupWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\vst.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\vst.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\vst.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\VstHost.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\vst~.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\EditorThread.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\export.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PopupWindow.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\vst.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\VstHost.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\vst~.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\res\vst.rc2
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project
diff --git a/vst.dsw b/vst.dsw
new file mode 100644
index 0000000..a620ccd
--- /dev/null
+++ b/vst.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "vst"=.\vst.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/vst.h b/vst.h
new file mode 100644
index 0000000..098fc67
--- /dev/null
+++ b/vst.h
@@ -0,0 +1,46 @@
+// vst.h : main header file for the VST DLL
+//
+
+#if !defined(AFX_VST_H__013CDC75_CDE8_40AD_AE29_D952471B07F5__INCLUDED_)
+#define AFX_VST_H__013CDC75_CDE8_40AD_AE29_D952471B07F5__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// CVstApp
+// See vst.cpp for the implementation of this class
+//
+
+class CVstApp : public CWinApp
+{
+public:
+ CVstApp();
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CVstApp)
+ //}}AFX_VIRTUAL
+
+ //{{AFX_MSG(CVstApp)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_VST_H__013CDC75_CDE8_40AD_AE29_D952471B07F5__INCLUDED_)
+
diff --git a/vst.ncb b/vst.ncb
new file mode 100644
index 0000000..40caa31
--- /dev/null
+++ b/vst.ncb
Binary files differ
diff --git a/vst.opt b/vst.opt
new file mode 100644
index 0000000..8453f26
--- /dev/null
+++ b/vst.opt
Binary files differ
diff --git a/vst.plg b/vst.plg
new file mode 100644
index 0000000..4d13ceb
--- /dev/null
+++ b/vst.plg
@@ -0,0 +1,53 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: vst - Win32 Release--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\MARKW~1.APP\LOCALS~1\Temp\RSPEA6.tmp" with contents
+[
+/nologo /MT /W3 /GX /O2 /I "..\src" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "NT" /D "__GNUC__" /D "_WINDLL" /FR"Release/" /Fp"Release/vst.pch" /Yu"stdafx.h" /Fo"Release/" /Fd"Release/" /FD /c
+"C:\pd\vst\EditorThread.cpp"
+"C:\pd\vst\PopupWindow.cpp"
+"C:\pd\vst\vst.cpp"
+"C:\pd\vst\VstHost.cpp"
+"C:\pd\vst\vst~.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\MARKW~1.APP\LOCALS~1\Temp\RSPEA6.tmp"
+Creating temporary file "C:\DOCUME~1\MARKW~1.APP\LOCALS~1\Temp\RSPEA7.tmp" with contents
+[
+..\bin\pd.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"Release/vst.pdb" /machine:I386 /def:".\vst.def" /out:"Release/vst.dll" /implib:"Release/vst.lib"
+.\Release\EditorThread.obj
+.\Release\PopupWindow.obj
+.\Release\StdAfx.obj
+.\Release\vst.obj
+.\Release\VstHost.obj
+.\Release\vst~.obj
+.\Release\vst.res
+]
+Creating command line "link.exe @C:\DOCUME~1\MARKW~1.APP\LOCALS~1\Temp\RSPEA7.tmp"
+<h3>Output Window</h3>
+Compiling...
+EditorThread.cpp
+PopupWindow.cpp
+vst.cpp
+VstHost.cpp
+vst~.cpp
+Generating Code...
+Linking...
+ Creating library Release/vst.lib and object Release/vst.exp
+LINK : warning LNK4089: all references to "OLEAUT32.dll" discarded by /OPT:REF
+LINK : warning LNK4089: all references to "comdlg32.dll" discarded by /OPT:REF
+Creating command line "bscmake.exe /nologo /o"Release/vst.bsc" .\Release\StdAfx.sbr .\Release\EditorThread.sbr .\Release\PopupWindow.sbr .\Release\vst.sbr .\Release\VstHost.sbr .\Release\vst~.sbr"
+Creating browse info file...
+<h3>Output Window</h3>
+
+
+
+<h3>Results</h3>
+vst.dll - 0 error(s), 2 warning(s)
+</pre>
+</body>
+</html>
diff --git a/vst.rc b/vst.rc
new file mode 100644
index 0000000..ecf81fd
--- /dev/null
+++ b/vst.rc
@@ -0,0 +1,124 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif //_WIN32\r\n"
+ "#include ""res\\vst.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // APSTUDIO_INVOKED
+
+
+
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "vst DLL\0"
+ VALUE "FileVersion", "1, 0, 0, 1\0"
+ VALUE "InternalName", "vst\0"
+ VALUE "LegalCopyright", "Copyright (C) 2002\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename","vst.DLL\0"
+ VALUE "ProductName", "vst Dynamic Link Library\0"
+ VALUE "ProductVersion", "1, 0, 0, 1\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+#include "res\\vst.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/vst.sln b/vst.sln
new file mode 100644
index 0000000..d856c0d
--- /dev/null
+++ b/vst.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vst", "vst.vcproj", "{20B2DE85-3C09-43DB-A7A9-2F8326B6DB61}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {20B2DE85-3C09-43DB-A7A9-2F8326B6DB61}.Debug.ActiveCfg = Debug|Win32
+ {20B2DE85-3C09-43DB-A7A9-2F8326B6DB61}.Debug.Build.0 = Debug|Win32
+ {20B2DE85-3C09-43DB-A7A9-2F8326B6DB61}.Release.ActiveCfg = Release|Win32
+ {20B2DE85-3C09-43DB-A7A9-2F8326B6DB61}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/vst.suo b/vst.suo
new file mode 100644
index 0000000..5249dc0
--- /dev/null
+++ b/vst.suo
Binary files differ
diff --git a/vst.vcproj b/vst.vcproj
new file mode 100644
index 0000000..4982836
--- /dev/null
+++ b/vst.vcproj
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="vst"
+ SccProjectName=""
+ SccLocalPath=""
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ UseOfMFC="1"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\src"
+ PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;PD;NT;__GNUC__"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Release/vst.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="..\bin\pd.lib"
+ OutputFile=".\Release/vst.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ ModuleDefinitionFile=".\vst.def"
+ ProgramDatabaseFile=".\Release/vst.pdb"
+ SubSystem="2"
+ ImportLibrary=".\Release/vst.lib"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/vst.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="2057"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ UseOfMFC="1"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="..\src"
+ PreprocessorDefinitions="_DEBUG;PD;NT;__GNUC__;WIN32;_WINDOWS;_USRDLL"
+ StringPooling="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Debug/vst.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="..\bin\pd.lib"
+ OutputFile=".\Debug/vst.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="TRUE"
+ ModuleDefinitionFile=".\vst.def"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/vst.pdb"
+ SubSystem="2"
+ ImportLibrary=".\Debug/vst.lib"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/vst.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="2057"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath=".\EditorThread.cpp">
+ </File>
+ <File
+ RelativePath=".\PopupWindow.cpp">
+ </File>
+ <File
+ RelativePath=".\StdAfx.cpp">
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\VstHost.cpp">
+ </File>
+ <File
+ RelativePath=".\vst.cpp">
+ </File>
+ <File
+ RelativePath=".\vst.def">
+ </File>
+ <File
+ RelativePath=".\vst.rc">
+ </File>
+ <File
+ RelativePath=".\vst~.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath=".\EditorThread.h">
+ </File>
+ <File
+ RelativePath=".\PopupWindow.h">
+ </File>
+ <File
+ RelativePath=".\Resource.h">
+ </File>
+ <File
+ RelativePath=".\StdAfx.h">
+ </File>
+ <File
+ RelativePath=".\VstHost.h">
+ </File>
+ <File
+ RelativePath=".\export.h">
+ </File>
+ <File
+ RelativePath=".\vst.h">
+ </File>
+ <File
+ RelativePath=".\vst~.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath=".\res\vst.rc2">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vsttest.pd b/vsttest.pd
new file mode 100644
index 0000000..6b11c8d
--- /dev/null
+++ b/vsttest.pd
@@ -0,0 +1,32 @@
+#N canvas 218 503 725 555 12;
+#X obj 293 20 osc~ 440;
+#X obj 357 96 *~ 0.1;
+#X obj 486 21 vsl 15 128 0 1 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 302 357 dac~;
+#X obj 289 276 vst~ waldorf d-pole;
+#X msg 117 221 print;
+#X msg 64 236 edit;
+#X msg 225 191 param \$1 \$2;
+#X obj 191 145 pack \$1 \$2;
+#X floatatom 176 69 5 0 0;
+#X floatatom 256 84 5 0 1;
+#X obj 185 14 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
+-1;
+#X obj 225 110 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
+-1;
+#X connect 0 0 1 0;
+#X connect 1 0 4 1;
+#X connect 1 0 4 2;
+#X connect 2 0 1 1;
+#X connect 4 1 3 0;
+#X connect 4 2 3 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 4 0;
+#X connect 8 0 7 0;
+#X connect 9 0 8 0;
+#X connect 10 0 8 1;
+#X connect 10 0 12 0;
+#X connect 11 0 9 0;
+#X connect 12 0 8 0;
diff --git a/vst~.cpp b/vst~.cpp
new file mode 100644
index 0000000..15c26e5
--- /dev/null
+++ b/vst~.cpp
@@ -0,0 +1,579 @@
+#include "stdafx.h"
+#include "m_pd.h"
+#include <io.h>
+#include <stdlib.h>
+#include <direct.h>
+#include<time.h>
+#include "EditorThread.h"
+#include "VstHost.h"
+
+#include "vst~.h"
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+static const char * findFilePath( const char * path , const char * dllname );
+
+/* ------------------------ vst_tilde~ ----------------------------- */
+
+static t_class *vst_tilde_class;
+
+/**
+* the perform routine unpacks its parameters
+* looks to see if time is zero (do channel prob
+* everytime) if it is to chooses a channel.
+* the routine then copies everything in the input
+* to the choosen output
+*/
+
+t_int *vst_tilde_perform_replace(t_int *w)
+{
+ t_dsp_args *args = (t_dsp_args *)(w[1]);
+ int n = (t_int)(w[2]);
+ args->plug->processReplacing( args->inbufs , args->outbufs , args->num_samples );
+ return w+3;
+}
+
+t_int *vst_tilde_perform_acc(t_int *w)
+{
+ t_dsp_args *args = (t_dsp_args *)(w[1]);
+ int n = (t_int)(w[2]);
+ args->plug->process( args->inbufs , args->outbufs , args->num_samples );
+ return w+3;
+}
+
+/**
+* set up our dsp perform routine - it takes parameters
+* the input channel, the output channels ( left and right),
+* the pin object and the number of samples in the array
+*/
+
+static void vst_tilde_dsp(t_vst_tilde *x, t_signal **sp)
+{
+ int i;
+ if ( x->plug != NULL )
+ {
+ x->d_args = (t_dsp_args *) malloc( sizeof( t_dsp_args ));
+ x->d_args->num_in = x->num_audio_inputs;
+ x->d_args->num_out = x->num_audio_outputs;
+ x->d_args->inbufs = (float**) malloc( x->d_args->num_in * sizeof( float *));
+ for( i = 0 ; i< x->d_args->num_in;i++ )
+ {
+ x->d_args->inbufs[i] = sp[ i ]->s_vec;
+ }
+ x->d_args->outbufs = (float**) malloc( x->d_args->num_out * sizeof( float *));
+ for( i = 0 ; i< x->d_args->num_out;i++ )
+ {
+ x->d_args->outbufs[i] = sp[ i + x->d_args->num_in + 1]->s_vec;
+ }
+ x->d_args->num_samples = sp[0]->s_n;
+ x->d_args->sample_rate = sp[0]->s_sr;
+ x->d_args->plug = x->plug;
+ //post("*");
+ x->plug->Init( sp[0]->s_sr , sp[0]->s_n );
+ //post("*");
+ if ( x->plug->replace() )
+ {
+ dsp_add(vst_tilde_perform_replace, 2 , x->d_args , sp[0]->s_n );
+ }
+ else
+ {
+ dsp_add(vst_tilde_perform_acc, 2 , x->d_args , sp[0]->s_n );
+ }
+ }
+
+}
+
+/**
+* free up the tilde object - for now we only need
+* to get rid of the clock
+*/
+
+static void vst_tilde_free(t_vst_tilde *x)
+{
+ int i;
+ /* Destroy inlets */
+ if (x->audio_inlets != NULL)
+ {
+ for (i = 0; i < x->num_audio_inputs; i++)
+ {
+ inlet_free (x->audio_inlets[i]);
+ }
+ free (x->audio_inlets);
+ x->audio_inlets = NULL;
+ }
+ /* Destroy outlets */
+ if (x->control_outlet != NULL)
+ {
+ outlet_free (x->control_outlet);
+ x->control_outlet = NULL;
+ }
+ if (x->audio_outlets != NULL)
+ {
+ for (i = 0; i < x->num_audio_outputs; i++)
+ {
+ outlet_free (x->audio_outlets[i]);
+ }
+ free (x->audio_outlets);
+ x->audio_outlets = NULL;
+ }
+
+ if( x->d_args != NULL)
+ {
+ free( x->d_args->inbufs );
+ free( x->d_args->outbufs);
+ free( x->d_args );
+ }
+ if ( x->plug != NULL )
+ {
+ delete x->plug ;
+ }
+}
+
+/**
+* make a new object - set up out internal variables
+* and add our inlets and outlets
+*/
+
+static void *vst_tilde_new( t_symbol *s, int argc, t_atom *argv)
+{
+ post("In vst~ new");
+ t_vst_tilde *x = (t_vst_tilde *)pd_new(vst_tilde_class);
+ x->d_args = NULL;
+ x->plug = new VSTPlugin();
+ x->audio_inlets = NULL;
+ x->audio_outlets = NULL;
+ x->control_outlet = NULL;
+
+ // to help deal with spaces we assume ALL of the args make
+ // up the filename
+ char buf[255];
+ CString str;
+ for( int i = 0 ; i < argc ; i++ )
+ {
+ atom_string( &argv[i] , buf, 255 );
+ if ( i == 0 )
+ {
+ str += buf;
+ }
+ else
+ {
+ str += ' ';
+ str += buf;
+ }
+ }
+ bool lf = FALSE;
+
+ // try loading the dll from the raw filename
+ if ( x->plug->Instance( str ) == VSTINSTANCE_NO_ERROR )
+ {
+ //post( "it loaded fine ");
+ lf = TRUE;
+ }
+ else // try finding it on the VST PAth
+ {
+
+ char* vst_path = getenv ("VST_PATH");
+ char* tok_path = (char *) malloc( strlen( vst_path) * sizeof( char ));
+
+ CString dllname;
+ if ( str.MakeLower().Find( ".dll" ) == -1 )
+ {
+ dllname = str + ".dll";
+ }
+ else
+ {
+ dllname = str;
+ }
+ strcpy( tok_path , vst_path );
+ if ( vst_path != NULL )
+ {
+ char *tok = strtok( tok_path , ";" );
+ while( tok != NULL )
+ {
+ CString abpath( tok );
+ if( abpath.Right( 1 ) != _T("\\") )
+ {
+ abpath += "\\";
+ }
+ const char * realpath = findFilePath( abpath , dllname );
+ //post( "findFilePath( %s , %s ) = %s\n" , abpath , dllname , realpath );
+ if ( realpath != NULL )
+ {
+ CString rpath( realpath );
+ rpath += _T("\\") + str;
+ post( "trying %s " , rpath );
+ if ( x->plug->Instance( rpath ) == VSTINSTANCE_NO_ERROR )
+ {
+ post( " %s loaded " , x->plug->GetName());
+ lf = TRUE;
+ break;
+ }
+ }
+ tok = strtok( NULL , ";" );
+ if ( tok == NULL )
+ {
+ post( "couldn't find dll");
+ }
+ }
+ }
+ }
+ if ( !lf ) // failed - don't make any ins or outs
+ {
+ post("Unable to load %s" , str );
+ delete x->plug;
+ x->plug = NULL;
+ return( x);
+ }
+
+ // make our inlets and outlets next
+
+ x->num_audio_inputs = x->plug->getNumInputs();
+ x->num_audio_outputs = x->plug->getNumOutputs();
+
+ /* Allocate memory for in- and outlet pointers */
+ x->audio_inlets = (t_inlet**)calloc (x->num_audio_inputs, sizeof (t_inlet*));
+ x->audio_outlets = (t_outlet**)calloc (x->num_audio_outputs, sizeof (t_outlet*));
+
+
+ /* The first inlet is always there (needn't be created), and is
+ used for control messages. Now, create the rest of the
+ inlets for audio signal input. */
+ for (i = 0; i < x->num_audio_inputs; i++)
+ {
+ x->audio_inlets[i] = inlet_new (&x->x_obj,&x->x_obj.ob_pd,gensym ("signal"),gensym ("signal"));
+ }
+
+ // set up our inlets for midi notes
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("midinote"));
+ floatinlet_new(&x->x_obj, &x->x_vel);
+
+ /* We use the first outlet always for VST parameter control messages */
+ x->control_outlet = outlet_new (&x->x_obj, gensym ("control"));
+
+ /* The rest of the outlets are used for audio signal output */
+ for (i = 0; i < x->num_audio_outputs; i++)
+ {
+ x->audio_outlets[i] = outlet_new (&x->x_obj, gensym ("signal"));
+ }
+
+ return (x);
+}
+
+static const char * findFilePath( const char * path , const char * dllname )
+{
+ CFileFind finder;
+ _chdir( path );
+ if ( finder.FindFile( dllname ) == TRUE )
+ {
+ return path;
+ }
+ else
+ {
+ finder.FindFile();
+ while( finder.FindNextFile() )
+ {
+ if ( finder.IsDirectory() )
+ {
+ if ( !finder.IsDots() )
+ {
+ CString *npath = new CString( finder.GetFilePath());
+ const char * ret = findFilePath( *npath , dllname );
+ if ( ret != NULL)
+ {
+ CString *retstr = new CString( ret );
+ return *retstr;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+
+/**
+* setup - add our methods
+*/
+
+ void vst_tilde_setup(void)
+{
+ srand( (unsigned) time( NULL ) );
+ vst_tilde_class = class_new(gensym("vst~"), (t_newmethod) vst_tilde_new, (t_method) vst_tilde_free,
+ sizeof(t_vst_tilde), 0, A_GIMME , 0);
+ CLASS_MAINSIGNALIN( vst_tilde_class, t_vst_tilde, x_f);
+ class_addmethod(vst_tilde_class, (t_method) vst_tilde_dsp, gensym("dsp"), (t_atomtype)0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_control,gensym ("control"),A_DEFSYM, A_DEFFLOAT, 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_pitchbend,gensym ("pitchbend"),A_DEFFLOAT, 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_program,gensym ("program"),A_DEFFLOAT, 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_programchange,gensym ("programchange"),A_DEFFLOAT, 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_ctrlchange,gensym ("ctrlchange"),A_DEFFLOAT ,A_DEFFLOAT, 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_print,gensym ("print"),A_GIMME,(t_atomtype) 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_edit,gensym ("edit"),(t_atomtype) 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_showparams,gensym ("showparams"),(t_atomtype) 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_noshowparams,gensym ("noshowparams"),(t_atomtype) 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_param,gensym ("param"), A_DEFFLOAT , A_DEFFLOAT , (t_atomtype) 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_reset,gensym ("reset"),(t_atomtype) 0);
+ class_addmethod (vst_tilde_class,(t_method)vst_tilde_midinote,gensym ("midinote"),A_DEFFLOAT,(t_atomtype) 0);
+ //class_sethelpsymbol(vst_tilde_class, gensym("vst/vsthelp"));
+}
+
+ static void vst_tilde_control (t_vst_tilde* x, t_symbol* ctrl_name,t_float ctrl_value)
+{
+ unsigned parm_num = 0;
+
+ if (ctrl_name->s_name == NULL || strlen (ctrl_name->s_name) == 0)
+ {
+ error ("plugin~: control messages must have a name and a value");
+ return;
+ }
+ //parm_num = vst_tilde_get_parm_number (x, ctrl_name->s_name);
+ //if (parm_num)
+ //{
+ //vst_tilde_set_control_input_by_index (x, parm_num - 1, ctrl_value);
+ //}
+ //else
+ //{
+ //vst_tilde_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value);
+ //}
+}
+
+ static void vst_tilde_pitchbend (t_vst_tilde* x, t_float ctrl_value)
+{
+ x->plug->AddPitchBend( (int) ctrl_value );
+}
+
+ static void vst_tilde_programchange (t_vst_tilde* x, t_float ctrl_value)
+{
+ x->plug->AddProgramChange( (int) ctrl_value );
+}
+
+static void vst_tilde_program (t_vst_tilde* x, t_float ctrl_value)
+{
+ x->plug->SetCurrentProgram( (int) ctrl_value );
+}
+
+ static void vst_tilde_ctrlchange (t_vst_tilde* x, t_float control , t_float ctrl_value)
+{
+ x->plug->AddControlChange( (int) control , (int) ctrl_value );
+}
+
+
+ /**
+ * display the parameters names and values and some other bits and pieces that
+ * may be of use
+ */
+
+static void vst_tilde_print (t_vst_tilde* x, t_symbol *s, int ac, t_atom *av )
+{
+ int i;
+ bool params = false;
+ bool header = true;
+ bool programs = false;
+ bool parameters = true;
+ int specific = -1;
+ if ( ac > 0 )
+ {
+ for( i = 0 ; i < ac ; i++)
+ {
+ if ( av[i].a_type == A_SYMBOL )
+ {
+ char buf[255];
+ atom_string( &av[i] , buf, 255 );
+ if ( strcmp( buf , "-params" ) == 0 )
+ {
+ params = true;
+ }
+ else if ( strcmp( buf , "-noheader" ) == 0 )
+ {
+ header = false;
+ }
+ else if ( strcmp( buf , "-programs" ) == 0 )
+ {
+ programs = true;
+ parameters = false;
+ }
+ else if ( strcmp( buf , "-parameters" ) == 0 )
+ {
+ parameters = false;
+ }
+ else if ( strcmp( buf , "-help" ) == 0 )
+ {
+ post("print options:");
+ post("-help \t\tprint this");
+ post("-params \tshow the parameter display values ");
+ post("-noheader \tdo not display the header");
+ return;
+ }
+ }
+ else if ( av[i].a_type == A_FLOAT )
+ {
+ int p = (int) atom_getfloat( &av[i] );
+ if (( p > 0 ) && ( p <= x->plug->GetNumParams()))
+ {
+ specific = p - 1;
+ }
+ }
+ }
+ }
+ if ( header )
+ {
+ post("VST~ plugin: %s " , x->plug->GetName() );
+ post("made by: %s " , x->plug->GetVendorName() );
+ post("parameterss %d\naudio: %d in(s)/%d out(s) \nLoaded from library \"%s\".\n",
+ x->plug->GetNumParams(),
+ x->num_audio_inputs,
+ x->num_audio_outputs,
+ x->plug->GetDllName());
+
+ post("Flags");
+ if ( x->plug->_pEffect->flags & effFlagsHasEditor )
+ {
+ post("Has editor");
+ }
+ if ( x->plug->_pEffect->flags & effFlagsCanReplacing )
+ {
+ post("Can do replacing");
+ }
+ }
+ if ( parameters )
+ {
+ if ( specific == -1)
+ {
+ for (i = 0; i < x->plug->GetNumParams(); i++)
+ {
+ display_parameter( x , i , params );
+ }
+ }
+ else
+ {
+ display_parameter( x , specific , params);
+ }
+ }
+ if( programs )
+ {
+
+ for( int j = 0; j < x->plug->GetNumCategories() ; j++ )
+ {
+ for( i = 0 ; i < x->plug->GetNumParams() ; i++ )
+ {
+ char buf[64];
+ x->plug->GetProgramName( j , i , buf );
+ post("Program %d: %s ", i , buf );
+ }
+ }
+ }
+}
+
+static void display_parameter( t_vst_tilde* x, int param , bool showparams )
+{
+ int j = param;
+ /* the Steinberg(tm) way... */
+ char name[109];
+ char display[164];
+ float val;
+ if (j == 0)
+ {
+ post ("Control input/output(s):");
+ }
+ memset (name, 0, 108);
+ memset( display, 0 ,163);
+ x->plug->GetParamName( j , name );
+ if ( name[0] != NULL )
+ {
+ if ( showparams )
+ {
+ x->plug->DescribeValue( j , display );
+ val = x->plug->GetParamValue( j );
+ post ("parameter[#%d], \"%s\" value=%f (%s) ", j + 1, name, val,display);
+ }
+ else
+ {
+ val = x->plug->GetParamValue( j );
+ post ("parameter[#%d], \"%s\" value=%f ", j + 1, name, val);
+ }
+ }
+}
+
+
+/**
+* display an editor - currently not implemented
+*/
+
+
+static void vst_tilde_edit(t_vst_tilde* x)
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ if ( x->plug != NULL )
+ {
+ x->plug->edit();
+ }
+ else
+ {
+ post("No plugin to edit");
+ }
+}
+
+static void vst_tilde_showparams(t_vst_tilde* x)
+{
+ x->plug->SetShowParameters( true);
+}
+
+static void vst_tilde_noshowparams(t_vst_tilde* x)
+{
+ x->plug->SetShowParameters( false);
+}
+
+
+
+/**
+* set the value of a parameter
+*/
+
+static void vst_tilde_param(t_vst_tilde* x , t_float pnum , t_float val)
+{
+ if ( ( pnum > 0 ) && ( pnum <= x->plug->GetNumParams() ))
+ {
+ int i = (int) pnum - 1;
+ char name[9];
+ char display[64];
+ float xval;
+ memset (name, 0, 9);
+ memset( display, 0 ,64);
+ x->plug->GetParamName( i , name );
+ if ( name[0] != NULL )
+ {
+ xval = x->plug->GetParamValue( i );
+ if ( xval <= 1.0f)
+ {
+ x->plug->SetParameter( i , val );
+ if ( x->plug->ShowParams() )
+ {
+ display_parameter( x , i , true );
+ }
+ }
+ }
+ }
+}
+
+static void vst_tilde_reset (t_vst_tilde* x)
+{
+
+}
+
+static void vst_tilde_midinote(t_vst_tilde* x , t_float note )
+{
+ if ( x->x_vel > 0 )
+ {
+ x->plug->AddNoteOn( note , x->x_vel );
+ }
+ else
+ {
+ x->plug->AddNoteOff( note );
+ }
+}
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif \ No newline at end of file
diff --git a/vst~.h b/vst~.h
new file mode 100644
index 0000000..90c6c35
--- /dev/null
+++ b/vst~.h
@@ -0,0 +1,63 @@
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+
+typedef struct _dsp_args
+{
+ float num_samples;
+ float sample_rate;
+ int num_in;
+ int num_out;
+ t_float** inbufs;
+ t_float** outbufs;
+ VSTPlugin *plug;
+} t_dsp_args;
+
+
+
+typedef struct _vst_tilde
+{
+ t_object x_obj;
+ VSTPlugin *plug;
+ t_inlet** audio_inlets;
+ t_outlet** audio_outlets;
+ int num_audio_inputs;
+ int num_audio_outputs;
+ t_outlet* control_outlet;
+ t_dsp_args *d_args ;
+ t_float x_vel;
+ float x_f;
+} t_vst_tilde;
+
+t_int *vst_tilde_perform_replace(t_int *w);
+t_int *vst_tilde_perform_acc(t_int *w);
+static void vst_tilde_dsp(t_vst_tilde *x, t_signal **sp);
+static void vst_tilde_free(t_vst_tilde *x);
+static void *vst_tilde_new( t_symbol *s, int argc, t_atom *argv);
+static void vst_tilde_float(t_vst_tilde* x, t_float n);
+
+ void vst_tilde_setup(void);
+
+ static void vst_tilde_control (t_vst_tilde* x, t_symbol* ctrl_name,t_float ctrl_value) ;
+static void vst_tilde_print (t_vst_tilde* x, t_symbol *s, int ac, t_atom *av );
+static void display_parameter(t_vst_tilde* x, int param, bool showparams );
+static void vst_tilde_edit (t_vst_tilde* x);
+static void vst_tilde_showparams(t_vst_tilde* x);
+static void vst_tilde_noshowparams(t_vst_tilde* x);
+static void vst_tilde_param (t_vst_tilde* x , t_float pnum , t_float val );
+static void vst_tilde_reset (t_vst_tilde* x);
+static void vst_tilde_pitchbend (t_vst_tilde* x, t_float ctrl_value);
+ static void vst_tilde_programchange (t_vst_tilde* x, t_float ctrl_value);
+static void vst_tilde_ctrlchange (t_vst_tilde* x, t_float control ,t_float ctrl_value);
+static void vst_tilde_program (t_vst_tilde* x, t_float ctrl_value) ;
+
+static void vst_tilde_midinote(t_vst_tilde* x , t_float note );
+
+static void *vstnamecanvas_new(t_symbol *s);
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
+
+
diff --git a/vst~.pdf b/vst~.pdf
new file mode 100644
index 0000000..cb15b2c
--- /dev/null
+++ b/vst~.pdf
Binary files differ