/[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 1777 - (hide 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 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 <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