/[svn]/linuxsampler/trunk/src/hostplugins/dssi/PluginDssi.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/hostplugins/dssi/PluginDssi.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2013 - (hide annotations) (download)
Sat Oct 24 09:07:38 2009 UTC (14 years, 6 months ago) by persson
File size: 12816 byte(s)
* fixed compilation error in DSSI plugin
* removed gig engine dependency in DSSI plugin

1 persson 1777 /***************************************************************************
2     * *
3 persson 1858 * 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 <algorithm>
22     #include <cstring>
23     #include <exception>
24     #include <sstream>
25     #include <string>
26    
27     #include "PluginDssi.h"
28    
29 persson 2013 #include "../../engines/AbstractEngineChannel.h"
30 persson 1777
31     namespace {
32    
33     // *************** PluginDssi ***************
34     // *
35    
36 persson 1858 PluginDssi::PluginDssi(unsigned long SampleRate) :
37     RefCount(0) {
38 persson 1777 // As there is no way in DSSI of knowing a max value of the
39     // output buffer size, we set the audio device buffer size to
40     // 128 and let RunSynth call Render in a loop if needed.
41     Init(SampleRate, 128);
42 persson 1858 }
43 persson 1777
44 persson 1858 PluginDssi* PluginInstance::plugin = 0;
45    
46     PluginInstance::PluginInstance(unsigned long SampleRate) {
47     Out[0] = 0;
48     Out[1] = 0;
49    
50     uint outputChannel = 0;
51     uint midiPort = 0;
52     if (!plugin) {
53     plugin = new PluginDssi(SampleRate);
54     }
55     plugin->RefCount++;
56    
57     pChannel = plugin->global->pSampler->AddSamplerChannel();
58 persson 1777 pChannel->SetEngineType("gig");
59 persson 1858 pChannel->SetAudioOutputDevice(plugin->pAudioDevice);
60 persson 2013 pPort = plugin->pMidiDevice->CreateMidiPort();
61     pPort->Connect(pChannel->GetEngineChannel(), LinuxSampler::midi_chan_all);
62 persson 1858
63 persson 2013 LinuxSampler::AbstractEngineChannel* engineChannel =
64     static_cast<LinuxSampler::AbstractEngineChannel*>(pChannel->GetEngineChannel());
65 persson 1858 // TODO: pChannelLeft and pChannelRight are meant to be
66     // protected
67     engineChannel->pChannelLeft = new LinuxSampler::AudioChannel(0, 0, 0);
68     engineChannel->pChannelRight = new LinuxSampler::AudioChannel(1, 0, 0);
69 persson 1777 }
70    
71 persson 1858 PluginInstance::~PluginInstance() {
72 persson 2013 LinuxSampler::AbstractEngineChannel* engineChannel =
73     static_cast<LinuxSampler::AbstractEngineChannel*>(pChannel->GetEngineChannel());
74 persson 1858 delete engineChannel->pChannelLeft;
75     delete engineChannel->pChannelRight;
76    
77     if (--plugin->RefCount == 0) {
78     delete plugin;
79     plugin = 0;
80     } else {
81     plugin->global->pSampler->RemoveSamplerChannel(pChannel);
82     }
83    
84 persson 2013 LinuxSampler::MidiInputDevicePlugin::DeleteMidiPort(pPort);
85 persson 1777 }
86    
87 persson 1858 void PluginInstance::ConnectPort(unsigned long Port, LADSPA_Data* DataLocation) {
88 persson 1777 if (Port < 2) Out[Port] = DataLocation;
89     }
90    
91 persson 1858 char* PluginInstance::Configure(const char* Key, const char* Value) {
92 persson 1777 dmsg(2, ("linuxsampler: configure Key=%s Value=%s\n", Key, Value));
93    
94     if (strcmp(Key, "instrument") == 0 && strcmp(Value, "") != 0) {
95     String filename(Value);
96     String::size_type colon = filename.rfind(':');
97     int instrument = 0;
98     if (colon != String::npos) {
99     std::stringstream(String(filename, colon + 1)) >> instrument;
100     filename.erase(colon);
101     }
102     try {
103     LinuxSampler::EngineChannel* engineChannel =
104     pChannel->GetEngineChannel();
105     dmsg(2, (" before LoadInstrument\n"));
106     engineChannel->PrepareLoadInstrument(filename.c_str(),
107     instrument);
108     engineChannel->LoadInstrument();
109     dmsg(2, (" after LoadInstrument\n"));
110     }
111     catch (std::exception& e) {
112     return strdup(e.what());
113     }
114     }
115    
116     return 0;
117     }
118    
119 persson 1858 inline void PluginInstance::RunMultipleSynths(unsigned long InstanceCount,
120     LADSPA_Handle* Instances,
121     unsigned long SampleCount,
122     snd_seq_event_t** Events,
123     unsigned long* EventCounts) {
124     if (InstanceCount == 0) return;
125    
126     LinuxSampler::AudioOutputDevicePlugin* audioDevice =
127     static_cast<PluginInstance*>(Instances[0])->plugin->pAudioDevice;
128    
129     unsigned eventPosArr[InstanceCount];
130     for (unsigned long i = 0 ; i < InstanceCount ; i++) eventPosArr[i] = 0;
131    
132 persson 1777 int samplePos = 0;
133     while (SampleCount) {
134     int samples = std::min(SampleCount, 128UL);
135    
136 persson 1858 for (unsigned long i = 0 ; i < InstanceCount ; i++) {
137     PluginInstance* instance = static_cast<PluginInstance*>(Instances[i]);
138     LinuxSampler::EngineChannel* engineChannel =
139     instance->pChannel->GetEngineChannel();
140     LinuxSampler::MidiInputPort* port = engineChannel->GetMidiInputPort();
141 persson 1777
142 persson 1858 snd_seq_event_t* events = Events[i];
143     unsigned& eventPos = eventPosArr[i];
144    
145     for ( ; eventPos < EventCounts[i] ; eventPos++) {
146     snd_seq_event_t* ev = &events[eventPos];
147     int time = ev->time.tick - samplePos;
148     if (time >= samples) break;
149     switch (ev->type) {
150     case SND_SEQ_EVENT_CONTROLLER:
151     port->DispatchControlChange(ev->data.control.param,
152     ev->data.control.value,
153     ev->data.control.channel, time);
154     break;
155    
156     case SND_SEQ_EVENT_CHANPRESS:
157     port->DispatchControlChange(128, ev->data.control.value,
158     ev->data.control.channel, time);
159     break;
160    
161     case SND_SEQ_EVENT_PITCHBEND:
162     port->DispatchPitchbend(ev->data.control.value,
163 persson 1777 ev->data.control.channel, time);
164 persson 1858 break;
165 persson 1777
166 persson 1858 case SND_SEQ_EVENT_NOTEON:
167     port->DispatchNoteOn(ev->data.note.note,
168     ev->data.note.velocity,
169     ev->data.control.channel, time);
170     break;
171 persson 1777
172 persson 1858 case SND_SEQ_EVENT_NOTEOFF:
173     port->DispatchNoteOff(ev->data.note.note,
174     ev->data.note.velocity,
175     ev->data.control.channel, time);
176     break;
177 persson 1777
178 persson 1858 case SND_SEQ_EVENT_SYSEX:
179     port->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len);
180     break;
181     }
182     }
183 persson 1777
184 persson 2013 LinuxSampler::AbstractEngineChannel* abstractEngineChannel =
185     static_cast<LinuxSampler::AbstractEngineChannel*>(engineChannel);
186     abstractEngineChannel->pChannelLeft->SetBuffer(instance->Out[0] + samplePos);
187     abstractEngineChannel->pChannelRight->SetBuffer(instance->Out[1] + samplePos);
188 persson 1858 if (i) {
189 persson 2013 abstractEngineChannel->pChannelLeft->Clear(samples);
190     abstractEngineChannel->pChannelRight->Clear(samples);
191 persson 1858 } else {
192     // the buffer set in the audio device is cleared
193     // by Render
194     audioDevice->Channel(0)->SetBuffer(instance->Out[0] + samplePos);
195     audioDevice->Channel(1)->SetBuffer(instance->Out[1] + samplePos);
196 persson 1777 }
197     }
198    
199 persson 1858 audioDevice->Render(samples);
200 persson 1777
201     samplePos += samples;
202     SampleCount -= samples;
203     }
204     }
205    
206 persson 1858 void PluginInstance::Activate() {
207 persson 1777 dmsg(2, ("linuxsampler: activate instance=%p\n", static_cast<void*>(this)));
208 persson 1858 pChannel->GetEngineChannel()->GetMidiInputPort()->DispatchControlChange(123, 0, 0, 0); // all sound off
209 persson 1777 }
210    
211    
212     // *************** LADSPA callback functions ***************
213     // *
214    
215     LADSPA_Handle instantiate(const LADSPA_Descriptor* Descriptor,
216     unsigned long SampleRate) {
217 persson 1858 return new PluginInstance(SampleRate);
218 persson 1777 }
219    
220     void cleanup(LADSPA_Handle Instance) {
221     dmsg(2, ("linuxsampler: cleanup Instance=%p\n", static_cast<void*>(Instance)));
222 persson 1858 delete static_cast<PluginInstance*>(Instance);
223 persson 1777 }
224    
225     void activate(LADSPA_Handle Instance) {
226 persson 1858 static_cast<PluginInstance*>(Instance)->Activate();
227 persson 1777 }
228    
229     void connect_port(LADSPA_Handle Instance, unsigned long Port,
230     LADSPA_Data* DataLocation) {
231 persson 1858 static_cast<PluginInstance*>(Instance)->ConnectPort(Port, DataLocation);
232 persson 1777 }
233    
234     void run(LADSPA_Handle Instance, unsigned long SampleCount) {
235 persson 1858 return;
236 persson 1777 }
237    
238    
239     // *************** DSSI callback functions ***************
240     // *
241    
242     void run_multiple_synths(unsigned long InstanceCount,
243     LADSPA_Handle* Instances,
244     unsigned long SampleCount,
245     snd_seq_event_t** Events,
246 persson 1858 unsigned long* EventCounts) {
247     PluginInstance::RunMultipleSynths(InstanceCount, Instances,
248     SampleCount, Events,
249     EventCounts);
250 persson 1777 }
251    
252     char* configure(LADSPA_Handle Instance, const char* Key, const char* Value) {
253 persson 1858 return static_cast<PluginInstance*>(Instance)->Configure(Key, Value);
254 persson 1777 }
255    
256    
257     // *************** PluginInfo ***************
258     // *
259    
260     PluginInfo PluginInfo::Instance;
261    
262     PluginInfo::PluginInfo() {
263     Ladspa.UniqueID = 3781; // (received from ladspa.org)
264     Ladspa.Label = "LinuxSampler";
265     Ladspa.Properties = 0;
266     Ladspa.Name = "LinuxSampler";
267     Ladspa.Maker = "linuxsampler.org";
268     Ladspa.Copyright = "(C) 2003,2004 Benno Senoner and Christian Schoenebeck, "
269 persson 1858 "2005-2009 Christian Schoenebeck";
270 persson 1777 Ladspa.PortCount = 2;
271     Ladspa.ImplementationData = 0;
272     Ladspa.PortDescriptors = PortDescriptors;
273     Ladspa.PortRangeHints = PortRangeHints;
274     Ladspa.PortNames = PortNames;
275    
276     PortDescriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
277     PortNames[0] = "Output Left";
278     PortRangeHints[0].HintDescriptor = 0;
279     PortDescriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
280     PortNames[1] = "Output Right";
281     PortRangeHints[1].HintDescriptor = 0;
282    
283     Ladspa.activate = activate;
284     Ladspa.cleanup = cleanup;
285     Ladspa.connect_port = connect_port;
286     Ladspa.deactivate = 0;
287     Ladspa.instantiate = instantiate;
288     Ladspa.run = run;
289     Ladspa.run_adding = 0;
290     Ladspa.set_run_adding_gain = 0;
291    
292     Dssi.DSSI_API_Version = 1;
293     Dssi.LADSPA_Plugin = &Ladspa;
294     Dssi.configure = configure;
295     Dssi.get_program = 0;
296     Dssi.get_midi_controller_for_port = 0;
297     Dssi.select_program = 0;
298 persson 1858 Dssi.run_synth = 0;
299 persson 1777 Dssi.run_synth_adding = 0;
300     Dssi.run_multiple_synths = run_multiple_synths;
301     Dssi.run_multiple_synths_adding = 0;
302     }
303     }
304    
305    
306     extern "C" {
307     const LADSPA_Descriptor* ladspa_descriptor(unsigned long Index) {
308     dmsg(2, ("linuxsampler: ladspa_descriptor\n"));
309     return Index == 0 ? PluginInfo::LadspaDescriptor() : 0;
310     }
311    
312     const DSSI_Descriptor *dssi_descriptor(unsigned long Index) {
313     dmsg(2, ("linuxsampler: dssi_descriptor\n"));
314     return Index == 0 ? PluginInfo::DssiDescriptor() : 0;
315     }
316     }

  ViewVC Help
Powered by ViewVC