Merged with trunk R795

Fiddled with scrolling to leave a bit of context on each side.  'scroll interval' is a single float, should make it a configuration variable some day


git-svn-id: svn://localhost/ardour2/branches/midi@796 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard
2006-08-12 19:43:09 +00:00
parent 30ab1fd615
commit a98a67120e
27 changed files with 352 additions and 116 deletions

View File

@@ -86,6 +86,9 @@ class AUPlugin : public ARDOUR::Plugin
bool has_editor () const;
CAAudioUnit* get_au () { return unit; }
CAComponent* get_comp () { return comp; }
private:
CAComponent* comp;
CAAudioUnit* unit;
@@ -110,6 +113,7 @@ class AUPluginInfo : public PluginInfo {
private:
static std::string get_name (CAComponentDescription&);
void setup_nchannels (CAComponentDescription&);
};
typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;

View File

@@ -186,8 +186,19 @@ static inline cycles_t get_cycles (void)
/* begin mach */
#elif defined(__APPLE__)
#include <CoreAudio/CoreAudioTypes.h>
#ifdef HAVE_COREAUDIO
#include <CoreAudio/HostTime.h>
#else // Due to MacTypes.h and libgnomecanvasmm Rect conflict
typedef unsigned long long UInt64;
extern UInt64
AudioGetCurrentHostTime();
extern UInt64
AudioConvertHostTimeToNanos(UInt64 inHostTime);
#endif
typedef UInt64 cycles_t;
static inline cycles_t get_cycles (void)
{

View File

@@ -493,7 +493,7 @@ class Session : public sigc::trackable, public Stateful
int save_state (string snapshot_name, bool pending = false);
int restore_state (string snapshot_name);
int save_template (string template_name);
int save_history ();
int save_history (string snapshot_name = "");
static int rename_template (string old_name, string new_name);

View File

@@ -137,7 +137,7 @@ AUPlugin::get_parameter (uint32_t which) const
int
AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
{
return -1;
return 0;
}
uint32_t
@@ -325,6 +325,7 @@ AUPluginInfo::discover ()
plug->type = ARDOUR::AudioUnit;
plug->n_inputs = 0;
plug->n_outputs = 0;
// plug->setup_nchannels (temp);
plug->category = "AudioUnit";
plug->desc = new CAComponentDescription(temp);
@@ -376,3 +377,20 @@ AUPluginInfo::get_name (CAComponentDescription& comp_desc)
return CFStringRefToStdString(itemName);
}
void
AUPluginInfo::setup_nchannels (CAComponentDescription& comp_desc)
{
CAAudioUnit unit;
CAAudioUnit::Open (comp_desc, unit);
if (unit.SupportsNumChannels()) {
n_inputs = n_outputs = 0;
} else {
AUChannelInfo cinfo;
size_t info_size = sizeof(cinfo);
OSStatus err = AudioUnitGetProperty (unit.AU(), kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global,
0, &cinfo, &info_size);
}
}

View File

@@ -1015,7 +1015,7 @@ Session::auto_punch_start_changed (Location* location)
if (get_record_enabled() && get_punch_in()) {
/* capture start has been changed, so save new pending state */
save_state ("", true);
save_history();
save_history("");
}
}
@@ -1337,7 +1337,7 @@ Session::maybe_enable_record ()
*/
save_state ("", true);
save_history();
save_history ("");
if (_transport_speed) {
if (!punch_in) {
@@ -2066,6 +2066,7 @@ Session::add_route (shared_ptr<Route> route)
set_dirty();
save_state (_current_snapshot_name);
save_history (_current_snapshot_name);
RouteAdded (route); /* EMIT SIGNAL */
}
@@ -2097,7 +2098,7 @@ Session::add_diskstream (Diskstream* dstream)
set_dirty();
save_state (_current_snapshot_name);
save_history();
save_history (_current_snapshot_name);
DiskstreamAdded (dstream); /* EMIT SIGNAL */
}
@@ -2161,6 +2162,7 @@ Session::remove_route (shared_ptr<Route> route)
/* XXX should we disconnect from the Route's signals ? */
save_state (_current_snapshot_name);
save_history (_current_snapshot_name);
/* all shared ptrs to route should go out of scope here */
}
@@ -2849,7 +2851,7 @@ Session::remove_source (Source* source)
*/
save_state (_current_snapshot_name);
save_history();
save_history (_current_snapshot_name);
}
SourceRemoved(source); /* EMIT SIGNAL */

View File

@@ -9,7 +9,6 @@ Command *Session::memento_command_factory(XMLNode *n)
{
PBD::ID id;
XMLNode *before, *after;
//void *obj;
/* get obj_id */
@@ -21,6 +20,7 @@ Command *Session::memento_command_factory(XMLNode *n)
if (Diskstream *obj = diskstream_by_id(id))
return new MementoCommand<Diskstream>(*obj, *before, *after);
// etc.
return 0;
}

View File

@@ -605,6 +605,7 @@ Session::mmc_record_strobe (MIDI::MachineControl &mmc)
*/
save_state ("", true);
save_history ("");
g_atomic_int_set (&_record_status, Enabled);
RecordStateChanged (); /* EMIT SIGNAL */

View File

@@ -608,7 +608,7 @@ Session::create (bool& new_session, string* mix_template, jack_nframes_t initial
_state_of_the_state = Clean;
if (save_state (_current_snapshot_name)) {
save_history();
save_history (_current_snapshot_name);
return -1;
}
}
@@ -1696,7 +1696,7 @@ Session::set_state (const XMLNode& node)
if (state_was_pending) {
save_state (_current_snapshot_name);
save_history();
save_history (_current_snapshot_name);
remove_pending_capture_state ();
state_was_pending = false;
}
@@ -2498,7 +2498,7 @@ void
Session::auto_save()
{
save_state (_current_snapshot_name);
save_history();
save_history (_current_snapshot_name);
}
RouteGroup *
@@ -3170,6 +3170,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
*/
save_state ("");
save_history ("");
out:
_state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
@@ -3303,7 +3304,7 @@ Session::add_instant_xml (XMLNode& node, const std::string& dir)
int
Session::save_history ()
Session::save_history (string snapshot_name)
{
XMLTree tree;
string xml_path;
@@ -3311,7 +3312,11 @@ Session::save_history ()
tree.set_root (&history.get_state());
xml_path = _path + _current_snapshot_name + ".history";
if (snapshot_name.empty()) {
snapshot_name = _current_snapshot_name;
}
xml_path = _path + snapshot_name + ".history";
bak_path = xml_path + ".bak";

View File

@@ -413,7 +413,7 @@ Session::non_realtime_stop (bool abort)
if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
/* capture start has been changed, so save pending state */
save_state ("", true);
save_history();
save_history ("");
}
/* always try to get rid of this */
@@ -424,6 +424,7 @@ Session::non_realtime_stop (bool abort)
if (did_record) {
save_state (_current_snapshot_name);
save_history (_current_snapshot_name);
}
if (post_transport_work & PostTransportDuration) {

View File

@@ -224,7 +224,7 @@ Track::set_name (string str, void *src)
if ((ret = IO::set_name (str, src)) == 0) {
_session.save_state ("");
_session.save_history();
_session.save_history ("");
}
return ret;
}

View File

@@ -6,32 +6,29 @@
#include <list>
template<class T>
class RCUManager
{
public:
RCUManager (T* new_rcu_value)
: m_rcu_value(new_rcu_value)
{
public:
RCUManager (T* new_rcu_value) {
m_rcu_value = new boost::shared_ptr<T> (new_rcu_value);
}
virtual ~RCUManager() { }
virtual ~RCUManager() { delete m_rcu_value; }
boost::shared_ptr<T> reader () const { return m_rcu_value; }
boost::shared_ptr<T> reader () const { return *((boost::shared_ptr<T> *) g_atomic_pointer_get (&m_rcu_value)); }
// should be private
virtual boost::shared_ptr<T> write_copy () = 0;
// should be private
virtual void update (boost::shared_ptr<T> new_value) = 0;
protected:
boost::shared_ptr<T> m_rcu_value;
virtual bool update (boost::shared_ptr<T> new_value) = 0;
protected:
boost::shared_ptr<T>* m_rcu_value;
// this monstrosity is needed because of some wierd behavior by g++
gpointer * the_pointer() const { return (gpointer *) &m_rcu_value; }
};
@@ -49,37 +46,63 @@ public:
virtual boost::shared_ptr<T> write_copy ()
{
m_lock.lock();
// I hope this is doing what I think it is doing :)
boost::shared_ptr<T> new_copy(new T(*RCUManager<T>::m_rcu_value));
// XXX todo remove old copies with only 1 reference from the list.
// clean out any dead wood
typename std::list<boost::shared_ptr<T> >::iterator i;
for (i = m_dead_wood.begin(); i != m_dead_wood.end(); ) {
if ((*i).use_count() == 1) {
i = m_dead_wood.erase (i);
} else {
++i;
}
}
// store the current
current_write_old = RCUManager<T>::m_rcu_value;
boost::shared_ptr<T> new_copy (new T(**current_write_old));
return new_copy;
}
virtual void update (boost::shared_ptr<T> new_value)
virtual bool update (boost::shared_ptr<T> new_value)
{
// So a current reader doesn't hold the only reference to
// the existing value when we assign it a new value which
// should ensure that deletion of old values doesn't
// occur in a reader thread.
boost::shared_ptr<T> old_copy = RCUManager<T>::m_rcu_value;
// we hold the lock at this point effectively blocking
// other writers.
RCUManager<T>::m_rcu_value = new_value;
// XXX add the old value to the list of old copies.
boost::shared_ptr<T>* new_spp = new boost::shared_ptr<T> (new_value);
// update, checking that nobody beat us to it
bool ret = g_atomic_pointer_compare_and_exchange (RCUManager<T>::the_pointer(),
(gpointer) current_write_old,
(gpointer) new_spp);
if (ret) {
// successful update : put the old value into dead_wood,
m_dead_wood.push_back (*current_write_old);
// now delete it - this gets rid of the shared_ptr<T> but
// because dead_wood contains another shared_ptr<T> that
// references the same T, the underlying object lives on
delete current_write_old;
}
m_lock.unlock();
return ret;
}
private:
Glib::Mutex m_lock;
std::list<boost::shared_ptr<T> > m_old_values;
Glib::Mutex m_lock;
boost::shared_ptr<T>* current_write_old;
std::list<boost::shared_ptr<T> > m_dead_wood;
};
template<class T>

View File

@@ -145,7 +145,7 @@ void
BasicUI::save_state ()
{
session->save_state ("");
session->save_history();
session->save_history("");
}
void