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

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

Parent Directory Parent Directory | Revision Log Revision Log


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


1 /***************************************************************************
2 * *
3 * Copyright (C) 2008 - 2015 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 #define _DEFAULT_SOURCE 1
22 #define _BSD_SOURCE 1 /* for realpath() */
23
24 #include <algorithm>
25 #include <cassert>
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cstring>
29 #include <fstream>
30 #include <string>
31
32 #include "PluginLv2.h"
33
34 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
35 #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
36
37 #define NS_LS "http://linuxsampler.org/schema#"
38
39 #define CHANNELS 32
40
41 namespace {
42
43 PluginLv2::PluginLv2(const LV2_Descriptor* Descriptor,
44 double SampleRate, const char* BundlePath,
45 const LV2_Feature* const* Features) {
46 Out = new float*[CHANNELS];
47 for (int i = 0 ; i < CHANNELS ; i++) {
48 Out[i] = 0;
49 }
50 UriMap = 0;
51 MapPath = 0;
52 MakePath = 0;
53 for (int i = 0 ; Features[i] ; i++) {
54 dmsg(2, ("linuxsampler: init feature: %s\n", Features[i]->URI));
55 if (!strcmp(Features[i]->URI, LV2_URID__map)) {
56 UriMap = (LV2_URID_Map*)Features[i]->data;
57 } else if (!strcmp(Features[i]->URI, LV2_STATE__mapPath)) {
58 MapPath = (LV2_State_Map_Path*)Features[i]->data;
59 } else if (!strcmp(Features[i]->URI, LV2_STATE__makePath)) {
60 MakePath = (LV2_State_Make_Path*)Features[i]->data;
61 }
62 }
63
64 MidiEventType = uri_to_id(LV2_MIDI__MidiEvent);
65
66 Init(SampleRate, 128, CHANNELS);
67
68 InitState();
69
70 DefaultState = GetState();
71 }
72
73 PluginLv2::~PluginLv2() {
74 delete[] Out;
75 }
76
77 void PluginLv2::ConnectPort(uint32_t Port, void* DataLocation) {
78 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 }
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
92 LV2_Atom_Event* ev = lv2_atom_sequence_begin(&MidiBuf->body);
93
94 while (SampleCount) {
95 int samples = std::min(SampleCount, 128U);
96
97 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
102 int time = ev->time.frames - samplePos;
103 if (time >= samples) break;
104
105 uint8_t* data = reinterpret_cast<uint8_t*>(ev + 1);
106
107 pMidiDevice->Port()->DispatchRaw(data, time);
108 }
109 }
110 for (int i = 0 ; i < CHANNELS ; i++) {
111 pAudioDevice->Channel(i)->SetBuffer(Out[i] + samplePos);
112 }
113 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 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 String PluginLv2::PathToState(const String& path) {
142 if (MapPath) {
143 char* cstr = MapPath->abstract_path(MapPath->handle, path.c_str());
144 const String abstract_path(cstr);
145 free(cstr);
146 return abstract_path;
147 }
148 return path;
149 }
150
151 String PluginLv2::PathFromState(const String& path) {
152 if (MapPath) {
153 char* cstr = MapPath->absolute_path(MapPath->handle, path.c_str());
154 // Resolve symbolic links so SFZ sample paths load correctly
155 const String absolute_path(RealPath(cstr));
156 free(cstr);
157 return absolute_path;
158 }
159 return path;
160 }
161
162 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 if (!strcmp(Features[i]->URI, LV2_STATE__mapPath)) {
167 MapPath = (LV2_State_Map_Path*)Features[i]->data;
168 } else if (!strcmp(Features[i]->URI, LV2_STATE__makePath)) {
169 MakePath = (LV2_State_Make_Path*)Features[i]->data;
170 }
171 }
172 }
173
174 LV2_State_Status PluginLv2::Save(
175 LV2_State_Store_Function store, LV2_State_Handle handle,
176 uint32_t flags, const LV2_Feature* const* features)
177 {
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 out << GetState();
188
189 char* path = MapPath->abstract_path(MapPath->handle, abs_path);
190
191 store(handle,
192 uri_to_id(NS_LS "state-file"),
193 path,
194 strlen(path) + 1,
195 uri_to_id(LV2_ATOM__Path),
196 LV2_STATE_IS_PORTABLE);
197
198 free(path);
199 free(abs_path);
200 } else {
201 dmsg(2, ("saving to string\n"));
202
203 std::ostringstream out;
204 out << GetState();
205
206 store(handle,
207 uri_to_id(NS_LS "state-string"),
208 out.str().c_str(),
209 out.str().length() + 1,
210 uri_to_id(LV2_ATOM__String),
211 LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
212 }
213 dmsg(2, ("saving done\n"));
214
215 MapPath = OldMapPath;
216 MakePath = OldMakePath;
217
218 return LV2_STATE_SUCCESS;
219 }
220
221 LV2_State_Status PluginLv2::Restore(
222 LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle,
223 uint32_t rflags, const LV2_Feature* const* features)
224 {
225 LV2_State_Map_Path* OldMapPath = MapPath;
226 LV2_State_Make_Path* OldMakePath = MakePath;
227 SetStateFeatures(features);
228
229 size_t size;
230 uint32_t type;
231 uint32_t flags;
232
233 const void* value = retrieve(
234 handle,
235 uri_to_id(NS_LS "state-file"),
236 &size, &type, &flags);
237 if (value) {
238 // Restore from state-file
239 assert(type == uri_to_id(LV2_ATOM__Path));
240 const String path((const char*)value);
241 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 } else if ((value = retrieve(handle,
247 uri_to_id(NS_LS "state-string"),
248 &size, &type, &flags))) {
249 // Restore from state-string
250 dmsg(2, ("linuxsampler: restoring from string\n"));
251 assert(type == uri_to_id(LV2_ATOM__String));
252 String state((const char*)value);
253 SetState(state);
254 } else {
255 // No valid state found, reset to default state
256 dmsg(2, ("linuxsampler: restoring default state\n"));
257 SetState(DefaultState);
258 }
259
260 MapPath = OldMapPath;
261 MakePath = OldMakePath;
262
263 return LV2_STATE_SUCCESS;
264 }
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 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 return static_cast<PluginLv2*>(handle)->Save(
296 store, state, flags, features);
297 }
298
299 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 return static_cast<PluginLv2*>(handle)->Restore(
303 retrieve, state, flags, features);
304 }
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 StateInterface.save = save;
318 StateInterface.restore = restore;
319 }
320
321
322 const void* extension_data(const char* uri) {
323 dmsg(2, ("linuxsampler: extension_data %s\n", uri));
324 if (strcmp(uri, LV2_STATE__interface) == 0) {
325 return PluginInfo::Lv2StateInterface();
326 }
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