/[svn]/linuxsampler/trunk/src/hostplugins/vst/PluginVst.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/hostplugins/vst/PluginVst.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1777 - (hide annotations) (download)
Mon Sep 15 16:58:10 2008 UTC (15 years, 7 months ago) by persson
File size: 9964 byte(s)
* added experimental support for running LinuxSampler as a DSSI, LV2
  and VST plugin

1 persson 1777 /***************************************************************************
2     * *
3     * Copyright (C) 2008 Andreas Persson *
4     * *
5     * This program is free software; you can redistribute it and/or modify *
6     * it under the terms of the GNU General Public License as published by *
7     * the Free Software Foundation; either version 2 of the License, or *
8     * (at your option) any later version. *
9     * *
10     * This program is distributed in the hope that it will be useful, *
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13     * GNU General Public License for more details. *
14     * *
15     * You should have received a copy of the GNU General Public License *
16     * along with this program; if not, write to the Free Software *
17     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
18     * MA 02110-1301 USA *
19     ***************************************************************************/
20    
21     #include <cstdio>
22     #include <cstdlib>
23     #include <cstring>
24    
25     #ifdef WIN32
26     #include <tchar.h>
27     #endif
28    
29     #include "PluginVst.h"
30    
31     namespace {
32    
33     #if defined(WIN32) && CONFIG_DEBUG_LEVEL >= 2
34     // on windows, send debug logging to a file instead of a non-existent
35     // console
36     #include <cstdarg>
37     #include "../../common/Mutex.h"
38     LinuxSampler::Mutex logmutex;
39    
40     void log(const char* fmt, ...) {
41     logmutex.Lock();
42     FILE* f = fopen("C:\\linuxsamplervst.log", "a");
43     va_list ap;
44     va_start(ap, fmt);
45     vfprintf(f, fmt, ap);
46     va_end(ap);
47     fclose(f);
48     logmutex.Unlock();
49     }
50     #undef dmsg
51     #define dmsg(debuglevel,x) log x;
52     #endif
53    
54    
55     // *************** LinuxSamplerVstProgram ***************
56     // *
57    
58     LinuxSamplerVstProgram::LinuxSamplerVstProgram() {
59     vst_strncpy(name, "Basic", kVstMaxProgNameLen);
60     }
61    
62    
63     // *************** LinuxSamplerEditor ***************
64     // *
65    
66     LinuxSamplerEditor::LinuxSamplerEditor(AudioEffect* effect) :
67     AEffEditor(effect) {
68     dmsg(2, ("-->LinuxSamplerEditor constructor\n"));
69     }
70    
71     bool LinuxSamplerEditor::open(void* ptr) {
72     dmsg(2, ("-->LinuxSamplerEditor::open\n"));
73     AEffEditor::open(ptr);
74    
75     #ifdef WIN32
76     // try to start the JSample Fantasia GUI as a separate process
77    
78     ProcessHandle = INVALID_HANDLE_VALUE;
79    
80     // look for a Fantasia jar file in %programfiles%\LinuxSampler
81     if (const char* programfiles = getenv("PROGRAMFILES")) {
82     String lspath = String(programfiles) + "\\LinuxSampler\\";
83     WIN32_FIND_DATA fd;
84     HANDLE hFind = FindFirstFile((lspath + "Fantasia*.jar").c_str(), &fd);
85     if (hFind != INVALID_HANDLE_VALUE) {
86     String fantasia(fd.cFileName);
87     FindClose(hFind);
88    
89     // start a java process
90     STARTUPINFO si;
91     PROCESS_INFORMATION pi;
92     ZeroMemory(&si, sizeof(si));
93     si.cb = sizeof(si);
94     ZeroMemory(&pi, sizeof(pi));
95    
96     Command = _tcsdup(TEXT((String("javaw -jar \"") + lspath + fantasia + "\" &").c_str()));
97     CreateProcess(NULL, Command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
98     ProcessHandle = pi.hProcess;
99     }
100     }
101     #endif
102     dmsg(2, ("<--LinuxSamplerEditor::open\n"));
103     return true;
104     }
105    
106     void LinuxSamplerEditor::close() {
107     systemWindow = 0;
108     #ifdef WIN32
109     if (ProcessHandle != INVALID_HANDLE_VALUE) {
110     TerminateProcess(ProcessHandle, 0);
111     free(Command);
112     }
113     #endif
114     }
115    
116     bool LinuxSamplerEditor::getRect(ERect** rect) {
117     ERect* r = new ERect();
118     r->top = 0;
119     r->left = 0;
120     r->bottom = 0;
121     r->right = 400;
122     *rect = r;
123     return true;
124     }
125    
126    
127     // *************** LinuxSamplerVst ***************
128     // *
129    
130     LinuxSamplerVst::LinuxSamplerVst(audioMasterCallback audioMaster) :
131     AudioEffectX(audioMaster, NbPrograms, 0),
132     StateBuf(0)
133     {
134     dmsg(2, ("-->constructor\n"));
135    
136     Programs = new LinuxSamplerVstProgram[NbPrograms];
137     setProgram(0);
138     setNumInputs(0);
139     setNumOutputs(2);
140     canProcessReplacing();
141     isSynth();
142     programsAreChunks();
143     setUniqueID(CCONST('L', 'S', 'm', 'p')); // (registred at Steinberg)
144     setEditor(new LinuxSamplerEditor(this));
145    
146     suspend();
147     dmsg(2, ("<--constructor\n"));
148     }
149    
150    
151     void LinuxSamplerVst::resume() {
152     dmsg(2, ("-->resume\n"));
153     if (!pAudioDevice) {
154     Init(int(sampleRate), blockSize);
155    
156     if (SavedChunk.length()) {
157     SetState(SavedChunk);
158     SavedChunk = "";
159     } else {
160     InitState();
161     }
162     }
163     dmsg(2, ("<--resume\n"));
164     }
165    
166     LinuxSamplerVst::~LinuxSamplerVst() {
167     dmsg(2, ("-->destructor\n"));
168     delete[] Programs;
169     if (StateBuf) free(StateBuf);
170     dmsg(2, ("<--destructor\n"));
171     }
172    
173    
174     void LinuxSamplerVst::setProgram(VstInt32 program) {
175     if (program < 0 || program >= NbPrograms) return;
176    
177     curProgram = program;
178     }
179    
180    
181     void LinuxSamplerVst::setProgramName(char* name) {
182     vst_strncpy(Programs[curProgram].name, name, kVstMaxProgNameLen);
183     }
184    
185    
186     void LinuxSamplerVst::getProgramName(char* name) {
187     vst_strncpy(name, Programs[curProgram].name, kVstMaxProgNameLen);
188     }
189    
190    
191     bool LinuxSamplerVst::getOutputProperties(VstInt32 index,
192     VstPinProperties* properties) {
193     if (index < 2) {
194     sprintf(properties->label, "LS %d", index + 1);
195     properties->flags = kVstPinIsActive | kVstPinIsStereo;
196     return true;
197     }
198     return false;
199     }
200    
201    
202     bool LinuxSamplerVst::getProgramNameIndexed(VstInt32 category, VstInt32 index,
203     char* text) {
204     if (index < NbPrograms) {
205     vst_strncpy(text, Programs[index].name, kVstMaxProgNameLen);
206     return true;
207     }
208     return false;
209     }
210    
211    
212     bool LinuxSamplerVst::getEffectName(char* name) {
213     vst_strncpy(name, "LinuxSampler", kVstMaxEffectNameLen);
214     return true;
215     }
216    
217    
218     bool LinuxSamplerVst::getVendorString(char* text) {
219     vst_strncpy(text, "linuxsampler.org", kVstMaxVendorStrLen);
220     return true;
221     }
222    
223    
224     bool LinuxSamplerVst::getProductString(char* text) {
225     vst_strncpy(text, "LinuxSampler VST", kVstMaxProductStrLen);
226     return true;
227     }
228    
229    
230     VstInt32 LinuxSamplerVst::getVendorVersion() {
231     return 1000;
232     }
233    
234    
235     VstInt32 LinuxSamplerVst::canDo(char* text) {
236     dmsg(2, ("canDo %s\n", text));
237     if (strcmp(text, "receiveVstEvents") == 0 ||
238     strcmp(text, "receiveVstMidiEvent") == 0) return 1;
239     return -1;
240     }
241    
242     void LinuxSamplerVst::setSampleRate(float sampleRate) {
243     dmsg(2, ("linuxsampler: setSampleRate %f\n", sampleRate));
244     AudioEffectX::setSampleRate(sampleRate);
245     }
246    
247     void LinuxSamplerVst::setBlockSize(VstInt32 blockSize) {
248     dmsg(2, ("linuxsampler: setBlockSize %d\n", blockSize));
249     AudioEffectX::setBlockSize(blockSize);
250     }
251    
252    
253     void LinuxSamplerVst::processReplacing(float** inputs, float** outputs,
254     VstInt32 sampleFrames) {
255     if (pAudioDevice) {
256     pAudioDevice->Channel(0)->SetBuffer(outputs[0]);
257     pAudioDevice->Channel(1)->SetBuffer(outputs[1]);
258     pAudioDevice->Render(sampleFrames);
259     } else {
260     memset(outputs[0], 0, sampleFrames * sizeof(float));
261     memset(outputs[1], 0, sampleFrames * sizeof(float));
262     }
263     }
264    
265    
266     VstInt32 LinuxSamplerVst::processEvents(VstEvents* ev) {
267     if (pMidiDevice) {
268     for (int i = 0; i < ev->numEvents; i++)
269     {
270     if (ev->events[i]->type == kVstMidiType) {
271     VstMidiEvent* event = reinterpret_cast<VstMidiEvent*>(ev->events[i]);
272     pMidiDevice->Port()->DispatchRaw(reinterpret_cast<uint8_t*>(event->midiData),
273     event->deltaFrames);
274     }
275     }
276     }
277     return 1;
278     }
279    
280    
281     VstInt32 LinuxSamplerVst::getChunk(void** data, bool isPreset) {
282     dmsg(2, ("-->getChunk\n"));
283    
284     String state = GetState();
285     dmsg(2, ("state=\"%s\"\n", state.c_str()));;
286     if (StateBuf) free(StateBuf);
287     StateBuf = strdup(state.c_str());
288     *data = StateBuf;
289     dmsg(2, ("<--getChunk\n"));
290     return state.length() + 1;
291     }
292    
293    
294     VstInt32 LinuxSamplerVst::setChunk(void* data, VstInt32 byteSize,
295     bool isPreset) {
296     dmsg(2, ("-->setChunk byteSize=%d isPreset=%d\n", byteSize, isPreset));
297    
298     const char* state = static_cast<const char*>(data);
299     VstInt32 res = 0;
300     if (byteSize > 0 && state[byteSize - 1] == '\0') {
301     dmsg(2, ("state=\"%s\"\n", state));
302     if (pAudioDevice) {
303     res = SetState(state);
304     } else {
305     SavedChunk = state;
306     }
307     }
308     dmsg(2, ("<--setChunk\n"));
309     return res;
310     }
311     }
312    
313    
314     // *************** VST main function ***************
315     // *
316    
317     AudioEffect* createEffectInstance(audioMasterCallback audioMaster)
318     {
319     return new LinuxSamplerVst(audioMaster);
320     }

  ViewVC Help
Powered by ViewVC