/[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 1928 - (hide annotations) (download)
Fri Jul 3 11:14:46 2009 UTC (14 years, 8 months ago) by schoenebeck
File size: 10927 byte(s)
* VST: look for the Fantasia binary in liblinuxsampler.dll's directory and
  in its parent directory (required for the next Windows installer which
  allows to install the 64 bit and 32 bit version of LinuxSampler VST
  alongside)

1 persson 1777 /***************************************************************************
2     * *
3 persson 1908 * Copyright (C) 2008 - 2009 Andreas Persson *
4 persson 1777 * *
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 persson 1908 #ifndef CHANNELS
32 persson 1917 #define CHANNELS 32
33 persson 1908 #endif
34    
35 persson 1777 namespace {
36    
37     #if defined(WIN32) && CONFIG_DEBUG_LEVEL >= 2
38     // on windows, send debug logging to a file instead of a non-existent
39     // console
40     #include <cstdarg>
41     #include "../../common/Mutex.h"
42     LinuxSampler::Mutex logmutex;
43    
44     void log(const char* fmt, ...) {
45     logmutex.Lock();
46     FILE* f = fopen("C:\\linuxsamplervst.log", "a");
47     va_list ap;
48     va_start(ap, fmt);
49     vfprintf(f, fmt, ap);
50     va_end(ap);
51     fclose(f);
52     logmutex.Unlock();
53     }
54     #undef dmsg
55     #define dmsg(debuglevel,x) log x;
56     #endif
57    
58    
59     // *************** LinuxSamplerVstProgram ***************
60     // *
61    
62     LinuxSamplerVstProgram::LinuxSamplerVstProgram() {
63     vst_strncpy(name, "Basic", kVstMaxProgNameLen);
64     }
65    
66    
67     // *************** LinuxSamplerEditor ***************
68     // *
69    
70     LinuxSamplerEditor::LinuxSamplerEditor(AudioEffect* effect) :
71     AEffEditor(effect) {
72     dmsg(2, ("-->LinuxSamplerEditor constructor\n"));
73 persson 1895 #ifdef WIN32
74     ProcessHandle = INVALID_HANDLE_VALUE;
75     #endif
76 persson 1777 }
77    
78 persson 1895 LinuxSamplerEditor::~LinuxSamplerEditor() {
79     close();
80     }
81    
82 persson 1777 bool LinuxSamplerEditor::open(void* ptr) {
83     dmsg(2, ("-->LinuxSamplerEditor::open\n"));
84     AEffEditor::open(ptr);
85    
86     #ifdef WIN32
87     // try to start the JSample Fantasia GUI as a separate process
88    
89 persson 1908 // first check if it's already running
90     if (ProcessHandle != INVALID_HANDLE_VALUE) {
91     DWORD exitCode;
92     if (GetExitCodeProcess(ProcessHandle, &exitCode)) {
93     if (exitCode == STILL_ACTIVE) return true;
94     }
95     free(Command);
96     CloseHandle(ProcessHandle);
97     ProcessHandle = INVALID_HANDLE_VALUE;
98     }
99 persson 1777
100 schoenebeck 1928 // assume Fantasia is in the same directory or one directory above
101     // the liblinuxsampler dll
102 persson 1897 String lspath = LinuxSampler::Sampler::GetInstallDir();
103     if (!lspath.empty()) {
104     lspath += "\\";
105 persson 1777 WIN32_FIND_DATA fd;
106     HANDLE hFind = FindFirstFile((lspath + "Fantasia*.jar").c_str(), &fd);
107 schoenebeck 1928 if (hFind == INVALID_HANDLE_VALUE) {
108     lspath += "..\\";
109     hFind = FindFirstFile((lspath + "Fantasia*.jar").c_str(), &fd);
110     }
111 persson 1777 if (hFind != INVALID_HANDLE_VALUE) {
112     String fantasia(fd.cFileName);
113     FindClose(hFind);
114    
115     // start a java process
116     STARTUPINFO si;
117     PROCESS_INFORMATION pi;
118     ZeroMemory(&si, sizeof(si));
119     si.cb = sizeof(si);
120     ZeroMemory(&pi, sizeof(pi));
121    
122 senoner 1920 Command = _tcsdup(TEXT((String("javaw -jar \"") + lspath + fantasia + "\"").c_str()));
123 persson 1777 CreateProcess(NULL, Command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
124     ProcessHandle = pi.hProcess;
125 persson 1908 CloseHandle(pi.hThread);
126 persson 1777 }
127     }
128     #endif
129     dmsg(2, ("<--LinuxSamplerEditor::open\n"));
130     return true;
131     }
132    
133     void LinuxSamplerEditor::close() {
134     systemWindow = 0;
135     #ifdef WIN32
136     if (ProcessHandle != INVALID_HANDLE_VALUE) {
137     TerminateProcess(ProcessHandle, 0);
138     free(Command);
139 persson 1908 CloseHandle(ProcessHandle);
140 persson 1895 ProcessHandle = INVALID_HANDLE_VALUE;
141 persson 1777 }
142     #endif
143     }
144    
145     bool LinuxSamplerEditor::getRect(ERect** rect) {
146     ERect* r = new ERect();
147     r->top = 0;
148     r->left = 0;
149     r->bottom = 0;
150     r->right = 400;
151     *rect = r;
152     return true;
153     }
154    
155    
156     // *************** LinuxSamplerVst ***************
157     // *
158    
159     LinuxSamplerVst::LinuxSamplerVst(audioMasterCallback audioMaster) :
160     AudioEffectX(audioMaster, NbPrograms, 0),
161     StateBuf(0)
162     {
163     dmsg(2, ("-->constructor\n"));
164    
165     Programs = new LinuxSamplerVstProgram[NbPrograms];
166     setProgram(0);
167     setNumInputs(0);
168 persson 1908 setNumOutputs(CHANNELS);
169 persson 1777 canProcessReplacing();
170     isSynth();
171     programsAreChunks();
172     setUniqueID(CCONST('L', 'S', 'm', 'p')); // (registred at Steinberg)
173     setEditor(new LinuxSamplerEditor(this));
174    
175     suspend();
176     dmsg(2, ("<--constructor\n"));
177     }
178    
179    
180     void LinuxSamplerVst::resume() {
181     dmsg(2, ("-->resume\n"));
182     if (!pAudioDevice) {
183 persson 1908 Init(int(sampleRate), blockSize, CHANNELS);
184 persson 1777
185 persson 1895 if (!SavedChunk.empty()) {
186 persson 1777 SetState(SavedChunk);
187 persson 1895 SavedChunk.clear();
188 persson 1777 } else {
189     InitState();
190     }
191 persson 1895 } else {
192     Init(int(sampleRate), blockSize);
193 persson 1777 }
194     dmsg(2, ("<--resume\n"));
195     }
196    
197     LinuxSamplerVst::~LinuxSamplerVst() {
198     dmsg(2, ("-->destructor\n"));
199     delete[] Programs;
200     if (StateBuf) free(StateBuf);
201     dmsg(2, ("<--destructor\n"));
202     }
203    
204    
205     void LinuxSamplerVst::setProgram(VstInt32 program) {
206     if (program < 0 || program >= NbPrograms) return;
207    
208     curProgram = program;
209     }
210    
211    
212     void LinuxSamplerVst::setProgramName(char* name) {
213     vst_strncpy(Programs[curProgram].name, name, kVstMaxProgNameLen);
214     }
215    
216    
217     void LinuxSamplerVst::getProgramName(char* name) {
218     vst_strncpy(name, Programs[curProgram].name, kVstMaxProgNameLen);
219     }
220    
221    
222     bool LinuxSamplerVst::getOutputProperties(VstInt32 index,
223     VstPinProperties* properties) {
224 persson 1908 if (index < CHANNELS) {
225 persson 1777 sprintf(properties->label, "LS %d", index + 1);
226     properties->flags = kVstPinIsActive | kVstPinIsStereo;
227     return true;
228     }
229     return false;
230     }
231    
232    
233     bool LinuxSamplerVst::getProgramNameIndexed(VstInt32 category, VstInt32 index,
234     char* text) {
235     if (index < NbPrograms) {
236     vst_strncpy(text, Programs[index].name, kVstMaxProgNameLen);
237     return true;
238     }
239     return false;
240     }
241    
242    
243     bool LinuxSamplerVst::getEffectName(char* name) {
244     vst_strncpy(name, "LinuxSampler", kVstMaxEffectNameLen);
245     return true;
246     }
247    
248    
249     bool LinuxSamplerVst::getVendorString(char* text) {
250     vst_strncpy(text, "linuxsampler.org", kVstMaxVendorStrLen);
251     return true;
252     }
253    
254    
255     bool LinuxSamplerVst::getProductString(char* text) {
256     vst_strncpy(text, "LinuxSampler VST", kVstMaxProductStrLen);
257     return true;
258     }
259    
260    
261     VstInt32 LinuxSamplerVst::getVendorVersion() {
262     return 1000;
263     }
264    
265    
266     VstInt32 LinuxSamplerVst::canDo(char* text) {
267     dmsg(2, ("canDo %s\n", text));
268     if (strcmp(text, "receiveVstEvents") == 0 ||
269     strcmp(text, "receiveVstMidiEvent") == 0) return 1;
270     return -1;
271     }
272    
273     void LinuxSamplerVst::setSampleRate(float sampleRate) {
274     dmsg(2, ("linuxsampler: setSampleRate %f\n", sampleRate));
275     AudioEffectX::setSampleRate(sampleRate);
276     }
277    
278     void LinuxSamplerVst::setBlockSize(VstInt32 blockSize) {
279     dmsg(2, ("linuxsampler: setBlockSize %d\n", blockSize));
280     AudioEffectX::setBlockSize(blockSize);
281     }
282    
283    
284     void LinuxSamplerVst::processReplacing(float** inputs, float** outputs,
285     VstInt32 sampleFrames) {
286     if (pAudioDevice) {
287 persson 1908 for (int i = 0 ; i < CHANNELS ; i++) {
288     pAudioDevice->Channel(i)->SetBuffer(outputs[i]);
289     }
290 persson 1777 pAudioDevice->Render(sampleFrames);
291     } else {
292 persson 1908 for (int i = 0 ; i < CHANNELS ; i++) {
293     memset(outputs[i], 0, sampleFrames * sizeof(float));
294     }
295 persson 1777 }
296     }
297    
298    
299     VstInt32 LinuxSamplerVst::processEvents(VstEvents* ev) {
300     if (pMidiDevice) {
301     for (int i = 0; i < ev->numEvents; i++)
302     {
303     if (ev->events[i]->type == kVstMidiType) {
304     VstMidiEvent* event = reinterpret_cast<VstMidiEvent*>(ev->events[i]);
305     pMidiDevice->Port()->DispatchRaw(reinterpret_cast<uint8_t*>(event->midiData),
306     event->deltaFrames);
307     }
308     }
309     }
310     return 1;
311     }
312    
313    
314     VstInt32 LinuxSamplerVst::getChunk(void** data, bool isPreset) {
315     dmsg(2, ("-->getChunk\n"));
316    
317     String state = GetState();
318     dmsg(2, ("state=\"%s\"\n", state.c_str()));;
319     if (StateBuf) free(StateBuf);
320     StateBuf = strdup(state.c_str());
321     *data = StateBuf;
322     dmsg(2, ("<--getChunk\n"));
323     return state.length() + 1;
324     }
325    
326    
327     VstInt32 LinuxSamplerVst::setChunk(void* data, VstInt32 byteSize,
328     bool isPreset) {
329     dmsg(2, ("-->setChunk byteSize=%d isPreset=%d\n", byteSize, isPreset));
330    
331     const char* state = static_cast<const char*>(data);
332     VstInt32 res = 0;
333     if (byteSize > 0 && state[byteSize - 1] == '\0') {
334     dmsg(2, ("state=\"%s\"\n", state));
335     if (pAudioDevice) {
336     res = SetState(state);
337     } else {
338     SavedChunk = state;
339     }
340     }
341     dmsg(2, ("<--setChunk\n"));
342     return res;
343     }
344     }
345    
346    
347     // *************** VST main function ***************
348     // *
349    
350     AudioEffect* createEffectInstance(audioMasterCallback audioMaster)
351     {
352     return new LinuxSamplerVst(audioMaster);
353     }

  ViewVC Help
Powered by ViewVC