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

  ViewVC Help
Powered by ViewVC