/[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 1777 - (show annotations) (download)
Mon Sep 15 16:58:10 2008 UTC (15 years, 6 months ago) by persson
File size: 9964 byte(s)
* added experimental support for running LinuxSampler as a DSSI, LV2
  and VST plugin

1 /***************************************************************************
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