On 05/04/11 10:36 AM, David Robillard wrote:
On 03/04/11 03:29 AM, Christian Schoenebeck wrote:
[...]
We just checked it. The extensions and your LinuxSampler patch look fine to us.
Good job! But we like to wait for applying your patch until QTractor also
supports those new LV2 extensions. Is that OK for you David?

Great.

Sure, that makes sense. AFAIK there are no other implementations yet, so
once qtractor is done everyone is on the same page.

Updated version of the patch attached that should work with the latest qtractor svn (and ardour).

The main changes from the previous patch are a few URIs, and resetting the default state should actually work now.

I have used http://linuxsampler.org/schema for the LinuxSampler namespace, this is where you would host a document documenting whatever keys you use (or whatever other dataey things), like the extensions at lv2plug.in (though you don't actually have to do so); you may want to change that. Otherwise, the implementation is complete, except I need to decide what flags should be passed for AbstractPath values, but that's a trivial fix if it needs to change.

I will probably implement file mapping in Ardour soon to make symlinks in the session directory for all files referenced by LinuxSampler state to get exportable sessions, which would be a nice leap in progress for LAD in general, but the current implementation should work fine.

Cheers,

-dr

? Doxyfile
? Makefile
? Makefile.in
? aclocal.m4
? autom4te.cache
? config.guess
? config.h
? config.h.in
? config.log
? config.status
? config.sub
? configure
? depcomp
? install-sh
? libtool
? linuxsampler.pc
? linuxsampler.spec
? linuxsampler_lv2_persist_files.diff
? ltmain.sh
? missing
? stamp-h1
? Artwork/Makefile
? Artwork/Makefile.in
? Documentation/Makefile
? Documentation/Makefile.in
? Documentation/Engines/Makefile
? Documentation/Engines/Makefile.in
? Documentation/Engines/gig/Makefile
? Documentation/Engines/gig/Makefile.in
? debian/Makefile
? debian/Makefile.in
? man/Makefile
? man/Makefile.in
? man/linuxsampler.1
? osx/Makefile
? osx/Makefile.in
? osx/linuxsampler.xcodeproj/Makefile
? osx/linuxsampler.xcodeproj/Makefile.in
? scripts/Makefile
? scripts/Makefile.in
? src/.deps
? src/.libs
? src/Makefile
? src/Makefile.in
? src/Sampler.lo
? src/liblinuxsampler.la
? src/linuxsampler
? src/common/.deps
? src/common/.libs
? src/common/Condition.lo
? src/common/ConditionServer.lo
? src/common/DynamicLibraries.lo
? src/common/Features.lo
? src/common/File.lo
? src/common/IDGenerator.lo
? src/common/Makefile
? src/common/Makefile.in
? src/common/Mutex.lo
? src/common/Path.lo
? src/common/RTMath.lo
? src/common/Thread.lo
? src/common/WorkerThread.lo
? src/common/global_private.lo
? src/common/liblinuxsamplercommon.la
? src/common/optional.lo
? src/common/stacktrace.lo
? src/db/.deps
? src/db/.libs
? src/db/Makefile
? src/db/Makefile.in
? src/db/liblinuxsamplerdb.la
? src/db/liblinuxsamplerdb_la-InstrumentsDb.lo
? src/db/liblinuxsamplerdb_la-InstrumentsDbUtilities.lo
? src/drivers/.deps
? src/drivers/.libs
? src/drivers/Device.lo
? src/drivers/DeviceParameter.lo
? src/drivers/DeviceParameterFactory.lo
? src/drivers/Makefile
? src/drivers/Makefile.in
? src/drivers/Plugin.lo
? src/drivers/liblinuxsamplerdrivers.la
? src/drivers/audio/.deps
? src/drivers/audio/.libs
? src/drivers/audio/AudioChannel.lo
? src/drivers/audio/AudioOutputDevice.lo
? src/drivers/audio/AudioOutputDeviceAlsa.lo
? src/drivers/audio/AudioOutputDeviceFactory.lo
? src/drivers/audio/AudioOutputDeviceJack.lo
? src/drivers/audio/AudioOutputDevicePlugin.lo
? src/drivers/audio/Makefile
? src/drivers/audio/Makefile.in
? src/drivers/audio/liblinuxsampleraudiodriver.la
? src/drivers/midi/.deps
? src/drivers/midi/.libs
? src/drivers/midi/Makefile
? src/drivers/midi/Makefile.in
? src/drivers/midi/MidiInputDevice.lo
? src/drivers/midi/MidiInputDeviceAlsa.lo
? src/drivers/midi/MidiInputDeviceFactory.lo
? src/drivers/midi/MidiInputDeviceJack.lo
? src/drivers/midi/MidiInputDevicePlugin.lo
? src/drivers/midi/MidiInputPort.lo
? src/drivers/midi/MidiInstrumentMapper.lo
? src/drivers/midi/VirtualMidiDevice.lo
? src/drivers/midi/liblinuxsamplermididriver.la
? src/effects/.deps
? src/effects/.libs
? src/effects/Effect.lo
? src/effects/EffectChain.lo
? src/effects/EffectControl.lo
? src/effects/EffectFactory.lo
? src/effects/LadspaEffect.lo
? src/effects/Makefile
? src/effects/Makefile.in
? src/effects/liblinuxsamplereffects.la
? src/engines/.deps
? src/engines/.libs
? src/engines/AbstractEngine.lo
? src/engines/AbstractEngineChannel.lo
? src/engines/Engine.lo
? src/engines/EngineChannel.lo
? src/engines/EngineChannelFactory.lo
? src/engines/EngineFactory.lo
? src/engines/FxSend.lo
? src/engines/InstrumentManager.lo
? src/engines/InstrumentManagerThread.lo
? src/engines/Makefile
? src/engines/Makefile.in
? src/engines/liblinuxsamplerengines.la
? src/engines/common/.deps
? src/engines/common/.libs
? src/engines/common/AbstractVoice.lo
? src/engines/common/DiskThreadBase.lo
? src/engines/common/EG.lo
? src/engines/common/Event.lo
? src/engines/common/Makefile
? src/engines/common/Makefile.in
? src/engines/common/SampleFile.lo
? src/engines/common/StreamBase.lo
? src/engines/common/liblinuxsamplercommonengine.la
? src/engines/gig/.deps
? src/engines/gig/.libs
? src/engines/gig/DiskThread.lo
? src/engines/gig/EGADSR.lo
? src/engines/gig/EGDecay.lo
? src/engines/gig/Engine.lo
? src/engines/gig/EngineChannel.lo
? src/engines/gig/InstrumentResourceManager.lo
? src/engines/gig/Makefile
? src/engines/gig/Makefile.in
? src/engines/gig/Profiler.lo
? src/engines/gig/SmoothVolume.lo
? src/engines/gig/Stream.lo
? src/engines/gig/Synthesizer.lo
? src/engines/gig/Voice.lo
? src/engines/gig/liblinuxsamplergigengine.la
? src/engines/sf2/.deps
? src/engines/sf2/.libs
? src/engines/sf2/DiskThread.lo
? src/engines/sf2/Engine.lo
? src/engines/sf2/EngineChannel.lo
? src/engines/sf2/InstrumentResourceManager.lo
? src/engines/sf2/Makefile
? src/engines/sf2/Makefile.in
? src/engines/sf2/Stream.lo
? src/engines/sf2/Voice.lo
? src/engines/sf2/liblinuxsamplersf2engine.la
? src/engines/sfz/.deps
? src/engines/sfz/.libs
? src/engines/sfz/DiskThread.lo
? src/engines/sfz/EG.lo
? src/engines/sfz/EGADSR.lo
? src/engines/sfz/Engine.lo
? src/engines/sfz/EngineChannel.lo
? src/engines/sfz/InstrumentResourceManager.lo
? src/engines/sfz/LookupTable.lo
? src/engines/sfz/Makefile
? src/engines/sfz/Makefile.in
? src/engines/sfz/Stream.lo
? src/engines/sfz/Voice.lo
? src/engines/sfz/liblinuxsamplersfzengine.la
? src/engines/sfz/sfz.lo
? src/hostplugins/Makefile
? src/hostplugins/Makefile.in
? src/hostplugins/au/.deps
? src/hostplugins/au/Makefile
? src/hostplugins/au/Makefile.in
? src/hostplugins/dssi/.deps
? src/hostplugins/dssi/Makefile
? src/hostplugins/dssi/Makefile.in
? src/hostplugins/lv2/.deps
? src/hostplugins/lv2/.libs
? src/hostplugins/lv2/Makefile
? src/hostplugins/lv2/Makefile.in
? src/hostplugins/lv2/PluginLv2.lo
? src/hostplugins/lv2/linuxsampler.la
? src/hostplugins/lv2/lv2_files.h
? src/hostplugins/lv2/lv2_persist.h
? src/hostplugins/lv2/lv2_uri_map.h
? src/hostplugins/vst/.deps
? src/hostplugins/vst/Makefile
? src/hostplugins/vst/Makefile.in
? src/network/.deps
? src/network/.libs
? src/network/Makefile
? src/network/Makefile.in
? src/network/liblinuxsamplernetwork.la
? src/network/lscpevent.lo
? src/network/lscpparser.cpp
? src/network/lscpparser.lo
? src/network/lscpresultset.lo
? src/network/lscpserver.lo
? src/network/lscpsymbols.h
? src/plugins/.deps
? src/plugins/.libs
? src/plugins/InstrumentEditor.lo
? src/plugins/InstrumentEditorFactory.lo
? src/plugins/Makefile
? src/plugins/Makefile.in
? src/plugins/liblinuxsamplerplugins.la
? src/testcases/.deps
? src/testcases/Makefile
? src/testcases/Makefile.in
Index: AUTHORS
===================================================================
RCS file: /var/cvs/linuxsampler/linuxsampler/AUTHORS,v
retrieving revision 1.8
diff -u -r1.8 AUTHORS
--- AUTHORS	31 Jul 2009 07:45:47 -0000	1.8
+++ AUTHORS	8 Apr 2011 23:45:53 -0000
@@ -46,3 +46,4 @@
     Andrew Williams
     Devin Anderson
     Chris Cherrett
+    David Robillard
Index: src/drivers/Plugin.cpp
===================================================================
RCS file: /var/cvs/linuxsampler/linuxsampler/src/drivers/Plugin.cpp,v
retrieving revision 1.11
diff -u -r1.11 Plugin.cpp
--- src/drivers/Plugin.cpp	20 Feb 2011 14:20:21 -0000	1.11
+++ src/drivers/Plugin.cpp	8 Apr 2011 23:45:53 -0000
@@ -173,6 +173,20 @@
     }
 
     /*
+      These methods can be overloaded by different plugin types to map
+      file names to/from file names to be used in the state text, making
+      it possible for state to be self-contained and/or movable.
+    */
+
+    String Plugin::PathToState(const String& string) {
+        return string;
+    }
+
+    String Plugin::PathFromState(const String& string) {
+        return string;
+    }
+
+    /*
       The sampler state is stored in a text base format, designed to
       be easy to parse with the istream >> operator. Values are
       separated by spaces or newlines. All string values that may
@@ -218,7 +232,7 @@
                      int(iter->first.midi_bank_lsb)) << ' ' <<
                     int(iter->first.midi_prog) << ' ' <<
                     iter->second.EngineName << ' ' <<
-                    iter->second.InstrumentFile << '\n' <<
+                    PathToState(iter->second.InstrumentFile) << '\n' <<
                     MIDIMAPPING << ' ' <<
                     iter->second.InstrumentIndex << ' ' <<
                     iter->second.Volume << ' ' <<
@@ -240,7 +254,7 @@
                 String filename = engine_channel->InstrumentFileName();
                 s << channel->GetMidiInputChannel() << ' ' <<
                     engine_channel->Volume() << ' ' <<
-                    filename << '\n' <<
+                    PathToState(filename) << '\n' <<
                     engine_channel->InstrumentIndex() << ' ' <<
                     engine_channel->GetSolo() << ' ' <<
                     (engine_channel->GetMute() == 1) << ' ' <<
@@ -336,7 +350,7 @@
                 }
                 if (!filename.empty() && index != -1) {
                     InstrumentManager::instrument_id_t id;
-                    id.FileName = filename;
+                    id.FileName = PathFromState(filename);
                     id.Index    = index;
                     InstrumentManager::LoadInstrumentInBackground(id, engine_channel);
                 }
Index: src/drivers/Plugin.h
===================================================================
RCS file: /var/cvs/linuxsampler/linuxsampler/src/drivers/Plugin.h,v
retrieving revision 1.4
diff -u -r1.4 Plugin.h
--- src/drivers/Plugin.h	28 Aug 2009 07:48:46 -0000	1.4
+++ src/drivers/Plugin.h	8 Apr 2011 23:45:54 -0000
@@ -69,6 +69,9 @@
         void PreInit();
         void Init(int SampleRate, int FragmentSize, int Channels = -1);
 
+        virtual String PathToState(const String& string);
+        virtual String PathFromState(const String& string);
+        
         void InitState();
         String GetState();
         bool SetState(String State);
Index: src/hostplugins/lv2/PluginLv2.cpp
===================================================================
RCS file: /var/cvs/linuxsampler/linuxsampler/src/hostplugins/lv2/PluginLv2.cpp,v
retrieving revision 1.1
diff -u -r1.1 PluginLv2.cpp
--- src/hostplugins/lv2/PluginLv2.cpp	15 Sep 2008 16:58:10 -0000	1.1
+++ src/hostplugins/lv2/PluginLv2.cpp	8 Apr 2011 23:45:54 -0000
@@ -19,6 +19,7 @@
  ***************************************************************************/
 
 #include <algorithm>
+#include <cassert>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -27,6 +28,9 @@
 
 #include "PluginLv2.h"
 
+#define NS_ATOM "http://lv2plug.in/ns/ext/atom#";
+#define NS_LS   "http://linuxsampler.org/schema#";
+
 namespace {
 
     PluginLv2::PluginLv2(const LV2_Descriptor* Descriptor,
@@ -34,13 +38,25 @@
                          const LV2_Feature* const* Features) {
         Out[0] = 0;
         Out[1] = 0;
+        UriMap = 0;
+        PathSupport = 0;
+        NewFileSupport = 0;
         for (int i = 0 ; Features[i] ; i++) {
             dmsg(2, ("linuxsampler: host feature: %s\n", Features[i]->URI));
+            if (!strcmp(Features[i]->URI, LV2_URI_MAP_URI)) {
+                UriMap = (LV2_URI_Map_Feature*)Features[i]->data;
+            } else if (!strcmp(Features[i]->URI, LV2_FILES_PATH_SUPPORT_URI)) {
+                PathSupport = (LV2_Files_Path_Support*)Features[i]->data;
+            } else if (!strcmp(Features[i]->URI, LV2_FILES_NEW_FILE_SUPPORT_URI)) {
+                NewFileSupport = (LV2_Files_New_File_Support*)Features[i]->data;
+            }
         }
 
         Init(SampleRate, 128);
 
         InitState();
+
+        DefaultState = GetState();
     }
 
     void PluginLv2::ConnectPort(uint32_t Port, void* DataLocation) {
@@ -86,44 +102,97 @@
         dmsg(2, ("linuxsampler: Deactivate\n"));
     }
 
-    char* PluginLv2::Save(const char* Directory, LV2SR_File*** Files) {
-        dmsg(2, ("linuxsampler: Save Directory=%s\n", Directory));
-
-        String filename(Directory);
-        filename += "/linuxsampler";
-        dmsg(2, ("saving to %s\n", filename.c_str()));
-        std::ofstream out(filename.c_str());
-        out << GetState();
-        out.close();
-
-        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;
+    String PluginLv2::PathToState(const String& path) {
+        if (PathSupport) {
+            char* cstr = PathSupport->abstract_path(PathSupport->host_data,
+                                                    path.c_str());
+            const String abstract_path(cstr);
+            free(cstr);
+            return abstract_path;
+        }
+        return path;
+    }
 
-        *Files = filearr;
+    String PluginLv2::PathFromState(const String& path) {
+        if (PathSupport) {
+            char* cstr = PathSupport->absolute_path(PathSupport->host_data,
+                                                    path.c_str());
+            const String abstract_path(cstr);
+            free(cstr);
+            return abstract_path;
+        }
+        return path;
+    }
 
+    void PluginLv2::Save(LV2_Persist_Store_Function store, void* host_data) {
+        if (NewFileSupport) {
+            char* path = NewFileSupport->new_file_path(PathSupport->host_data,
+                                                       "linuxsampler");
+            dmsg(2, ("saving to file %s\n", path));
+
+            std::ofstream out(path);
+            out << GetState();
+
+            const String abstract_path = PathToState(path);
+
+            store(host_data,
+                  uri_to_id(NULL, NS_LS "state-file"),
+                  abstract_path.c_str(),
+                  abstract_path.length() + 1,
+                  uri_to_id(NULL, LV2_FILES_URI "#AbstractPath"),
+                  LV2_PERSIST_IS_PORTABLE);
+        } else {
+            dmsg(2, ("saving to string\n"));
+
+            std::ostringstream out;
+            out << GetState();
+
+            store(host_data,
+                  uri_to_id(NULL, NS_LS "state-string"),
+                  out.str().c_str(),
+                  out.str().length() + 1,
+                  uri_to_id(NULL, NS_ATOM "String"),
+                  LV2_PERSIST_IS_POD | LV2_PERSIST_IS_PORTABLE);
+        }
         dmsg(2, ("saving done\n"));
-        return 0;
     }
 
-    char* PluginLv2::Restore(const LV2SR_File** Files) {
-        dmsg(2, ("linuxsampler: restore\n"));
-        for (int i = 0 ; Files[i] ; i++) {
-            dmsg(2, ("  name=%s path=%s\n", Files[i]->name, Files[i]->path));
-            if (strcmp(Files[i]->name, "linuxsampler") == 0) {
-                std::ifstream in(Files[0]->path);
-                String state;
-                std::getline(in, state, '\0');
-                SetState(state);
-            }
+    void PluginLv2::Restore(LV2_Persist_Retrieve_Function retrieve, void* data) {
+        size_t   size;
+        uint32_t type;
+        uint32_t flags;
+
+        const void* value = retrieve(
+            data,
+            uri_to_id(NULL, NS_LS "state-file"),
+            &size, &type, &flags);
+
+        if (value) {
+            assert(type == uri_to_id(NULL, LV2_FILES_URI "#AbstractPath"));
+            const String path = PathFromState((const char*)value);
+            dmsg(2, ("linuxsampler: restoring from file %s\n", path.c_str()));
+            std::ifstream in(path.c_str());
+            String state;
+            std::getline(in, state, '\0');
+            SetState(state);
+            return;
         }
-        return 0;
+
+        value = retrieve(
+                data,
+                uri_to_id(NULL, NS_LS "state-string"),
+                &size, &type, &flags);
+        if (value) {
+            dmsg(2, ("linuxsampler: restoring from string\n"));
+            assert(type == uri_to_id(NULL, NS_ATOM "String"));
+            String state((const char*)value);
+            SetState(state);
+            return;
+        }
+
+        // No valid state found, reset to default state
+        dmsg(2, ("linuxsampler: restoring default state\n"));
+        SetState(DefaultState);
     }
 
     LV2_Handle instantiate(const LV2_Descriptor* descriptor,
@@ -152,12 +221,12 @@
         delete static_cast<PluginLv2*>(instance);
     }
 
-    char* save(LV2_Handle handle, const char* directory, LV2SR_File*** files) {
-        return static_cast<PluginLv2*>(handle)->Save(directory, files);
+    void save(LV2_Handle handle, LV2_Persist_Store_Function store, void* callback_data) {
+	    return static_cast<PluginLv2*>(handle)->Save(store, callback_data);
     }
 
-    char* restore(LV2_Handle handle, const LV2SR_File** files) {
-        return static_cast<PluginLv2*>(handle)->Restore(files);
+    void restore(LV2_Handle handle, LV2_Persist_Retrieve_Function store, void* callback_data) {
+        return static_cast<PluginLv2*>(handle)->Restore(store, callback_data);
     }
 
     PluginInfo PluginInfo::Instance;
@@ -171,15 +240,15 @@
         Lv2.instantiate = instantiate;
         Lv2.run = run;
         Lv2.extension_data = extension_data;
-        Lv2sr.save = save;
-        Lv2sr.restore = restore;
+        Persist.save = save;
+        Persist.restore = restore;
     }
 
 
     const void* extension_data(const char* uri) {
         dmsg(2, ("linuxsampler: extension_data %s\n", uri));
-        if (strcmp(uri, LV2_SAVERESTORE_URI) == 0) {
-            return PluginInfo::Lv2srDescriptor();
+        if (strcmp(uri, LV2_PERSIST_URI) == 0) {
+            return PluginInfo::Lv2PersistDescriptor();
         }
         return 0;
     }
Index: src/hostplugins/lv2/PluginLv2.h
===================================================================
RCS file: /var/cvs/linuxsampler/linuxsampler/src/hostplugins/lv2/PluginLv2.h,v
retrieving revision 1.1
diff -u -r1.1 PluginLv2.h
--- src/hostplugins/lv2/PluginLv2.h	15 Sep 2008 16:58:10 -0000	1.1
+++ src/hostplugins/lv2/PluginLv2.h	8 Apr 2011 23:45:54 -0000
@@ -23,7 +23,9 @@
 
 #include <lv2.h>
 #include "lv2_event.h"
-#include "lv2-saverestore.h"
+#include "lv2_persist.h"
+#include "lv2_uri_map.h"
+#include "lv2_files.h"
 #include "../../drivers/Plugin.h"
 
 namespace {
@@ -37,12 +39,25 @@
         void Activate();
         void Run(uint32_t SampleCount);
         void Deactivate();
-        char* Save(const char* Directory, LV2SR_File*** Files);
-        char* Restore(const LV2SR_File** Files);
+        void Save(LV2_Persist_Store_Function store, void* data);
+        void Restore(LV2_Persist_Retrieve_Function retrieve, void* data);
+
+	protected:
+        virtual String PathToState(const String& string);
+        virtual String PathFromState(const String& string);
 
     private:
+        uint32_t uri_to_id(const char* map, const char* uri) {
+	        return UriMap->uri_to_id(UriMap->callback_data, map, uri);
+        }
+
         float* Out[2];
         LV2_Event_Buffer* MidiBuf;
+        LV2_URI_Map_Feature* UriMap;
+        LV2_Files_Path_Support* PathSupport;
+        LV2_Files_New_File_Support* NewFileSupport;
+
+        String DefaultState;
     };
 
     class PluginInfo {
@@ -50,12 +65,12 @@
         static const LV2_Descriptor* Lv2Descriptor() {
             return &Instance.Lv2;
         }
-        static const LV2SR_Descriptor* Lv2srDescriptor() {
-            return &Instance.Lv2sr;
+        static const LV2_Persist* Lv2PersistDescriptor() {
+            return &Instance.Persist;
         }
     private:
         LV2_Descriptor Lv2;
-        LV2SR_Descriptor Lv2sr;
+        LV2_Persist Persist;
 
         PluginInfo();
         static PluginInfo Instance;
@@ -73,9 +88,13 @@
         static void cleanup(LV2_Handle instance);
         static const void* extension_data(const char* uri);
 
-        static char* save(LV2_Handle handle, const char* directory,
-                          LV2SR_File*** files);
-        static char* restore(LV2_Handle handle, const LV2SR_File** files);
+        static void save(LV2_Handle                 handle,
+                         LV2_Persist_Store_Function store,
+                         void*                      data);
+
+        static void restore(LV2_Handle                    handle,
+                            LV2_Persist_Retrieve_Function retrieve,
+                            void*                         data);
     }
 }
 
Index: src/hostplugins/lv2/linuxsampler.ttl
===================================================================
RCS file: /var/cvs/linuxsampler/linuxsampler/src/hostplugins/lv2/linuxsampler.ttl,v
retrieving revision 1.1
diff -u -r1.1 linuxsampler.ttl
--- src/hostplugins/lv2/linuxsampler.ttl	15 Sep 2008 16:58:10 -0000	1.1
+++ src/hostplugins/lv2/linuxsampler.ttl	8 Apr 2011 23:45:54 -0000
@@ -8,7 +8,10 @@
     doap:name "LinuxSampler" ;
     doap:license <http://linuxsampler.org/downloads.html#exception> ;
     lv2:optionalFeature lv2:hardRtCapable ;
-    lv2:optionalFeature <http://ll-plugins.nongnu.org/lv2/ext/saverestore> ;
+    lv2:optionalFeature <http://lv2plug.in/ns/ext/persist> ;
+    lv2:optionalFeature <http://lv2plug.in/ns/ext/files#pathSupport> ;
+    lv2:optionalFeature <http://lv2plug.in/ns/ext/files#newFileSupport> ;
+    lv2:optionalFeature <http://lv2plug.in/ns/ext/uri-map> ;
     lv2:port [
 	a lv2:AudioPort , lv2:OutputPort ;
 	lv2:index 0 ;
------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
Linuxsampler-devel mailing list
Linuxsampler-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxsampler-devel

Reply via email to