/[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 1897 - (show annotations) (download)
Sun May 10 09:31:51 2009 UTC (14 years, 11 months ago) by persson
File size: 10224 byte(s)
* Windows: look for editor plugins and Fantasia using base directory
  of liblinuxsampler dll
* lscp bugfix: SET CHANNEL MIDI_INPUT_TYPE didn't work with the MME
  driver

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 #ifdef WIN32
70 ProcessHandle = INVALID_HANDLE_VALUE;
71 #endif
72 }
73
74 LinuxSamplerEditor::~LinuxSamplerEditor() {
75 close();
76 }
77
78 bool LinuxSamplerEditor::open(void* ptr) {
79 dmsg(2, ("-->LinuxSamplerEditor::open\n"));
80 AEffEditor::open(ptr);
81
82 #ifdef WIN32
83 // try to start the JSample Fantasia GUI as a separate process
84
85 ProcessHandle = INVALID_HANDLE_VALUE;
86
87 // assume Fantasia is in the same directory as the
88 // liblinuxsampler dll
89 String lspath = LinuxSampler::Sampler::GetInstallDir();
90 if (!lspath.empty()) {
91 lspath += "\\";
92 WIN32_FIND_DATA fd;
93 HANDLE hFind = FindFirstFile((lspath + "Fantasia*.jar").c_str(), &fd);
94 if (hFind != INVALID_HANDLE_VALUE) {
95 String fantasia(fd.cFileName);
96 FindClose(hFind);
97
98 // start a java process
99 STARTUPINFO si;
100 PROCESS_INFORMATION pi;
101 ZeroMemory(&si, sizeof(si));
102 si.cb = sizeof(si);
103 ZeroMemory(&pi, sizeof(pi));
104
105 Command = _tcsdup(TEXT((String("javaw -jar \"") + lspath + fantasia + "\" &").c_str()));
106 CreateProcess(NULL, Command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
107 ProcessHandle = pi.hProcess;
108 }
109 }
110 #endif
111 dmsg(2, ("<--LinuxSamplerEditor::open\n"));
112 return true;
113 }
114
115 void LinuxSamplerEditor::close() {
116 systemWindow = 0;
117 #ifdef WIN32
118 if (ProcessHandle != INVALID_HANDLE_VALUE) {
119 TerminateProcess(ProcessHandle, 0);
120 free(Command);
121 ProcessHandle = INVALID_HANDLE_VALUE;
122 }
123 #endif
124 }
125
126 bool LinuxSamplerEditor::getRect(ERect** rect) {
127 ERect* r = new ERect();
128 r->top = 0;
129 r->left = 0;
130 r->bottom = 0;
131 r->right = 400;
132 *rect = r;
133 return true;
134 }
135
136
137 // *************** LinuxSamplerVst ***************
138 // *
139
140 LinuxSamplerVst::LinuxSamplerVst(audioMasterCallback audioMaster) :
141 AudioEffectX(audioMaster, NbPrograms, 0),
142 StateBuf(0)
143 {
144 dmsg(2, ("-->constructor\n"));
145
146 Programs = new LinuxSamplerVstProgram[NbPrograms];
147 setProgram(0);
148 setNumInputs(0);
149 setNumOutputs(2);
150 canProcessReplacing();
151 isSynth();
152 programsAreChunks();
153 setUniqueID(CCONST('L', 'S', 'm', 'p')); // (registred at Steinberg)
154 setEditor(new LinuxSamplerEditor(this));
155
156 suspend();
157 dmsg(2, ("<--constructor\n"));
158 }
159
160
161 void LinuxSamplerVst::resume() {
162 dmsg(2, ("-->resume\n"));
163 if (!pAudioDevice) {
164 Init(int(sampleRate), blockSize);
165
166 if (!SavedChunk.empty()) {
167 SetState(SavedChunk);
168 SavedChunk.clear();
169 } else {
170 InitState();
171 }
172 } else {
173 Init(int(sampleRate), blockSize);
174 }
175 dmsg(2, ("<--resume\n"));
176 }
177
178 LinuxSamplerVst::~LinuxSamplerVst() {
179 dmsg(2, ("-->destructor\n"));
180 delete[] Programs;
181 if (StateBuf) free(StateBuf);
182 dmsg(2, ("<--destructor\n"));
183 }
184
185
186 void LinuxSamplerVst::setProgram(VstInt32 program) {
187 if (program < 0 || program >= NbPrograms) return;
188
189 curProgram = program;
190 }
191
192
193 void LinuxSamplerVst::setProgramName(char* name) {
194 vst_strncpy(Programs[curProgram].name, name, kVstMaxProgNameLen);
195 }
196
197
198 void LinuxSamplerVst::getProgramName(char* name) {
199 vst_strncpy(name, Programs[curProgram].name, kVstMaxProgNameLen);
200 }
201
202
203 bool LinuxSamplerVst::getOutputProperties(VstInt32 index,
204 VstPinProperties* properties) {
205 if (index < 2) {
206 sprintf(properties->label, "LS %d", index + 1);
207 properties->flags = kVstPinIsActive | kVstPinIsStereo;
208 return true;
209 }
210 return false;
211 }
212
213
214 bool LinuxSamplerVst::getProgramNameIndexed(VstInt32 category, VstInt32 index,
215 char* text) {
216 if (index < NbPrograms) {
217 vst_strncpy(text, Programs[index].name, kVstMaxProgNameLen);
218 return true;
219 }
220 return false;
221 }
222
223
224 bool LinuxSamplerVst::getEffectName(char* name) {
225 vst_strncpy(name, "LinuxSampler", kVstMaxEffectNameLen);
226 return true;
227 }
228
229
230 bool LinuxSamplerVst::getVendorString(char* text) {
231 vst_strncpy(text, "linuxsampler.org", kVstMaxVendorStrLen);
232 return true;
233 }
234
235
236 bool LinuxSamplerVst::getProductString(char* text) {
237 vst_strncpy(text, "LinuxSampler VST", kVstMaxProductStrLen);
238 return true;
239 }
240
241
242 VstInt32 LinuxSamplerVst::getVendorVersion() {
243 return 1000;
244 }
245
246
247 VstInt32 LinuxSamplerVst::canDo(char* text) {
248 dmsg(2, ("canDo %s\n", text));
249 if (strcmp(text, "receiveVstEvents") == 0 ||
250 strcmp(text, "receiveVstMidiEvent") == 0) return 1;
251 return -1;
252 }
253
254 void LinuxSamplerVst::setSampleRate(float sampleRate) {
255 dmsg(2, ("linuxsampler: setSampleRate %f\n", sampleRate));
256 AudioEffectX::setSampleRate(sampleRate);
257 }
258
259 void LinuxSamplerVst::setBlockSize(VstInt32 blockSize) {
260 dmsg(2, ("linuxsampler: setBlockSize %d\n", blockSize));
261 AudioEffectX::setBlockSize(blockSize);
262 }
263
264
265 void LinuxSamplerVst::processReplacing(float** inputs, float** outputs,
266 VstInt32 sampleFrames) {
267 if (pAudioDevice) {
268 pAudioDevice->Channel(0)->SetBuffer(outputs[0]);
269 pAudioDevice->Channel(1)->SetBuffer(outputs[1]);
270 pAudioDevice->Render(sampleFrames);
271 } else {
272 memset(outputs[0], 0, sampleFrames * sizeof(float));
273 memset(outputs[1], 0, sampleFrames * sizeof(float));
274 }
275 }
276
277
278 VstInt32 LinuxSamplerVst::processEvents(VstEvents* ev) {
279 if (pMidiDevice) {
280 for (int i = 0; i < ev->numEvents; i++)
281 {
282 if (ev->events[i]->type == kVstMidiType) {
283 VstMidiEvent* event = reinterpret_cast<VstMidiEvent*>(ev->events[i]);
284 pMidiDevice->Port()->DispatchRaw(reinterpret_cast<uint8_t*>(event->midiData),
285 event->deltaFrames);
286 }
287 }
288 }
289 return 1;
290 }
291
292
293 VstInt32 LinuxSamplerVst::getChunk(void** data, bool isPreset) {
294 dmsg(2, ("-->getChunk\n"));
295
296 String state = GetState();
297 dmsg(2, ("state=\"%s\"\n", state.c_str()));;
298 if (StateBuf) free(StateBuf);
299 StateBuf = strdup(state.c_str());
300 *data = StateBuf;
301 dmsg(2, ("<--getChunk\n"));
302 return state.length() + 1;
303 }
304
305
306 VstInt32 LinuxSamplerVst::setChunk(void* data, VstInt32 byteSize,
307 bool isPreset) {
308 dmsg(2, ("-->setChunk byteSize=%d isPreset=%d\n", byteSize, isPreset));
309
310 const char* state = static_cast<const char*>(data);
311 VstInt32 res = 0;
312 if (byteSize > 0 && state[byteSize - 1] == '\0') {
313 dmsg(2, ("state=\"%s\"\n", state));
314 if (pAudioDevice) {
315 res = SetState(state);
316 } else {
317 SavedChunk = state;
318 }
319 }
320 dmsg(2, ("<--setChunk\n"));
321 return res;
322 }
323 }
324
325
326 // *************** VST main function ***************
327 // *
328
329 AudioEffect* createEffectInstance(audioMasterCallback audioMaster)
330 {
331 return new LinuxSamplerVst(audioMaster);
332 }

  ViewVC Help
Powered by ViewVC