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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1928 - (show annotations) (download)
Fri Jul 3 11:14:46 2009 UTC (11 years, 1 month 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 /***************************************************************************
2 * *
3 * Copyright (C) 2008 - 2009 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 #ifndef CHANNELS
32 #define CHANNELS 32
33 #endif
34
35 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 #ifdef WIN32
74 ProcessHandle = INVALID_HANDLE_VALUE;
75 #endif
76 }
77
78 LinuxSamplerEditor::~LinuxSamplerEditor() {
79 close();
80 }
81
82 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 // 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
100 // assume Fantasia is in the same directory or one directory above
101 // the liblinuxsampler dll
102 String lspath = LinuxSampler::Sampler::GetInstallDir();
103 if (!lspath.empty()) {
104 lspath += "\\";
105 WIN32_FIND_DATA fd;
106 HANDLE hFind = FindFirstFile((lspath + "Fantasia*.jar").c_str(), &fd);
107 if (hFind == INVALID_HANDLE_VALUE) {
108 lspath += "..\\";
109 hFind = FindFirstFile((lspath + "Fantasia*.jar").c_str(), &fd);
110 }
111 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 Command = _tcsdup(TEXT((String("javaw -jar \"") + lspath + fantasia + "\"").c_str()));
123 CreateProcess(NULL, Command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
124 ProcessHandle = pi.hProcess;
125 CloseHandle(pi.hThread);
126 }
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 CloseHandle(ProcessHandle);
140 ProcessHandle = INVALID_HANDLE_VALUE;
141 }
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 setNumOutputs(CHANNELS);
169 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 Init(int(sampleRate), blockSize, CHANNELS);
184
185 if (!SavedChunk.empty()) {
186 SetState(SavedChunk);
187 SavedChunk.clear();
188 } else {
189 InitState();
190 }
191 } else {
192 Init(int(sampleRate), blockSize);
193 }
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 if (index < CHANNELS) {
225 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 for (int i = 0 ; i < CHANNELS ; i++) {
288 pAudioDevice->Channel(i)->SetBuffer(outputs[i]);
289 }
290 pAudioDevice->Render(sampleFrames);
291 } else {
292 for (int i = 0 ; i < CHANNELS ; i++) {
293 memset(outputs[i], 0, sampleFrames * sizeof(float));
294 }
295 }
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