/[svn]/linuxsampler/trunk/src/hostplugins/lv2/PluginLv2.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/hostplugins/lv2/PluginLv2.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2837 - (hide annotations) (download)
Sun Aug 23 06:14:00 2015 UTC (4 years, 10 months ago) by persson
File size: 11578 byte(s)
* fixed printf type errors (mostly in debug messages)


1 persson 1777 /***************************************************************************
2     * *
3 persson 2837 * Copyright (C) 2008 - 2015 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 persson 2837 #define _DEFAULT_SOURCE 1
22 persson 2360 #define _BSD_SOURCE 1 /* for realpath() */
23    
24 persson 1777 #include <algorithm>
25 capela 2174 #include <cassert>
26 persson 1777 #include <cstdio>
27     #include <cstdlib>
28     #include <cstring>
29     #include <fstream>
30     #include <string>
31    
32     #include "PluginLv2.h"
33    
34 persson 2356 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
35     #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
36    
37 capela 2174 #define NS_LS "http://linuxsampler.org/schema#"
38    
39 persson 2356 #define CHANNELS 32
40    
41 persson 1777 namespace {
42    
43     PluginLv2::PluginLv2(const LV2_Descriptor* Descriptor,
44     double SampleRate, const char* BundlePath,
45     const LV2_Feature* const* Features) {
46 persson 2356 Out = new float*[CHANNELS];
47     for (int i = 0 ; i < CHANNELS ; i++) {
48     Out[i] = 0;
49     }
50 capela 2174 UriMap = 0;
51 capela 2291 MapPath = 0;
52     MakePath = 0;
53 persson 1777 for (int i = 0 ; Features[i] ; i++) {
54 schoenebeck 2304 dmsg(2, ("linuxsampler: init feature: %s\n", Features[i]->URI));
55 persson 2356 if (!strcmp(Features[i]->URI, LV2_URID__map)) {
56     UriMap = (LV2_URID_Map*)Features[i]->data;
57 capela 2340 } else if (!strcmp(Features[i]->URI, LV2_STATE__mapPath)) {
58 capela 2291 MapPath = (LV2_State_Map_Path*)Features[i]->data;
59 capela 2340 } else if (!strcmp(Features[i]->URI, LV2_STATE__makePath)) {
60 capela 2291 MakePath = (LV2_State_Make_Path*)Features[i]->data;
61 capela 2174 }
62 persson 1777 }
63    
64 persson 2356 MidiEventType = uri_to_id(LV2_MIDI__MidiEvent);
65 persson 1777
66 persson 2356 Init(SampleRate, 128, CHANNELS);
67    
68 persson 1777 InitState();
69 capela 2174
70     DefaultState = GetState();
71 persson 1777 }
72    
73 persson 2356 PluginLv2::~PluginLv2() {
74     delete[] Out;
75     }
76    
77 persson 1777 void PluginLv2::ConnectPort(uint32_t Port, void* DataLocation) {
78 persson 2356 if (Port == 0) {
79     MidiBuf = static_cast<LV2_Atom_Sequence*>(DataLocation);
80     } else if (Port < CHANNELS + 1) {
81     Out[Port - 1] = static_cast<float*>(DataLocation);
82 persson 1777 }
83     }
84    
85     void PluginLv2::Activate() {
86     dmsg(2, ("linuxsampler: Activate\n"));
87     }
88    
89     void PluginLv2::Run(uint32_t SampleCount) {
90     int samplePos = 0;
91 persson 2356
92     LV2_Atom_Event* ev = lv2_atom_sequence_begin(&MidiBuf->body);
93    
94 persson 1777 while (SampleCount) {
95     int samples = std::min(SampleCount, 128U);
96    
97 persson 2356 for ( ; !lv2_atom_sequence_is_end(&MidiBuf->body,
98     MidiBuf->atom.size, ev) ;
99     ev = lv2_atom_sequence_next(ev)) {
100     if (ev->body.type == MidiEventType) {
101 persson 1777
102 persson 2356 int time = ev->time.frames - samplePos;
103     if (time >= samples) break;
104 persson 1777
105 persson 2356 uint8_t* data = reinterpret_cast<uint8_t*>(ev + 1);
106 persson 1777
107 persson 2356 pMidiDevice->Port()->DispatchRaw(data, time);
108     }
109 persson 1777 }
110 persson 2356 for (int i = 0 ; i < CHANNELS ; i++) {
111     pAudioDevice->Channel(i)->SetBuffer(Out[i] + samplePos);
112     }
113 persson 1777 pAudioDevice->Render(samples);
114    
115     samplePos += samples;
116     SampleCount -= samples;
117     }
118     }
119    
120     void PluginLv2::Deactivate() {
121     dmsg(2, ("linuxsampler: Deactivate\n"));
122     }
123    
124 persson 2360 static String RealPath(const String& path)
125     {
126     String out = path;
127     char* cpath = NULL;
128     #ifdef _WIN32
129     cpath = (char*)malloc(MAX_PATH);
130     GetFullPathName(path.c_str(), MAX_PATH, cpath, NULL);
131     #else
132     cpath = realpath(path.c_str(), NULL);
133     #endif
134     if (cpath) {
135     out = cpath;
136     free(cpath);
137     }
138     return out;
139     }
140    
141 capela 2174 String PluginLv2::PathToState(const String& path) {
142 capela 2291 if (MapPath) {
143 schoenebeck 2304 char* cstr = MapPath->abstract_path(MapPath->handle, path.c_str());
144 capela 2174 const String abstract_path(cstr);
145     free(cstr);
146     return abstract_path;
147     }
148     return path;
149     }
150 persson 1777
151 capela 2174 String PluginLv2::PathFromState(const String& path) {
152 capela 2291 if (MapPath) {
153 schoenebeck 2304 char* cstr = MapPath->absolute_path(MapPath->handle, path.c_str());
154 persson 2360 // Resolve symbolic links so SFZ sample paths load correctly
155     const String absolute_path(RealPath(cstr));
156 capela 2174 free(cstr);
157 persson 2360 return absolute_path;
158 capela 2174 }
159     return path;
160     }
161 persson 1777
162 schoenebeck 2304 void PluginLv2::SetStateFeatures(const LV2_Feature* const* Features)
163     {
164     for (int i = 0 ; Features[i] ; i++) {
165     dmsg(2, ("linuxsampler: state feature: %s\n", Features[i]->URI));
166 capela 2340 if (!strcmp(Features[i]->URI, LV2_STATE__mapPath)) {
167 schoenebeck 2304 MapPath = (LV2_State_Map_Path*)Features[i]->data;
168 capela 2340 } else if (!strcmp(Features[i]->URI, LV2_STATE__makePath)) {
169 schoenebeck 2304 MakePath = (LV2_State_Make_Path*)Features[i]->data;
170     }
171     }
172     }
173 persson 1777
174 capela 2340 LV2_State_Status PluginLv2::Save(
175 persson 2356 LV2_State_Store_Function store, LV2_State_Handle handle,
176     uint32_t flags, const LV2_Feature* const* features)
177 schoenebeck 2304 {
178     LV2_State_Map_Path* OldMapPath = MapPath;
179     LV2_State_Make_Path* OldMakePath = MakePath;
180     SetStateFeatures(features);
181    
182     if (MakePath && MapPath) {
183     char* abs_path = MakePath->path(MakePath->handle, "linuxsampler");
184     dmsg(2, ("saving to file %s\n", abs_path));
185    
186     std::ofstream out(abs_path);
187 capela 2174 out << GetState();
188 persson 1777
189 schoenebeck 2304 char* path = MapPath->abstract_path(MapPath->handle, abs_path);
190    
191 capela 2291 store(handle,
192 persson 2356 uri_to_id(NS_LS "state-file"),
193 capela 2291 path,
194     strlen(path) + 1,
195 persson 2356 uri_to_id(LV2_ATOM__Path),
196 capela 2291 LV2_STATE_IS_PORTABLE);
197 schoenebeck 2304
198     free(path);
199     free(abs_path);
200 capela 2174 } else {
201     dmsg(2, ("saving to string\n"));
202 persson 1777
203 capela 2174 std::ostringstream out;
204     out << GetState();
205    
206 capela 2291 store(handle,
207 persson 2356 uri_to_id(NS_LS "state-string"),
208 capela 2174 out.str().c_str(),
209     out.str().length() + 1,
210 persson 2356 uri_to_id(LV2_ATOM__String),
211 capela 2291 LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
212 capela 2174 }
213 persson 1777 dmsg(2, ("saving done\n"));
214 schoenebeck 2304
215     MapPath = OldMapPath;
216     MakePath = OldMakePath;
217 capela 2340
218     return LV2_STATE_SUCCESS;
219 persson 1777 }
220    
221 capela 2340 LV2_State_Status PluginLv2::Restore(
222 persson 2356 LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle,
223     uint32_t rflags, const LV2_Feature* const* features)
224 schoenebeck 2304 {
225     LV2_State_Map_Path* OldMapPath = MapPath;
226     LV2_State_Make_Path* OldMakePath = MakePath;
227     SetStateFeatures(features);
228    
229 capela 2174 size_t size;
230     uint32_t type;
231     uint32_t flags;
232    
233     const void* value = retrieve(
234 capela 2291 handle,
235 persson 2356 uri_to_id(NS_LS "state-file"),
236 capela 2174 &size, &type, &flags);
237     if (value) {
238 persson 2311 // Restore from state-file
239 persson 2356 assert(type == uri_to_id(LV2_ATOM__Path));
240 capela 2291 const String path((const char*)value);
241 capela 2174 dmsg(2, ("linuxsampler: restoring from file %s\n", path.c_str()));
242     std::ifstream in(path.c_str());
243     String state;
244     std::getline(in, state, '\0');
245     SetState(state);
246 persson 2311 } else if ((value = retrieve(handle,
247 persson 2356 uri_to_id(NS_LS "state-string"),
248 persson 2311 &size, &type, &flags))) {
249     // Restore from state-string
250 capela 2174 dmsg(2, ("linuxsampler: restoring from string\n"));
251 persson 2356 assert(type == uri_to_id(LV2_ATOM__String));
252 capela 2174 String state((const char*)value);
253     SetState(state);
254 persson 2311 } else {
255     // No valid state found, reset to default state
256     dmsg(2, ("linuxsampler: restoring default state\n"));
257     SetState(DefaultState);
258 capela 2174 }
259    
260 persson 2311 MapPath = OldMapPath;
261     MakePath = OldMakePath;
262 schoenebeck 2304
263 capela 2340 return LV2_STATE_SUCCESS;
264 persson 1777 }
265    
266     LV2_Handle instantiate(const LV2_Descriptor* descriptor,
267     double sample_rate, const char* bundle_path,
268     const LV2_Feature* const* features) {
269     return new PluginLv2(descriptor, sample_rate, bundle_path, features);
270     }
271    
272     void connect_port(LV2_Handle instance, uint32_t port, void* data_location) {
273     static_cast<PluginLv2*>(instance)->ConnectPort(port, data_location);
274     }
275    
276     void activate(LV2_Handle instance) {
277     static_cast<PluginLv2*>(instance)->Activate();
278     }
279    
280     void run(LV2_Handle instance, uint32_t sample_count) {
281     static_cast<PluginLv2*>(instance)->Run(sample_count);
282     }
283    
284     void deactivate(LV2_Handle instance) {
285     static_cast<PluginLv2*>(instance)->Deactivate();
286     }
287    
288     void cleanup(LV2_Handle instance) {
289     delete static_cast<PluginLv2*>(instance);
290     }
291    
292 capela 2340 LV2_State_Status save(LV2_Handle handle, LV2_State_Store_Function store,
293     LV2_State_Handle state,
294     uint32_t flags, const LV2_Feature* const* features) {
295 schoenebeck 2304 return static_cast<PluginLv2*>(handle)->Save(
296     store, state, flags, features);
297 persson 1777 }
298    
299 capela 2340 LV2_State_Status restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve,
300     LV2_State_Handle state,
301     uint32_t flags, const LV2_Feature* const* features) {
302 schoenebeck 2304 return static_cast<PluginLv2*>(handle)->Restore(
303     retrieve, state, flags, features);
304 persson 1777 }
305    
306     PluginInfo PluginInfo::Instance;
307    
308     PluginInfo::PluginInfo() {
309     Lv2.URI = "http://linuxsampler.org/plugins/linuxsampler";
310     Lv2.activate = activate;
311     Lv2.cleanup = cleanup;
312     Lv2.connect_port = connect_port;
313     Lv2.deactivate = deactivate;
314     Lv2.instantiate = instantiate;
315     Lv2.run = run;
316     Lv2.extension_data = extension_data;
317 capela 2291 StateInterface.save = save;
318     StateInterface.restore = restore;
319 persson 1777 }
320    
321    
322     const void* extension_data(const char* uri) {
323     dmsg(2, ("linuxsampler: extension_data %s\n", uri));
324 capela 2340 if (strcmp(uri, LV2_STATE__interface) == 0) {
325 capela 2291 return PluginInfo::Lv2StateInterface();
326 persson 1777 }
327     return 0;
328     }
329     }
330    
331    
332     extern "C" {
333     LV2_SYMBOL_EXPORT
334     const LV2_Descriptor* lv2_descriptor(uint32_t index) {
335     return index == 0 ? PluginInfo::Lv2Descriptor() : 0;
336     }
337     }

  ViewVC Help
Powered by ViewVC