/[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 2311 - (show annotations) (download)
Sat Feb 11 11:08:09 2012 UTC (12 years, 2 months ago) by persson
File size: 10674 byte(s)
* more LV2 "state" extension support fixes (patch by David Robillard)
* sfz parser: allow double spaces in sample filenames
* sfz parser: allow absolute paths for sample filenames
* MME driver: fixed memory handling bug found with cppcheck
* sfz/sf2 engines: use linear decay and release for filter and pitch
  envelope generators

1 /***************************************************************************
2 * *
3 * Copyright (C) 2008 - 2012 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 <cassert>
23 #include <cstdio>
24 #include <cstdlib>
25 #include <cstring>
26 #include <fstream>
27 #include <string>
28
29 #include "PluginLv2.h"
30
31 #define NS_ATOM "http://lv2plug.in/ns/ext/atom#"
32 #define NS_LS "http://linuxsampler.org/schema#"
33
34 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 UriMap = 0;
42 MapPath = 0;
43 MakePath = 0;
44 for (int i = 0 ; Features[i] ; i++) {
45 dmsg(2, ("linuxsampler: init feature: %s\n", Features[i]->URI));
46 if (!strcmp(Features[i]->URI, LV2_URI_MAP_URI)) {
47 UriMap = (LV2_URI_Map_Feature*)Features[i]->data;
48 } else if (!strcmp(Features[i]->URI, LV2_STATE_MAP_PATH_URI)) {
49 MapPath = (LV2_State_Map_Path*)Features[i]->data;
50 } else if (!strcmp(Features[i]->URI, LV2_STATE_MAKE_PATH_URI)) {
51 MakePath = (LV2_State_Make_Path*)Features[i]->data;
52 }
53 }
54
55 Init(SampleRate, 128);
56
57 InitState();
58
59 DefaultState = GetState();
60 }
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 String PluginLv2::PathToState(const String& path) {
106 if (MapPath) {
107 char* cstr = MapPath->abstract_path(MapPath->handle, path.c_str());
108 const String abstract_path(cstr);
109 free(cstr);
110 return abstract_path;
111 }
112 return path;
113 }
114
115 String PluginLv2::PathFromState(const String& path) {
116 if (MapPath) {
117 char* cstr = MapPath->absolute_path(MapPath->handle, path.c_str());
118 const String abstract_path(cstr);
119 free(cstr);
120 return abstract_path;
121 }
122 return path;
123 }
124
125 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 if (!strcmp(Features[i]->URI, LV2_STATE_MAP_PATH_URI)) {
130 MapPath = (LV2_State_Map_Path*)Features[i]->data;
131 } else if (!strcmp(Features[i]->URI, LV2_STATE_MAKE_PATH_URI)) {
132 MakePath = (LV2_State_Make_Path*)Features[i]->data;
133 }
134 }
135 }
136
137 void PluginLv2::Save(LV2_State_Store_Function store, LV2_State_Handle handle,
138 uint32_t flags, const LV2_Feature* const* features)
139 {
140 LV2_State_Map_Path* OldMapPath = MapPath;
141 LV2_State_Make_Path* OldMakePath = MakePath;
142 SetStateFeatures(features);
143
144 if (MakePath && MapPath) {
145 char* abs_path = MakePath->path(MakePath->handle, "linuxsampler");
146 dmsg(2, ("saving to file %s\n", abs_path));
147
148 std::ofstream out(abs_path);
149 out << GetState();
150
151 char* path = MapPath->abstract_path(MapPath->handle, abs_path);
152
153 store(handle,
154 uri_to_id(NULL, NS_LS "state-file"),
155 path,
156 strlen(path) + 1,
157 uri_to_id(NULL, LV2_STATE_PATH_URI),
158 LV2_STATE_IS_PORTABLE);
159
160 free(path);
161 free(abs_path);
162 } else {
163 dmsg(2, ("saving to string\n"));
164
165 std::ostringstream out;
166 out << GetState();
167
168 store(handle,
169 uri_to_id(NULL, NS_LS "state-string"),
170 out.str().c_str(),
171 out.str().length() + 1,
172 uri_to_id(NULL, NS_ATOM "String"),
173 LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
174 }
175 dmsg(2, ("saving done\n"));
176
177 MapPath = OldMapPath;
178 MakePath = OldMakePath;
179 }
180
181 void PluginLv2::Restore(LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle,
182 uint32_t rflags, const LV2_Feature* const* features)
183 {
184 LV2_State_Map_Path* OldMapPath = MapPath;
185 LV2_State_Make_Path* OldMakePath = MakePath;
186 SetStateFeatures(features);
187
188 size_t size;
189 uint32_t type;
190 uint32_t flags;
191
192 const void* value = retrieve(
193 handle,
194 uri_to_id(NULL, NS_LS "state-file"),
195 &size, &type, &flags);
196 if (value) {
197 // Restore from state-file
198 assert(type == uri_to_id(NULL, LV2_STATE_PATH_URI));
199 const String path((const char*)value);
200 dmsg(2, ("linuxsampler: restoring from file %s\n", path.c_str()));
201 std::ifstream in(path.c_str());
202 String state;
203 std::getline(in, state, '\0');
204 SetState(state);
205 } else if ((value = retrieve(handle,
206 uri_to_id(NULL, NS_LS "state-string"),
207 &size, &type, &flags))) {
208 // Restore from state-string
209 dmsg(2, ("linuxsampler: restoring from string\n"));
210 assert(type == uri_to_id(NULL, NS_ATOM "String"));
211 String state((const char*)value);
212 SetState(state);
213 } else {
214 // No valid state found, reset to default state
215 dmsg(2, ("linuxsampler: restoring default state\n"));
216 SetState(DefaultState);
217 }
218
219 MapPath = OldMapPath;
220 MakePath = OldMakePath;
221
222 MapPath = OldMapPath;
223 MakePath = OldMakePath;
224 }
225
226 LV2_Handle instantiate(const LV2_Descriptor* descriptor,
227 double sample_rate, const char* bundle_path,
228 const LV2_Feature* const* features) {
229 return new PluginLv2(descriptor, sample_rate, bundle_path, features);
230 }
231
232 void connect_port(LV2_Handle instance, uint32_t port, void* data_location) {
233 static_cast<PluginLv2*>(instance)->ConnectPort(port, data_location);
234 }
235
236 void activate(LV2_Handle instance) {
237 static_cast<PluginLv2*>(instance)->Activate();
238 }
239
240 void run(LV2_Handle instance, uint32_t sample_count) {
241 static_cast<PluginLv2*>(instance)->Run(sample_count);
242 }
243
244 void deactivate(LV2_Handle instance) {
245 static_cast<PluginLv2*>(instance)->Deactivate();
246 }
247
248 void cleanup(LV2_Handle instance) {
249 delete static_cast<PluginLv2*>(instance);
250 }
251
252 void save(LV2_Handle handle, LV2_State_Store_Function store,
253 LV2_State_Handle state,
254 uint32_t flags, const LV2_Feature* const* features) {
255 return static_cast<PluginLv2*>(handle)->Save(
256 store, state, flags, features);
257 }
258
259 void restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve,
260 LV2_State_Handle state,
261 uint32_t flags, const LV2_Feature* const* features) {
262 return static_cast<PluginLv2*>(handle)->Restore(
263 retrieve, state, flags, features);
264 }
265
266 PluginInfo PluginInfo::Instance;
267
268 PluginInfo::PluginInfo() {
269 Lv2.URI = "http://linuxsampler.org/plugins/linuxsampler";
270 Lv2.activate = activate;
271 Lv2.cleanup = cleanup;
272 Lv2.connect_port = connect_port;
273 Lv2.deactivate = deactivate;
274 Lv2.instantiate = instantiate;
275 Lv2.run = run;
276 Lv2.extension_data = extension_data;
277 StateInterface.save = save;
278 StateInterface.restore = restore;
279 }
280
281
282 const void* extension_data(const char* uri) {
283 dmsg(2, ("linuxsampler: extension_data %s\n", uri));
284 if (strcmp(uri, LV2_STATE_URI "#Interface") == 0) {
285 return PluginInfo::Lv2StateInterface();
286 }
287 return 0;
288 }
289 }
290
291
292 extern "C" {
293 LV2_SYMBOL_EXPORT
294 const LV2_Descriptor* lv2_descriptor(uint32_t index) {
295 return index == 0 ? PluginInfo::Lv2Descriptor() : 0;
296 }
297 }

  ViewVC Help
Powered by ViewVC