/[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 1895 - (hide annotations) (download)
Sun May 3 12:15:40 2009 UTC (14 years, 10 months ago) by persson
File size: 10218 byte(s)
* fixes for using large audio device buffers
* VST: added support for sample rate and buffer size changes
* VST: close editor (Fantasia) when the VST is removed
* minor fix in configure for mmsystem.h detection on MinGW
* removed warnings from gcc 4.4 and valgrind

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

  ViewVC Help
Powered by ViewVC