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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2013 - (show 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 /***************************************************************************
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 <algorithm>
22 #include <cstring>
23 #include <exception>
24 #include <sstream>
25 #include <string>
26
27 #include "PluginDssi.h"
28
29 #include "../../engines/AbstractEngineChannel.h"
30
31 namespace {
32
33 // *************** PluginDssi ***************
34 // *
35
36 PluginDssi::PluginDssi(unsigned long SampleRate) :
37 RefCount(0) {
38 // 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 }
43
44 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 pChannel->SetEngineType("gig");
59 pChannel->SetAudioOutputDevice(plugin->pAudioDevice);
60 pPort = plugin->pMidiDevice->CreateMidiPort();
61 pPort->Connect(pChannel->GetEngineChannel(), LinuxSampler::midi_chan_all);
62
63 LinuxSampler::AbstractEngineChannel* engineChannel =
64 static_cast<LinuxSampler::AbstractEngineChannel*>(pChannel->GetEngineChannel());
65 // 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 }
70
71 PluginInstance::~PluginInstance() {
72 LinuxSampler::AbstractEngineChannel* engineChannel =
73 static_cast<LinuxSampler::AbstractEngineChannel*>(pChannel->GetEngineChannel());
74 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 LinuxSampler::MidiInputDevicePlugin::DeleteMidiPort(pPort);
85 }
86
87 void PluginInstance::ConnectPort(unsigned long Port, LADSPA_Data* DataLocation) {
88 if (Port < 2) Out[Port] = DataLocation;
89 }
90
91 char* PluginInstance::Configure(const char* Key, const char* Value) {
92 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 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 int samplePos = 0;
133 while (SampleCount) {
134 int samples = std::min(SampleCount, 128UL);
135
136 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
142 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 ev->data.control.channel, time);
164 break;
165
166 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
172 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
178 case SND_SEQ_EVENT_SYSEX:
179 port->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len);
180 break;
181 }
182 }
183
184 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 if (i) {
189 abstractEngineChannel->pChannelLeft->Clear(samples);
190 abstractEngineChannel->pChannelRight->Clear(samples);
191 } 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 }
197 }
198
199 audioDevice->Render(samples);
200
201 samplePos += samples;
202 SampleCount -= samples;
203 }
204 }
205
206 void PluginInstance::Activate() {
207 dmsg(2, ("linuxsampler: activate instance=%p\n", static_cast<void*>(this)));
208 pChannel->GetEngineChannel()->GetMidiInputPort()->DispatchControlChange(123, 0, 0, 0); // all sound off
209 }
210
211
212 // *************** LADSPA callback functions ***************
213 // *
214
215 LADSPA_Handle instantiate(const LADSPA_Descriptor* Descriptor,
216 unsigned long SampleRate) {
217 return new PluginInstance(SampleRate);
218 }
219
220 void cleanup(LADSPA_Handle Instance) {
221 dmsg(2, ("linuxsampler: cleanup Instance=%p\n", static_cast<void*>(Instance)));
222 delete static_cast<PluginInstance*>(Instance);
223 }
224
225 void activate(LADSPA_Handle Instance) {
226 static_cast<PluginInstance*>(Instance)->Activate();
227 }
228
229 void connect_port(LADSPA_Handle Instance, unsigned long Port,
230 LADSPA_Data* DataLocation) {
231 static_cast<PluginInstance*>(Instance)->ConnectPort(Port, DataLocation);
232 }
233
234 void run(LADSPA_Handle Instance, unsigned long SampleCount) {
235 return;
236 }
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 unsigned long* EventCounts) {
247 PluginInstance::RunMultipleSynths(InstanceCount, Instances,
248 SampleCount, Events,
249 EventCounts);
250 }
251
252 char* configure(LADSPA_Handle Instance, const char* Key, const char* Value) {
253 return static_cast<PluginInstance*>(Instance)->Configure(Key, Value);
254 }
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 "2005-2009 Christian Schoenebeck";
270 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 Dssi.run_synth = 0;
299 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