/[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 2174 - (hide annotations) (download)
Tue Apr 12 15:19:56 2011 UTC (13 years ago) by capela
File size: 9422 byte(s)
* plugin changes:
    - LV2 Persist + Files support (patch by David Robillard)

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 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     PathSupport = 0;
43     NewFileSupport = 0;
44 persson 1777 for (int i = 0 ; Features[i] ; i++) {
45     dmsg(2, ("linuxsampler: host 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     } else if (!strcmp(Features[i]->URI, LV2_FILES_PATH_SUPPORT_URI)) {
49     PathSupport = (LV2_Files_Path_Support*)Features[i]->data;
50     } else if (!strcmp(Features[i]->URI, LV2_FILES_NEW_FILE_SUPPORT_URI)) {
51     NewFileSupport = (LV2_Files_New_File_Support*)Features[i]->data;
52     }
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     if (PathSupport) {
107     char* cstr = PathSupport->abstract_path(PathSupport->host_data,
108     path.c_str());
109     const String abstract_path(cstr);
110     free(cstr);
111     return abstract_path;
112     }
113     return path;
114     }
115 persson 1777
116 capela 2174 String PluginLv2::PathFromState(const String& path) {
117     if (PathSupport) {
118     char* cstr = PathSupport->absolute_path(PathSupport->host_data,
119     path.c_str());
120     const String abstract_path(cstr);
121     free(cstr);
122     return abstract_path;
123     }
124     return path;
125     }
126 persson 1777
127 capela 2174 void PluginLv2::Save(LV2_Persist_Store_Function store, void* host_data) {
128     if (NewFileSupport) {
129     char* path = NewFileSupport->new_file_path(PathSupport->host_data,
130     "linuxsampler");
131     dmsg(2, ("saving to file %s\n", path));
132 persson 1777
133 capela 2174 std::ofstream out(path);
134     out << GetState();
135 persson 1777
136 capela 2174 const String abstract_path = PathToState(path);
137 persson 1777
138 capela 2174 store(host_data,
139     uri_to_id(NULL, NS_LS "state-file"),
140     abstract_path.c_str(),
141     abstract_path.length() + 1,
142     uri_to_id(NULL, LV2_FILES_URI "#AbstractPath"),
143     LV2_PERSIST_IS_PORTABLE);
144     } else {
145     dmsg(2, ("saving to string\n"));
146 persson 1777
147 capela 2174 std::ostringstream out;
148     out << GetState();
149    
150     store(host_data,
151     uri_to_id(NULL, NS_LS "state-string"),
152     out.str().c_str(),
153     out.str().length() + 1,
154     uri_to_id(NULL, NS_ATOM "String"),
155     LV2_PERSIST_IS_POD | LV2_PERSIST_IS_PORTABLE);
156     }
157 persson 1777 dmsg(2, ("saving done\n"));
158     }
159    
160 capela 2174 void PluginLv2::Restore(LV2_Persist_Retrieve_Function retrieve, void* data) {
161     size_t size;
162     uint32_t type;
163     uint32_t flags;
164    
165     const void* value = retrieve(
166     data,
167     uri_to_id(NULL, NS_LS "state-file"),
168     &size, &type, &flags);
169    
170     if (value) {
171     assert(type == uri_to_id(NULL, LV2_FILES_URI "#AbstractPath"));
172     const String path = PathFromState((const char*)value);
173     dmsg(2, ("linuxsampler: restoring from file %s\n", path.c_str()));
174     std::ifstream in(path.c_str());
175     String state;
176     std::getline(in, state, '\0');
177     SetState(state);
178     return;
179 persson 1777 }
180 capela 2174
181     value = retrieve(
182     data,
183     uri_to_id(NULL, NS_LS "state-string"),
184     &size, &type, &flags);
185     if (value) {
186     dmsg(2, ("linuxsampler: restoring from string\n"));
187     assert(type == uri_to_id(NULL, NS_ATOM "String"));
188     String state((const char*)value);
189     SetState(state);
190     return;
191     }
192    
193     // No valid state found, reset to default state
194     dmsg(2, ("linuxsampler: restoring default state\n"));
195     SetState(DefaultState);
196 persson 1777 }
197    
198     LV2_Handle instantiate(const LV2_Descriptor* descriptor,
199     double sample_rate, const char* bundle_path,
200     const LV2_Feature* const* features) {
201     return new PluginLv2(descriptor, sample_rate, bundle_path, features);
202     }
203    
204     void connect_port(LV2_Handle instance, uint32_t port, void* data_location) {
205     static_cast<PluginLv2*>(instance)->ConnectPort(port, data_location);
206     }
207    
208     void activate(LV2_Handle instance) {
209     static_cast<PluginLv2*>(instance)->Activate();
210     }
211    
212     void run(LV2_Handle instance, uint32_t sample_count) {
213     static_cast<PluginLv2*>(instance)->Run(sample_count);
214     }
215    
216     void deactivate(LV2_Handle instance) {
217     static_cast<PluginLv2*>(instance)->Deactivate();
218     }
219    
220     void cleanup(LV2_Handle instance) {
221     delete static_cast<PluginLv2*>(instance);
222     }
223    
224 capela 2174 void save(LV2_Handle handle, LV2_Persist_Store_Function store, void* callback_data) {
225     return static_cast<PluginLv2*>(handle)->Save(store, callback_data);
226 persson 1777 }
227    
228 capela 2174 void restore(LV2_Handle handle, LV2_Persist_Retrieve_Function store, void* callback_data) {
229     return static_cast<PluginLv2*>(handle)->Restore(store, callback_data);
230 persson 1777 }
231    
232     PluginInfo PluginInfo::Instance;
233    
234     PluginInfo::PluginInfo() {
235     Lv2.URI = "http://linuxsampler.org/plugins/linuxsampler";
236     Lv2.activate = activate;
237     Lv2.cleanup = cleanup;
238     Lv2.connect_port = connect_port;
239     Lv2.deactivate = deactivate;
240     Lv2.instantiate = instantiate;
241     Lv2.run = run;
242     Lv2.extension_data = extension_data;
243 capela 2174 Persist.save = save;
244     Persist.restore = restore;
245 persson 1777 }
246    
247    
248     const void* extension_data(const char* uri) {
249     dmsg(2, ("linuxsampler: extension_data %s\n", uri));
250 capela 2174 if (strcmp(uri, LV2_PERSIST_URI) == 0) {
251     return PluginInfo::Lv2PersistDescriptor();
252 persson 1777 }
253     return 0;
254     }
255     }
256    
257    
258     extern "C" {
259     LV2_SYMBOL_EXPORT
260     const LV2_Descriptor* lv2_descriptor(uint32_t index) {
261     return index == 0 ? PluginInfo::Lv2Descriptor() : 0;
262     }
263     }

  ViewVC Help
Powered by ViewVC