19 |
***************************************************************************/ |
***************************************************************************/ |
20 |
|
|
21 |
#include <algorithm> |
#include <algorithm> |
22 |
|
#include <cassert> |
23 |
#include <cstdio> |
#include <cstdio> |
24 |
#include <cstdlib> |
#include <cstdlib> |
25 |
#include <cstring> |
#include <cstring> |
28 |
|
|
29 |
#include "PluginLv2.h" |
#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 { |
namespace { |
35 |
|
|
36 |
PluginLv2::PluginLv2(const LV2_Descriptor* Descriptor, |
PluginLv2::PluginLv2(const LV2_Descriptor* Descriptor, |
38 |
const LV2_Feature* const* Features) { |
const LV2_Feature* const* Features) { |
39 |
Out[0] = 0; |
Out[0] = 0; |
40 |
Out[1] = 0; |
Out[1] = 0; |
41 |
|
UriMap = 0; |
42 |
|
PathSupport = 0; |
43 |
|
NewFileSupport = 0; |
44 |
for (int i = 0 ; Features[i] ; i++) { |
for (int i = 0 ; Features[i] ; i++) { |
45 |
dmsg(2, ("linuxsampler: host feature: %s\n", Features[i]->URI)); |
dmsg(2, ("linuxsampler: host 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_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 |
} |
} |
54 |
|
|
55 |
Init(SampleRate, 128); |
Init(SampleRate, 128); |
56 |
|
|
57 |
InitState(); |
InitState(); |
58 |
|
|
59 |
|
DefaultState = GetState(); |
60 |
} |
} |
61 |
|
|
62 |
void PluginLv2::ConnectPort(uint32_t Port, void* DataLocation) { |
void PluginLv2::ConnectPort(uint32_t Port, void* DataLocation) { |
102 |
dmsg(2, ("linuxsampler: Deactivate\n")); |
dmsg(2, ("linuxsampler: Deactivate\n")); |
103 |
} |
} |
104 |
|
|
105 |
char* PluginLv2::Save(const char* Directory, LV2SR_File*** Files) { |
String PluginLv2::PathToState(const String& path) { |
106 |
dmsg(2, ("linuxsampler: Save Directory=%s\n", Directory)); |
if (PathSupport) { |
107 |
|
char* cstr = PathSupport->abstract_path(PathSupport->host_data, |
108 |
String filename(Directory); |
path.c_str()); |
109 |
filename += "/linuxsampler"; |
const String abstract_path(cstr); |
110 |
dmsg(2, ("saving to %s\n", filename.c_str())); |
free(cstr); |
111 |
std::ofstream out(filename.c_str()); |
return abstract_path; |
112 |
out << GetState(); |
} |
113 |
out.close(); |
return path; |
114 |
|
} |
|
LV2SR_File** filearr = static_cast<LV2SR_File**>(malloc(sizeof(LV2SR_File*) * 2)); |
|
|
|
|
|
LV2SR_File* file = static_cast<LV2SR_File*>(malloc(sizeof(LV2SR_File))); |
|
|
file->name = strdup("linuxsampler"); |
|
|
file->path = strdup(filename.c_str()); |
|
|
file->must_copy = 0; |
|
|
|
|
|
filearr[0] = file; |
|
|
filearr[1] = 0; |
|
115 |
|
|
116 |
*Files = filearr; |
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 |
|
|
127 |
|
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 |
|
|
133 |
|
std::ofstream out(path); |
134 |
|
out << GetState(); |
135 |
|
|
136 |
|
const String abstract_path = PathToState(path); |
137 |
|
|
138 |
|
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 |
|
|
147 |
|
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 |
dmsg(2, ("saving done\n")); |
dmsg(2, ("saving done\n")); |
|
return 0; |
|
158 |
} |
} |
159 |
|
|
160 |
char* PluginLv2::Restore(const LV2SR_File** Files) { |
void PluginLv2::Restore(LV2_Persist_Retrieve_Function retrieve, void* data) { |
161 |
dmsg(2, ("linuxsampler: restore\n")); |
size_t size; |
162 |
for (int i = 0 ; Files[i] ; i++) { |
uint32_t type; |
163 |
dmsg(2, (" name=%s path=%s\n", Files[i]->name, Files[i]->path)); |
uint32_t flags; |
164 |
if (strcmp(Files[i]->name, "linuxsampler") == 0) { |
|
165 |
std::ifstream in(Files[0]->path); |
const void* value = retrieve( |
166 |
String state; |
data, |
167 |
std::getline(in, state, '\0'); |
uri_to_id(NULL, NS_LS "state-file"), |
168 |
SetState(state); |
&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 |
} |
} |
180 |
return 0; |
|
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 |
} |
} |
197 |
|
|
198 |
LV2_Handle instantiate(const LV2_Descriptor* descriptor, |
LV2_Handle instantiate(const LV2_Descriptor* descriptor, |
221 |
delete static_cast<PluginLv2*>(instance); |
delete static_cast<PluginLv2*>(instance); |
222 |
} |
} |
223 |
|
|
224 |
char* save(LV2_Handle handle, const char* directory, LV2SR_File*** files) { |
void save(LV2_Handle handle, LV2_Persist_Store_Function store, void* callback_data) { |
225 |
return static_cast<PluginLv2*>(handle)->Save(directory, files); |
return static_cast<PluginLv2*>(handle)->Save(store, callback_data); |
226 |
} |
} |
227 |
|
|
228 |
char* restore(LV2_Handle handle, const LV2SR_File** files) { |
void restore(LV2_Handle handle, LV2_Persist_Retrieve_Function store, void* callback_data) { |
229 |
return static_cast<PluginLv2*>(handle)->Restore(files); |
return static_cast<PluginLv2*>(handle)->Restore(store, callback_data); |
230 |
} |
} |
231 |
|
|
232 |
PluginInfo PluginInfo::Instance; |
PluginInfo PluginInfo::Instance; |
240 |
Lv2.instantiate = instantiate; |
Lv2.instantiate = instantiate; |
241 |
Lv2.run = run; |
Lv2.run = run; |
242 |
Lv2.extension_data = extension_data; |
Lv2.extension_data = extension_data; |
243 |
Lv2sr.save = save; |
Persist.save = save; |
244 |
Lv2sr.restore = restore; |
Persist.restore = restore; |
245 |
} |
} |
246 |
|
|
247 |
|
|
248 |
const void* extension_data(const char* uri) { |
const void* extension_data(const char* uri) { |
249 |
dmsg(2, ("linuxsampler: extension_data %s\n", uri)); |
dmsg(2, ("linuxsampler: extension_data %s\n", uri)); |
250 |
if (strcmp(uri, LV2_SAVERESTORE_URI) == 0) { |
if (strcmp(uri, LV2_PERSIST_URI) == 0) { |
251 |
return PluginInfo::Lv2srDescriptor(); |
return PluginInfo::Lv2PersistDescriptor(); |
252 |
} |
} |
253 |
return 0; |
return 0; |
254 |
} |
} |