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

  ViewVC Help
Powered by ViewVC