Stub implementation of LV2 persist extension.
git-svn-id: svn://localhost/ardour2/branches/3.0@8087 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
8b68ed57ec
commit
2a6dcddcc5
@ -136,6 +136,7 @@ class LV2Plugin : public ARDOUR::Plugin
|
||||
float* _defaults;
|
||||
float* _latency_control_port;
|
||||
bool _was_activated;
|
||||
bool _supports_persist;
|
||||
std::vector<bool> _port_is_input;
|
||||
std::map<std::string,uint32_t> _port_indices;
|
||||
|
||||
@ -143,6 +144,7 @@ class LV2Plugin : public ARDOUR::Plugin
|
||||
LV2_DataAccess _data_access_extension_data;
|
||||
LV2_Feature _data_access_feature;
|
||||
LV2_Feature _instance_access_feature;
|
||||
LV2_Feature _persist_feature;
|
||||
|
||||
static URIMap _uri_map;
|
||||
static uint32_t _midi_event_type;
|
||||
|
@ -128,24 +128,24 @@ extern void setup_enum_writer ();
|
||||
class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
|
||||
{
|
||||
public:
|
||||
enum RecordState {
|
||||
enum RecordState {
|
||||
Disabled = 0,
|
||||
Enabled = 1,
|
||||
Recording = 2
|
||||
};
|
||||
|
||||
/* a new session might have non-empty mix_template, an existing session should always have an empty one.
|
||||
the bus profile can be null if no master out bus is required.
|
||||
*/
|
||||
/* a new session might have non-empty mix_template, an existing session should always have an empty one.
|
||||
the bus profile can be null if no master out bus is required.
|
||||
*/
|
||||
|
||||
Session (AudioEngine&,
|
||||
const std::string& fullpath,
|
||||
const std::string& snapshot_name,
|
||||
BusProfile* bus_profile = 0,
|
||||
std::string mix_template = "");
|
||||
const std::string& fullpath,
|
||||
const std::string& snapshot_name,
|
||||
BusProfile* bus_profile = 0,
|
||||
std::string mix_template = "");
|
||||
|
||||
virtual ~Session ();
|
||||
|
||||
|
||||
std::string path() const { return _path; }
|
||||
std::string name() const { return _name; }
|
||||
std::string snap_name() const { return _current_snapshot_name; }
|
||||
@ -175,10 +175,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
std::string dead_sound_dir () const;
|
||||
std::string automation_dir () const;
|
||||
std::string analysis_dir() const;
|
||||
|
||||
std::string plugins_dir() const;
|
||||
|
||||
int ensure_subdirs ();
|
||||
|
||||
std::string peak_path (std::string) const;
|
||||
std::string peak_path (std::string) const;
|
||||
|
||||
std::string change_source_path_by_name (std::string oldpath, std::string oldname, std::string newname, bool destructive);
|
||||
|
||||
@ -233,7 +234,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
|
||||
template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
|
||||
|
||||
bool io_name_is_legal (const std::string&);
|
||||
bool io_name_is_legal (const std::string&);
|
||||
boost::shared_ptr<Route> route_by_name (std::string);
|
||||
boost::shared_ptr<Route> route_by_id (PBD::ID);
|
||||
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
|
||||
@ -282,8 +283,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
/** Emitted when anything about any of our route groups changes */
|
||||
PBD::Signal0<void> RouteGroupChanged;
|
||||
|
||||
/* Step Editing status changed */
|
||||
PBD::Signal1<void,bool> StepEditStatusChange;
|
||||
/* Step Editing status changed */
|
||||
PBD::Signal1<void,bool> StepEditStatusChange;
|
||||
|
||||
void queue_event (SessionEvent*);
|
||||
|
||||
@ -395,7 +396,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void remove_route_group (RouteGroup&);
|
||||
|
||||
RouteGroup* route_group_by_name (std::string);
|
||||
RouteGroup& all_route_group() const;
|
||||
RouteGroup& all_route_group() const;
|
||||
|
||||
PBD::Signal1<void,RouteGroup*> route_group_added;
|
||||
PBD::Signal0<void> route_group_removed;
|
||||
@ -429,7 +430,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
|
||||
/* Time */
|
||||
|
||||
framepos_t transport_frame () const {return _transport_frame; }
|
||||
framepos_t transport_frame () const {return _transport_frame; }
|
||||
framepos_t audible_frame () const;
|
||||
framepos_t requested_return_frame() const { return _requested_return_frame; }
|
||||
|
||||
@ -468,9 +469,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
static PBD::Signal1<void, framepos_t> EndTimeChanged;
|
||||
static PBD::Signal0<void> TimecodeOffsetChanged;
|
||||
|
||||
std::vector<SyncSource> get_available_sync_options() const;
|
||||
std::vector<SyncSource> get_available_sync_options() const;
|
||||
void request_sync_source (Slave*);
|
||||
bool synced_to_jack() const { return config.get_external_sync() && config.get_sync_source() == JACK; }
|
||||
bool synced_to_jack() const { return config.get_external_sync() && config.get_sync_source() == JACK; }
|
||||
|
||||
double transport_speed() const { return _transport_speed; }
|
||||
bool transport_stopped() const { return _transport_speed == 0.0f; }
|
||||
@ -535,10 +536,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
*/
|
||||
static PBD::Signal0<int> AskAboutPendingState;
|
||||
|
||||
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t,
|
||||
bool destructive, bool as_stub = false);
|
||||
|
||||
boost::shared_ptr<MidiSource> create_midi_source_for_session (Track*, std::string const &, bool as_stub = false);
|
||||
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
|
||||
size_t, std::string const &, uint32_t, bool destructive, bool as_stub = false);
|
||||
|
||||
boost::shared_ptr<MidiSource> create_midi_source_for_session (
|
||||
Track*, std::string const &, bool as_stub = false);
|
||||
|
||||
boost::shared_ptr<Source> source_by_id (const PBD::ID&);
|
||||
boost::shared_ptr<Source> source_by_path_and_channel (const std::string&, uint16_t);
|
||||
@ -586,7 +588,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
|
||||
bool soloing() const { return _non_soloed_outs_muted; }
|
||||
bool listening() const { return _listen_cnt > 0; }
|
||||
bool solo_isolated() const { return _solo_isolated_cnt > 0; }
|
||||
bool solo_isolated() const { return _solo_isolated_cnt > 0; }
|
||||
|
||||
static const SessionEvent::RTeventCallback rt_cleanup;
|
||||
|
||||
@ -595,11 +597,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
|
||||
|
||||
PBD::Signal1<void,bool> SoloActive;
|
||||
PBD::Signal0<void> SoloChanged;
|
||||
PBD::Signal0<void> IsolatedChanged;
|
||||
PBD::Signal0<void> IsolatedChanged;
|
||||
|
||||
/* control/master out */
|
||||
|
||||
@ -724,9 +726,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
|
||||
static PBD::Signal0<void> SendFeedback;
|
||||
|
||||
/* Speakers */
|
||||
/* Speakers */
|
||||
|
||||
VBAPSpeakers& get_speakers ();
|
||||
VBAPSpeakers& get_speakers ();
|
||||
|
||||
/* Controllables */
|
||||
|
||||
@ -785,24 +787,24 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
|
||||
PBD::Signal0<void> RouteOrderKeyChanged;
|
||||
|
||||
bool step_editing() const { return (_step_editors > 0); }
|
||||
bool step_editing() const { return (_step_editors > 0); }
|
||||
|
||||
void request_suspend_timecode_transmission ();
|
||||
void request_resume_timecode_transmission ();
|
||||
bool timecode_transmission_suspended () const;
|
||||
|
||||
std::string source_search_path(DataType) const;
|
||||
void ensure_search_path_includes (const std::string& path, DataType type);
|
||||
std::string source_search_path(DataType) const;
|
||||
void ensure_search_path_includes (const std::string& path, DataType type);
|
||||
|
||||
/* handlers can return an integer value:
|
||||
0: config.set_audio_search_path() or config.set_midi_search_path() was used
|
||||
to modify the search path and we should try to find it again.
|
||||
1: quit entire session load
|
||||
2: as 0, but don't ask about other missing files
|
||||
3: don't ask about other missing files, and just mark this one missing
|
||||
-1: just mark this one missing
|
||||
any other value: as -1
|
||||
*/
|
||||
/* handlers can return an integer value:
|
||||
0: config.set_audio_search_path() or config.set_midi_search_path() was used
|
||||
to modify the search path and we should try to find it again.
|
||||
1: quit entire session load
|
||||
2: as 0, but don't ask about other missing files
|
||||
3: don't ask about other missing files, and just mark this one missing
|
||||
-1: just mark this one missing
|
||||
any other value: as -1
|
||||
*/
|
||||
static PBD::Signal3<int,Session*,std::string,DataType> MissingFile;
|
||||
|
||||
/** Emitted when the session wants Ardour to quit */
|
||||
@ -893,8 +895,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void unblock_processing() { g_atomic_int_set (&processing_prohibited, 0); }
|
||||
bool processing_blocked() const { return g_atomic_int_get (&processing_prohibited); }
|
||||
|
||||
Glib::Mutex process_thread_lock;
|
||||
std::list<ProcessThread*> process_threads;
|
||||
Glib::Mutex process_thread_lock;
|
||||
std::list<ProcessThread*> process_threads;
|
||||
|
||||
/* slave tracking */
|
||||
|
||||
@ -914,11 +916,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void track_slave_state(float slave_speed, nframes_t slave_transport_frame, nframes_t this_delta);
|
||||
void follow_slave_silently(nframes_t nframes, float slave_speed);
|
||||
|
||||
void switch_to_sync_source (SyncSource); /* !RT context */
|
||||
void drop_sync_source (); /* !RT context */
|
||||
void use_sync_source (Slave*); /* RT context */
|
||||
void switch_to_sync_source (SyncSource); /* !RT context */
|
||||
void drop_sync_source (); /* !RT context */
|
||||
void use_sync_source (Slave*); /* RT context */
|
||||
|
||||
bool post_export_sync;
|
||||
bool post_export_sync;
|
||||
nframes_t post_export_position;
|
||||
|
||||
bool _exporting;
|
||||
@ -967,7 +969,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
|
||||
std::string _path;
|
||||
std::string _name;
|
||||
bool _is_new;
|
||||
bool _is_new;
|
||||
bool session_send_mtc;
|
||||
bool session_midi_feedback;
|
||||
bool play_loop;
|
||||
@ -1039,8 +1041,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void set_post_transport_work (PostTransportWork ptw) { g_atomic_int_set (&_post_transport_work, (gint) ptw); }
|
||||
void add_post_transport_work (PostTransportWork ptw);
|
||||
|
||||
void schedule_playback_buffering_adjustment ();
|
||||
void schedule_capture_buffering_adjustment ();
|
||||
void schedule_playback_buffering_adjustment ();
|
||||
void schedule_capture_buffering_adjustment ();
|
||||
|
||||
uint32_t cumulative_rf_motion;
|
||||
uint32_t rf_scale;
|
||||
@ -1170,11 +1172,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void overwrite_some_buffers (Track *);
|
||||
void flush_all_inserts ();
|
||||
int micro_locate (nframes_t distance);
|
||||
void locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true);
|
||||
void start_locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
|
||||
void locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true);
|
||||
void start_locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
|
||||
void force_locate (framepos_t frame, bool with_roll = false);
|
||||
void set_track_speed (Track *, double speed);
|
||||
void set_transport_speed (double speed, bool abort = false, bool clear_state = false);
|
||||
void set_transport_speed (double speed, bool abort = false, bool clear_state = false);
|
||||
void stop_transport (bool abort = false, bool clear_state = false);
|
||||
void start_transport ();
|
||||
void realtime_stop (bool abort, bool clear_state);
|
||||
@ -1195,7 +1197,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
int load_route_groups (const XMLNode&, int);
|
||||
|
||||
std::list<RouteGroup *> _route_groups;
|
||||
RouteGroup* _all_route_group;
|
||||
RouteGroup* _all_route_group;
|
||||
|
||||
/* routes stuff */
|
||||
|
||||
@ -1330,7 +1332,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
uint32_t _total_free_4k_blocks;
|
||||
Glib::Mutex space_lock;
|
||||
|
||||
bool no_questions_about_missing_files;
|
||||
bool no_questions_about_missing_files;
|
||||
|
||||
std::string get_best_session_directory_for_new_source ();
|
||||
|
||||
@ -1453,12 +1455,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void add_session_range_location (nframes_t, nframes_t);
|
||||
|
||||
void setup_midi_machine_control ();
|
||||
void cleanup_stubfiles ();
|
||||
void cleanup_stubfiles ();
|
||||
|
||||
void route_order_key_changed ();
|
||||
|
||||
void step_edit_status_change (bool);
|
||||
uint32_t _step_editors;
|
||||
void step_edit_status_change (bool);
|
||||
uint32_t _step_editors;
|
||||
|
||||
/** true if timecode transmission by the transport is suspended, otherwise false */
|
||||
mutable gint _suspend_timecode_transmission;
|
||||
@ -1468,7 +1470,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||
void start_time_changed (framepos_t);
|
||||
void end_time_changed (framepos_t);
|
||||
|
||||
VBAPSpeakers* _speakers;
|
||||
VBAPSpeakers* _speakers;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (C) 2009 Paul Davis
|
||||
Author: Dave Robillard
|
||||
Author: David Robillard
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include <glibmm.h>
|
||||
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/pathscanner.h"
|
||||
@ -42,6 +44,8 @@
|
||||
#include "i18n.h"
|
||||
#include <locale.h>
|
||||
|
||||
#include "lv2ext/lv2_persist.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
@ -83,14 +87,21 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
|
||||
_latency_control_port = 0;
|
||||
_was_activated = false;
|
||||
|
||||
SLV2Value persist_uri = slv2_value_new_uri(_world.world, "http://lv2plug.in/ns/ext/persist");
|
||||
_supports_persist = slv2_plugin_has_feature(plugin, persist_uri);
|
||||
slv2_value_free(persist_uri);
|
||||
|
||||
_instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
|
||||
_data_access_feature.URI = "http://lv2plug.in/ns/ext/data-access";
|
||||
_persist_feature.URI = "http://lv2plug.in/ns/ext/persist";
|
||||
_persist_feature.data = NULL;
|
||||
|
||||
_features = (LV2_Feature**)malloc(sizeof(LV2_Feature*) * 4);
|
||||
_features = (LV2_Feature**)malloc(sizeof(LV2_Feature*) * 5);
|
||||
_features[0] = &_instance_access_feature;
|
||||
_features[1] = &_data_access_feature;
|
||||
_features[2] = _uri_map.feature();
|
||||
_features[3] = NULL;
|
||||
_features[2] = &_persist_feature;
|
||||
_features[3] = _uri_map.feature();
|
||||
_features[4] = NULL;
|
||||
|
||||
_instance = slv2_plugin_instantiate(plugin, rate, _features);
|
||||
_name = slv2_plugin_get_name(plugin);
|
||||
@ -271,6 +282,19 @@ LV2Plugin::nth_parameter (uint32_t n, bool& ok) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct LV2Value { void* value; uint32_t type; };
|
||||
typedef std::map< std::string, LV2Value > LV2State;
|
||||
|
||||
static void
|
||||
lv2_persist_store_callback(void* callback_data,
|
||||
const char* key,
|
||||
const void* value,
|
||||
size_t size,
|
||||
uint32_t type)
|
||||
{
|
||||
cout << "LV2 PERSIST STORE " << key << " = " << value << " :: " << type << endl;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
LV2Plugin::get_state()
|
||||
{
|
||||
@ -296,6 +320,25 @@ LV2Plugin::get_state()
|
||||
}
|
||||
}
|
||||
|
||||
if (_supports_persist) {
|
||||
// Create state directory for this plugin instance
|
||||
const std::string state_path = Glib::build_filename(_session.plugins_dir(), _id.to_s());
|
||||
cout << "LV2 plugin state path " << state_path << endl;
|
||||
|
||||
// Get LV2 Persist extension data from plugin instance
|
||||
LV2_Persist* persist = (LV2_Persist*)slv2_instance_get_extension_data(
|
||||
_instance, "http://lv2plug.in/ns/ext/persist");
|
||||
if (!persist) {
|
||||
warning << string_compose(
|
||||
_("Plugin \"%1\% failed to return LV2 persist data"),
|
||||
unique_id());
|
||||
return *root; // FIXME: Possibly inconsistent state
|
||||
}
|
||||
|
||||
LV2State state;
|
||||
persist->save(_instance, lv2_persist_store_callback, &state);
|
||||
}
|
||||
|
||||
return *root;
|
||||
}
|
||||
|
||||
|
@ -500,6 +500,13 @@ Session::ensure_subdirs ()
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir = plugins_dir ();
|
||||
|
||||
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
|
||||
error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2177,6 +2184,12 @@ Session::analysis_dir () const
|
||||
return Glib::build_filename (_path, "analysis");
|
||||
}
|
||||
|
||||
string
|
||||
Session::plugins_dir () const
|
||||
{
|
||||
return Glib::build_filename (_path, "plugins");
|
||||
}
|
||||
|
||||
int
|
||||
Session::load_bundles (XMLNode const & node)
|
||||
{
|
||||
|
@ -1,19 +1,22 @@
|
||||
/* This file is part of Ingen.
|
||||
* Copyright (C) 2008 Dave Robillard <http://drobilla.net>
|
||||
*
|
||||
* Ingen is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2008-2010 Paul Davis
|
||||
Author: David Robillard
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
Loading…
Reference in New Issue
Block a user