summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-02-16 22:55:47 +0000
committerDavid Robillard <d@drobilla.net>2008-02-16 22:55:47 +0000
commit859e9106e72a7908fa093d946111d148223225a0 (patch)
treeec47825b5f5746bcbc5d321d40da7fc798f5c380 /libs/ardour
parent8aa9508c82f32efcf9c7c00e2c9e76268d4dddce (diff)
Merge with 2.0-ongoing R3071.
git-svn-id: svn://localhost/ardour2/branches/3.0@3074 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/SConscript12
-rw-r--r--libs/ardour/analyser.cc2
-rw-r--r--libs/ardour/ardour/ardour.h7
-rw-r--r--libs/ardour/ardour/audio_unit.h16
-rw-r--r--libs/ardour/ardour/audiosource.h1
-rw-r--r--libs/ardour/ardour/automatable.h5
-rw-r--r--libs/ardour/ardour/configuration_vars.h1
-rw-r--r--libs/ardour/ardour/io.h4
-rw-r--r--libs/ardour/ardour/io_processor.h2
-rw-r--r--libs/ardour/ardour/playlist.h1
-rw-r--r--libs/ardour/ardour/route.h4
-rw-r--r--libs/ardour/ardour/session.h17
-rw-r--r--libs/ardour/ardour/types.h3
-rw-r--r--libs/ardour/ardour/utils.h2
-rw-r--r--libs/ardour/audio_track.cc2
-rw-r--r--libs/ardour/audio_unit.cc178
-rw-r--r--libs/ardour/audioengine.cc2
-rw-r--r--libs/ardour/audiofilesource.cc26
-rw-r--r--libs/ardour/audioregion.cc11
-rw-r--r--libs/ardour/audiosource.cc19
-rw-r--r--libs/ardour/automatable.cc4
-rw-r--r--libs/ardour/filter.cc5
-rw-r--r--libs/ardour/globals.cc73
-rw-r--r--libs/ardour/import.cc51
-rw-r--r--libs/ardour/io.cc22
-rw-r--r--libs/ardour/playlist.cc40
-rw-r--r--libs/ardour/plugin.cc13
-rw-r--r--libs/ardour/region.cc8
-rw-r--r--libs/ardour/route.cc32
-rw-r--r--libs/ardour/session.cc135
-rw-r--r--libs/ardour/session_state.cc9
-rw-r--r--libs/ardour/session_transport.cc4
-rw-r--r--libs/ardour/source.cc2
-rw-r--r--libs/ardour/transient_detector.cc16
-rw-r--r--libs/ardour/utils.cc44
35 files changed, 599 insertions, 174 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 529a778942..7521bd728a 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -20,6 +20,9 @@ ardour.Append(CXXFLAGS=["-DLIBSIGC_DISABLE_DEPRECATED", "-DGLIBMM_EXCEPTIONS_ENA
ardour.Append(PACKAGE = domain)
ardour.Append(POTFILE = domain + '.pot')
+if ardour['IS_OSX']:
+ ardour.Append (LINKFLAGS="-Xlinker -headerpad -Xlinker 2048")
+
#
# explicitly reference the control protocol LGPL library for includes
#
@@ -312,7 +315,7 @@ ardour.Merge ([
libraries['sndfile-ardour'],
libraries['vamp'],
libraries['vamphost'],
- libraries['xml'],
+ libraries['xml']
])
if ardour['RUBBERBAND']:
@@ -380,5 +383,10 @@ env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
[ 'sse_functions_xmm.cc', 'sse_functions.s', 'sse_functions_64bit.s' ] +
[ 'rb_effect.cc', 'st_stretch.cc', 'st_pitch.cc' ] +
- ardour_files + osc_files + vst_files + coreaudio_files + audiounit_files +
+ ardour_files +
+ osc_files +
+ vst_files +
+ coreaudio_files +
+ audiounit_files +
+ lv2_files +
glob.glob('po/*.po') + glob.glob('ardour/*.h')))
diff --git a/libs/ardour/analyser.cc b/libs/ardour/analyser.cc
index 7ddb5428e9..2e14c74b86 100644
--- a/libs/ardour/analyser.cc
+++ b/libs/ardour/analyser.cc
@@ -95,7 +95,7 @@ Analyser::work ()
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
- if (afs) {
+ if (afs && afs->length()) {
analyse_audio_file_source (afs);
}
}
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h
index fcec83394f..6f653f10bf 100644
--- a/libs/ardour/ardour/ardour.h
+++ b/libs/ardour/ardour/ardour.h
@@ -20,8 +20,10 @@
#ifndef __ardour_ardour_h__
#define __ardour_ardour_h__
-#include <limits.h>
+#include <map>
#include <string>
+
+#include <limits.h>
#include <signal.h>
#include <pbd/error.h>
@@ -43,12 +45,15 @@ namespace ARDOUR {
extern OSC* osc;
static const nframes_t max_frames = JACK_MAX_FRAMES;
+ extern sigc::signal<void,std::string> BootMessage;
int init (bool with_vst, bool try_optimization);
int cleanup ();
std::string get_ardour_revision ();
+ void find_bindings_files (std::map<std::string,std::string>&);
+
const layer_t max_layer = UCHAR_MAX;
microseconds_t get_microseconds ();
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
index c781e8200d..bdeac0477b 100644
--- a/libs/ardour/ardour/audio_unit.h
+++ b/libs/ardour/ardour/audio_unit.h
@@ -32,6 +32,7 @@
#include <ardour/plugin.h>
#include <AudioUnit/AudioUnit.h>
+#include <appleutility/AUParamInfo.h>
#include <boost/shared_ptr.hpp>
@@ -45,6 +46,16 @@ namespace ARDOUR {
class AudioEngine;
class Session;
+struct AUParameterDescriptor : public Plugin::ParameterDescriptor {
+ // additional fields to make operations more efficient
+ AudioUnitParameterID id;
+ AudioUnitScope scope;
+ AudioUnitElement element;
+ float default_value;
+ bool automatable;
+ AudioUnitParameterUnit unit;
+};
+
class AUPlugin : public ARDOUR::Plugin
{
public:
@@ -105,7 +116,7 @@ class AUPlugin : public ARDOUR::Plugin
private:
boost::shared_ptr<CAComponent> comp;
boost::shared_ptr<CAAudioUnit> unit;
-
+
AudioStreamBasicDescription streamFormat;
bool initialized;
int format_set;
@@ -119,6 +130,7 @@ class AUPlugin : public ARDOUR::Plugin
int set_input_format ();
int set_stream_format (int scope, uint32_t cnt);
int _set_block_size (nframes_t nframes);
+ void discover_parameters ();
std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
uint32_t current_maxbuf;
@@ -126,6 +138,8 @@ class AUPlugin : public ARDOUR::Plugin
nframes_t cb_offset;
vector<Sample*>* current_buffers;
nframes_t frames_processed;
+
+ std::vector<AUParameterDescriptor> descriptors;
};
typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 1589841baa..d11b829694 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -116,7 +116,6 @@ class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR:
static bool _build_peakfiles;
bool _peaks_built;
- bool _analysed;
mutable Glib::Mutex _lock;
mutable Glib::Mutex _peaks_ready_lock;
Glib::ustring peakpath;
diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h
index f96ecc0bd1..a2c1d98ae7 100644
--- a/libs/ardour/ardour/automatable.h
+++ b/libs/ardour/ardour/automatable.h
@@ -57,7 +57,10 @@ public:
virtual void add_control(boost::shared_ptr<AutomationControl>);
- virtual void automation_snapshot(nframes_t now);
+ virtual void automation_snapshot(nframes_t now, bool force);
+ bool should_snapshot (nframes_t now) {
+ return (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval);
+ }
virtual void transport_stopped(nframes_t now);
virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
index 134557daeb..015c617425 100644
--- a/libs/ardour/ardour/configuration_vars.h
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -105,6 +105,7 @@ CONFIG_VARIABLE (bool, punch_out, "punch-out", false)
CONFIG_VARIABLE (bool, plugins_stop_with_transport, "plugins-stop-with-transport", false)
CONFIG_VARIABLE (bool, do_not_record_plugins, "do-not-record-plugins", false)
CONFIG_VARIABLE (bool, stop_recording_on_xrun, "stop-recording-on-xrun", false)
+CONFIG_VARIABLE (bool, create_xrun_marker, "create-xrun-marker", true)
CONFIG_VARIABLE (bool, stop_at_session_end, "stop-at-session-end", true)
CONFIG_VARIABLE (bool, seamless_loop, "seamless-loop", false)
CONFIG_VARIABLE (nframes_t, preroll, "preroll", 0)
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 0b82844f61..83b6378dae 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -251,8 +251,8 @@ class IO : public Automatable, public Latent
void set_parameter_automation_state (Parameter, AutoState);
- virtual void transport_stopped (nframes_t now); // interface: matches Insert
- void automation_snapshot (nframes_t now); // interface: matches Automatable
+ virtual void transport_stopped (nframes_t now);
+ virtual void automation_snapshot (nframes_t now, bool force);
void start_pan_touch (uint32_t which);
void end_pan_touch (uint32_t which);
diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h
index 409ad91b15..a535ce3bb4 100644
--- a/libs/ardour/ardour/io_processor.h
+++ b/libs/ardour/ardour/io_processor.h
@@ -65,7 +65,7 @@ class IOProcessor : public Processor
boost::shared_ptr<IO> io() { return _io; }
boost::shared_ptr<const IO> io() const { return _io; }
- virtual void automation_snapshot (nframes_t now) { _io->automation_snapshot(now); }
+ virtual void automation_snapshot (nframes_t now, bool force) { _io->automation_snapshot(now, force); }
virtual void run_in_place (BufferSet& in, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) = 0;
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index d8a38841f8..4640a8e32f 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -126,7 +126,6 @@ class Playlist : public SessionObject, public boost::enable_shared_from_this<Pla
sigc::signal<void> LengthChanged;
static string bump_name (string old_name, Session&);
- static string bump_name_once (string old_name);
void freeze ();
void thaw ();
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 2466f37996..c7c0b77102 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -75,6 +75,8 @@ class Route : public IO
Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
virtual ~Route();
+ static std::string ensure_track_or_route_name(std::string, Session &);
+
std::string comment() { return _comment; }
void set_comment (std::string str, void *src);
@@ -247,7 +249,7 @@ class Route : public IO
return _mute_control;
}
- void automation_snapshot (nframes_t now);
+ void automation_snapshot (nframes_t now, bool force=false);
void protect_automation ();
void set_remote_control_id (uint32_t id);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index c0c178eb02..10167ae5b3 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -353,7 +353,7 @@ class Session : public PBD::StatefulDestructible
sigc::signal<void> TransportStateChange; /* generic */
sigc::signal<void,nframes_t> PositionChanged; /* sent after any non-sequential motion */
sigc::signal<void> DurationChanged;
- sigc::signal<void> HaltOnXrun;
+ sigc::signal<void,nframes_t> Xrun;
sigc::signal<void> TransportLooped;
sigc::signal<void,RouteList&> RouteAdded;
@@ -563,8 +563,11 @@ class Session : public PBD::StatefulDestructible
/* region info */
- sigc::signal<void,boost::shared_ptr<Region> > RegionAdded;
- sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved;
+ void add_regions (std::vector<boost::shared_ptr<Region> >&);
+
+ sigc::signal<void,boost::weak_ptr<Region> > RegionAdded;
+ sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
+ sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string);
@@ -586,10 +589,10 @@ class Session : public PBD::StatefulDestructible
string doing_what;
/* control info */
- bool sample_convert;
SrcQuality quality;
volatile bool freeze;
std::vector<Glib::ustring> paths;
+ bool replace_existing_source;
/* result */
SourceList sources;
@@ -1480,6 +1483,12 @@ class Session : public PBD::StatefulDestructible
SourceMap sources;
+ public:
+ SourceMap get_sources() { return sources; }
+
+ private:
+
+
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index fdf8d0b439..efc2e35ecc 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -257,7 +257,8 @@ namespace ARDOUR {
enum EditMode {
Slide,
- Splice
+ Splice,
+ Lock
};
enum RegionPoint {
diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h
index e52274eb1f..eecde2e85f 100644
--- a/libs/ardour/ardour/utils.h
+++ b/libs/ardour/ardour/utils.h
@@ -45,6 +45,8 @@ static inline float f_max(float x, float a) {
return (x);
}
+std::string bump_name_once(std::string s);
+
int cmp_nocase (const std::string& s, const std::string& s2);
int touch_file(Glib::ustring path);
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index bc2f0d9feb..7d55cc343a 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -519,7 +519,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
if (lm.locked()) {
// automation snapshot can also be called from the non-rt context
// and it uses the redirect list, so we take the lock out here
- automation_snapshot (start_frame);
+ automation_snapshot (start_frame, false);
}
}
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index 387c7f1238..9132957743 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -32,6 +32,7 @@
#include <ardour/utils.h>
#include <appleutility/CAAudioUnit.h>
+#include <appleutility/CAAUParameter.h>
#include <CoreServices/CoreServices.h>
#include <AudioUnit/AudioUnit.h>
@@ -83,6 +84,7 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
throw failed_constructor();
}
+ unit->GetElementCount (kAudioUnitScope_Global, global_elements);
unit->GetElementCount (kAudioUnitScope_Input, input_elements);
unit->GetElementCount (kAudioUnitScope_Output, output_elements);
@@ -106,6 +108,10 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
error << _("AUPlugin: cannot set processing block size") << endmsg;
throw failed_constructor();
}
+
+ discover_parameters ();
+
+ Plugin::setup_controls ();
}
AUPlugin::~AUPlugin ()
@@ -119,6 +125,124 @@ AUPlugin::~AUPlugin ()
}
}
+void
+AUPlugin::discover_parameters ()
+{
+ /* discover writable parameters */
+
+ cerr << "get param info, there are " << global_elements << " global elements\n";
+
+ AudioUnitScope scopes[] = {
+ kAudioUnitScope_Global,
+ kAudioUnitScope_Output,
+ kAudioUnitScope_Input
+ };
+
+ descriptors.clear ();
+
+ for (uint32_t i = 0; i < sizeof (scopes) / sizeof (scopes[0]); ++i) {
+
+ AUParamInfo param_info (unit->AU(), false, false, scopes[i]);
+
+ cerr << "discovered " << param_info.NumParams() << " parameters in scope " << i << endl;
+
+ for (uint32_t i = 0; i < param_info.NumParams(); ++i) {
+
+ AUParameterDescriptor d;
+
+ d.id = param_info.ParamID (i);
+
+ const CAAUParameter* param = param_info.GetParamInfo (d.id);
+ const AudioUnitParameterInfo& info (param->ParamInfo());
+
+ const int len = CFStringGetLength (param->GetName());;
+ char local_buffer[len*2];
+ Boolean good = CFStringGetCString(param->GetName(),local_buffer,len*2,kCFStringEncodingMacRoman);
+ if (!good) {
+ d.label = "???";
+ } else {
+ d.label = local_buffer;
+ }
+
+ d.scope = param_info.GetScope ();
+ d.element = param_info.GetElement ();
+
+ /* info.units to consider */
+ /*
+ kAudioUnitParameterUnit_Generic = 0
+ kAudioUnitParameterUnit_Indexed = 1
+ kAudioUnitParameterUnit_Boolean = 2
+ kAudioUnitParameterUnit_Percent = 3
+ kAudioUnitParameterUnit_Seconds = 4
+ kAudioUnitParameterUnit_SampleFrames = 5
+ kAudioUnitParameterUnit_Phase = 6
+ kAudioUnitParameterUnit_Rate = 7
+ kAudioUnitParameterUnit_Hertz = 8
+ kAudioUnitParameterUnit_Cents = 9
+ kAudioUnitParameterUnit_RelativeSemiTones = 10
+ kAudioUnitParameterUnit_MIDINoteNumber = 11
+ kAudioUnitParameterUnit_MIDIController = 12
+ kAudioUnitParameterUnit_Decibels = 13
+ kAudioUnitParameterUnit_LinearGain = 14
+ kAudioUnitParameterUnit_Degrees = 15
+ kAudioUnitParameterUnit_EqualPowerCrossfade = 16
+ kAudioUnitParameterUnit_MixerFaderCurve1 = 17
+ kAudioUnitParameterUnit_Pan = 18
+ kAudioUnitParameterUnit_Meters = 19
+ kAudioUnitParameterUnit_AbsoluteCents = 20
+ kAudioUnitParameterUnit_Octaves = 21
+ kAudioUnitParameterUnit_BPM = 22
+ kAudioUnitParameterUnit_Beats = 23
+ kAudioUnitParameterUnit_Milliseconds = 24
+ kAudioUnitParameterUnit_Ratio = 25
+ */
+
+ /* info.flags to consider */
+
+ /*
+
+ kAudioUnitParameterFlag_CFNameRelease = (1L << 4)
+ kAudioUnitParameterFlag_HasClump = (1L << 20)
+ kAudioUnitParameterFlag_HasName = (1L << 21)
+ kAudioUnitParameterFlag_DisplayLogarithmic = (1L << 22)
+ kAudioUnitParameterFlag_IsHighResolution = (1L << 23)
+ kAudioUnitParameterFlag_NonRealTime = (1L << 24)
+ kAudioUnitParameterFlag_CanRamp = (1L << 25)
+ kAudioUnitParameterFlag_ExpertMode = (1L << 26)
+ kAudioUnitParameterFlag_HasCFNameString = (1L << 27)
+ kAudioUnitParameterFlag_IsGlobalMeta = (1L << 28)
+ kAudioUnitParameterFlag_IsElementMeta = (1L << 29)
+ kAudioUnitParameterFlag_IsReadable = (1L << 30)
+ kAudioUnitParameterFlag_IsWritable = (1L << 31)
+ */
+
+ d.lower = info.minValue;
+ d.upper = info.maxValue;
+ d.default_value = info.defaultValue;
+
+ d.integer_step = (info.unit & kAudioUnitParameterUnit_Indexed);
+ d.toggled = (info.unit & kAudioUnitParameterUnit_Boolean) ||
+ (d.integer_step && ((d.upper - d.lower) == 1.0));
+ d.sr_dependent = (info.unit & kAudioUnitParameterUnit_SampleFrames);
+ d.automatable = !d.toggled &&
+ !(info.flags & kAudioUnitParameterFlag_NonRealTime) &&
+ (info.flags & kAudioUnitParameterFlag_IsWritable);
+
+ d.logarithmic = (info.flags & kAudioUnitParameterFlag_DisplayLogarithmic);
+ d.unit = info.unit;
+
+ d.step = 1.0;
+ d.smallstep = 0.1;
+ d.largestep = 10.0;
+ d.min_unbound = 0; // lower is bound
+ d.max_unbound = 0; // upper is bound
+
+ descriptors.push_back (d);
+ }
+ }
+}
+
+
string
AUPlugin::unique_id () const
{
@@ -134,13 +258,16 @@ AUPlugin::label () const
uint32_t
AUPlugin::parameter_count () const
{
- return 0;
+ return descriptors.size();
}
float
AUPlugin::default_value (uint32_t port)
{
- // AudioUnits don't have default values. Maybe presets though?
+ if (port < descriptors.size()) {
+ return descriptors[port].default_value;
+ }
+
return 0;
}
@@ -157,28 +284,41 @@ AUPlugin::signal_latency () const
void
AUPlugin::set_parameter (uint32_t which, float val)
{
- // unit->SetParameter (parameter_map[which].first, parameter_map[which].second, 0, val);
+ if (which < descriptors.size()) {
+ const AUParameterDescriptor& d (descriptors[which]);
+ unit->SetParameter (d.id, d.scope, d.element, val);
+ }
}
float
AUPlugin::get_parameter (uint32_t which) const
{
- float outValue = 0.0;
-
- // unit->GetParameter(parameter_map[which].first, parameter_map[which].second, 0, outValue);
-
- return outValue;
+ float val = 0.0;
+ if (which < descriptors.size()) {
+ const AUParameterDescriptor& d (descriptors[which]);
+ unit->GetParameter(d.id, d.scope, d.element, val);
+ }
+ return val;
}
int
-AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
+AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& pd) const
{
- return 0;
+ if (which < descriptors.size()) {
+ pd = descriptors[which];
+ return 0;
+ }
+ return -1;
}
uint32_t
AUPlugin::nth_parameter (uint32_t which, bool& ok) const
{
+ if (which < descriptors.size()) {
+ ok = true;
+ return which;
+ }
+ ok = false;
return 0;
}
@@ -397,20 +537,26 @@ set<uint32_t>
AUPlugin::automatable() const
{
set<uint32_t> automates;
-
+
+ for (uint32_t i = 0; i < descriptors.size(); ++i) {
+ if (descriptors[i].automatable) {
+ automates.insert (i);
+ }
+ }
+
return automates;
}
string
-AUPlugin::describe_parameter (uint32_t)
+AUPlugin::describe_parameter (uint32_t param)
{
- return "";
+ return descriptors[param].label;
}
void
-AUPlugin::print_parameter (uint32_t, char*, uint32_t len) const
+AUPlugin::print_parameter (uint32_t param, char* buf, uint32_t len) const
{
-
+ // NameValue stuff here
}
bool
@@ -422,7 +568,7 @@ AUPlugin::parameter_is_audio (uint32_t) const
bool
AUPlugin::parameter_is_control (uint32_t) const
{
- return false;
+ return true;
}
bool
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index da4f8a642c..8d2589db0e 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -126,6 +126,8 @@ AudioEngine::start ()
if (session) {
nframes_t blocksize = jack_get_buffer_size (_jack);
+ BootMessage (_("Connect session to engine"));
+
session->set_block_size (blocksize);
session->set_frame_rate (jack_get_sample_rate (_jack));
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 81ad45e08a..00e0f925df 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -677,20 +677,18 @@ bool
AudioFileSource::safe_file_extension(ustring file)
{
return !(file.rfind(".wav") == ustring::npos &&
- file.rfind(".aiff")== ustring::npos &&
- file.rfind(".aif") == ustring::npos &&
- file.rfind(".snd") == ustring::npos &&
- file.rfind(".au") == ustring::npos &&
- file.rfind(".raw") == ustring::npos &&
- file.rfind(".sf") == ustring::npos &&
- file.rfind(".cdr") == ustring::npos &&
- file.rfind(".smp") == ustring::npos &&
- file.rfind(".maud")== ustring::npos &&
- file.rfind(".vwe") == ustring::npos &&
- file.rfind(".paf") == ustring::npos &&
- /* protools convention */
- file.rfind(".L") == ustring::npos &&
- file.rfind(".R") == ustring::npos &&
+ file.rfind(".aiff")== ustring::npos &&
+ file.rfind(".aif") == ustring::npos &&
+ file.rfind(".amb") == ustring::npos &&
+ file.rfind(".snd") == ustring::npos &&
+ file.rfind(".au") == ustring::npos &&
+ file.rfind(".raw") == ustring::npos &&
+ file.rfind(".sf") == ustring::npos &&
+ file.rfind(".cdr") == ustring::npos &&
+ file.rfind(".smp") == ustring::npos &&
+ file.rfind(".maud")== ustring::npos &&
+ file.rfind(".vwe") == ustring::npos &&
+ file.rfind(".paf") == ustring::npos &&
#ifdef HAVE_FLAC
file.rfind(".flac")== ustring::npos &&
#endif // HAVE_FLAC
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 20115ff944..7e2b709abd 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -1316,6 +1316,8 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
return 0;
}
+ cerr << "startup analysis of " << _name << endl;
+
TransientDetector t (pl->session().frame_rate());
bool existing_results = !results.empty();
@@ -1328,10 +1330,14 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
t.reset ();
+ cerr << "working on channel " << i << endl;
+
if (t.run ("", this, i, these_results)) {
return -1;
}
+ cerr << "done\n";
+
/* translate all transients to give absolute position */
for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
@@ -1357,6 +1363,11 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
/* make sure ours are clean too */
TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
+
+ } else {
+
+ TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
+ results = _transients;
}
_valid_transients = true;
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index cd71dd21e4..01dea08d3e 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -70,6 +70,7 @@ AudioSource::AudioSource (Session& s, ustring name)
AudioSource::AudioSource (Session& s, const XMLNode& node)
: Source (s, node)
{
+
_peaks_built = false;
_peak_byte_max = 0;
peakfile = -1;
@@ -213,7 +214,7 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
/* we found it in the peaks dir, so check it out */
- if (statbuf.st_size == 0) {
+ if (statbuf.st_size == 0 || (statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
// empty
_peaks_built = false;
} else {
@@ -221,12 +222,22 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
struct stat stat_file;
int err = stat (audio_path.c_str(), &stat_file);
- if (!err && stat_file.st_mtime > statbuf.st_mtime){
+ if (err) {
_peaks_built = false;
_peak_byte_max = 0;
} else {
- _peaks_built = true;
- _peak_byte_max = statbuf.st_size;
+
+ /* allow 6 seconds slop on checking peak vs. file times because of various
+ disk action "races"
+ */
+
+ if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
+ _peaks_built = false;
+ _peak_byte_max = 0;
+ } else {
+ _peaks_built = true;
+ _peak_byte_max = statbuf.st_size;
+ }
}
}
}
diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc
index 45b19d1997..8b8b843384 100644
--- a/libs/ardour/automatable.cc
+++ b/libs/ardour/automatable.cc
@@ -422,9 +422,9 @@ Automatable::protect_automation ()
}
void
-Automatable::automation_snapshot (nframes_t now)
+Automatable::automation_snapshot (nframes_t now, bool force)
{
- if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
+ if (force || _last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
for (Controls::iterator i = _controls.begin(); i != _controls.end(); ++i) {
if (i->second->list()->automation_write()) {
diff --git a/libs/ardour/filter.cc b/libs/ardour/filter.cc
index dc8185db95..be382f72da 100644
--- a/libs/ardour/filter.cc
+++ b/libs/ardour/filter.cc
@@ -28,6 +28,7 @@
#include <ardour/filter.h>
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
+#include <ardour/analyser.h>
#include "i18n.h"
@@ -101,6 +102,10 @@ Filter::finish (boost::shared_ptr<Region> region, SourceList& nsrcs, string regi
smfs->set_timeline_position (region->position());
smfs->flush_footer ();
}
+
+ /* now that there is data there, requeue the file for analysis */
+
+ Analyser::queue_source_for_analysis (*si, false);
}
/* create a new region */
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 6aba688cae..02c4a5ced6 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -19,9 +19,12 @@
#include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include <unistd.h>
#include <fcntl.h>
#include <locale.h>
+#include <errno.h>
#ifdef VST_SUPPORT
#include <fst.h>
@@ -31,12 +34,16 @@
#include <xmmintrin.h>
#endif
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
#include <lrdf.h>
#include <pbd/error.h>
#include <pbd/id.h>
#include <pbd/strsplit.h>
#include <pbd/fpu.h>
+#include <pbd/file_utils.h>
#include <midi++/port.h>
#include <midi++/manager.h>
@@ -54,6 +61,7 @@
#include <ardour/source_factory.h>
#include <ardour/control_protocol_manager.h>
#include <ardour/audioengine.h>
+#include <ardour/filesystem_paths.h>
#ifdef HAVE_LIBLO
#include <ardour/osc.h>
@@ -96,6 +104,8 @@ apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
+sigc::signal<void,std::string> ARDOUR::BootMessage;
+
#ifdef HAVE_LIBLO
static int
setup_osc ()
@@ -107,6 +117,7 @@ setup_osc ()
osc = new OSC (Config->get_osc_port());
if (Config->get_use_osc ()) {
+ BootMessage (_("Starting OSC"));
return osc->start ();
} else {
return 0;
@@ -122,6 +133,8 @@ setup_midi ()
return 0;
}
+ BootMessage (_("Configuring MIDI ports"));
+
for (std::map<string,XMLNode>::iterator i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
MIDI::Manager::instance()->add_port (i->second);
}
@@ -253,6 +266,33 @@ setup_hardware_optimization (bool try_optimization)
}
}
+static void
+lotsa_files_please ()
+{
+ struct rlimit rl;
+
+ if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
+
+ rl.rlim_cur = rl.rlim_max;
+
+ if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
+ if (rl.rlim_cur == RLIM_INFINITY) {
+ error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
+ } else {
+ error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
+ }
+ } else {
+ if (rl.rlim_cur == RLIM_INFINITY) {
+ info << _("Removed open file count limit. Excellent!") << endmsg;
+ } else {
+ info << string_compose (_("Ardour will be limited to %1 open files"), rl.rlim_cur) << endmsg;
+ }
+ }
+ } else {
+ error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
+ }
+}
+
int
ARDOUR::init (bool use_vst, bool try_optimization)
{
@@ -262,9 +302,14 @@ ARDOUR::init (bool use_vst, bool try_optimization)
setup_enum_writer ();
+ // allow ardour the absolute maximum number of open files
+ lotsa_files_please ();
+
lrdf_init();
Library = new AudioLibrary;
+ BootMessage (_("Loading configuration"));
+
Config = new Configuration;
if (Config->load_state ()) {
@@ -367,6 +412,34 @@ ARDOUR::get_ardour_revision ()
return "$Rev$";
}
+void
+ARDOUR::find_bindings_files (map<string,string>& files)
+{
+ vector<sys::path> found;
+
+ SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
+
+ if (getenv ("ARDOUR_SAE")) {
+ Glib::PatternSpec pattern("*SAE-*.bindings");
+ find_matching_files_in_search_path (spath, pattern, found);
+ } else {
+ Glib::PatternSpec pattern("*.bindings");
+ find_matching_files_in_search_path (spath, pattern, found);
+ }
+
+ if (found.empty()) {
+ return;
+ }
+
+ for (vector<sys::path>::iterator x = found.begin(); x != found.end(); ++x) {
+ sys::path path = *x;
+ pair<string,string> namepath;
+ namepath.second = path.to_string();
+ namepath.first = path.leaf().substr (0, path.leaf().find_first_of ('.'));
+ files.insert (namepath);
+ }
+}
+
ARDOUR::LocaleGuard::LocaleGuard (const char* str)
{
old = strdup (setlocale (LC_NUMERIC, NULL));
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 91e5b9850c..2bc3a00a7a 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -46,6 +46,7 @@
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
#include <ardour/resampled_source.h>
+#include <ardour/analyser.h>
#include "i18n.h"
@@ -65,7 +66,7 @@ open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQua
}
static std::string
-get_non_existent_filename (const std::string& basename, uint channel, uint channels)
+get_non_existent_filename (const bool allow_replacing, const std::string destdir, const std::string& basename, uint channel, uint channels)
{
char buf[PATH_MAX+1];
bool goodfile = false;
@@ -84,7 +85,9 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann
snprintf (buf, sizeof(buf), "%s.wav", base.c_str());
}
- if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
+
+ string tempname = destdir + "/" + buf;
+ if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
/* if the file already exists, we must come up with
* a new name for it. for now we just keep appending
@@ -104,7 +107,7 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann
}
static vector<string>
-get_paths_for_new_sources (const string& import_file_path, const string& session_dir, uint channels)
+get_paths_for_new_sources (const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
{
vector<string> new_paths;
const string basename = basename_nosuffix (import_file_path);
@@ -115,7 +118,7 @@ get_paths_for_new_sources (const string& import_file_path, const string& session
filepath = session_dir;
filepath += '/';
- filepath += get_non_existent_filename (basename, n, channels);
+ filepath += get_non_existent_filename (allow_replacing, session_dir, basename, n, channels);
new_paths.push_back (filepath);
}
@@ -124,6 +127,25 @@ get_paths_for_new_sources (const string& import_file_path, const string& session
}
static bool
+map_existing_mono_sources (const vector<string>& new_paths, Session& sess,
+ uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles, Session *session)
+{
+ for (vector<string>::const_iterator i = new_paths.begin();
+ i != new_paths.end(); ++i)
+ {
+ boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
+
+ if (source == 0) {
+ error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
+ return false;
+ }
+
+ newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source));
+ }
+ return true;
+}
+
+static bool
create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles)
{
@@ -228,6 +250,10 @@ remove_file_source (boost::shared_ptr<AudioFileSource> file_source)
::unlink (file_source->path().c_str());
}
+// This function is still unable to cleanly update an existing source, even though
+// it is possible to set the import_status flag accordingly. The functinality
+// is disabled at the GUI until the Source implementations are able to provide
+// the necessary API.
void
Session::import_audiofiles (import_status& status)
{
@@ -254,13 +280,19 @@ Session::import_audiofiles (import_status& status)
return;
}
- vector<string> new_paths = get_paths_for_new_sources (*p,
+ vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source,
+ *p,
get_best_session_directory_for_new_source (),
source->channels());
AudioSources newfiles;
- status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+ if (status.replace_existing_source) {
+ fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
+ status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
+ } else {
+ status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+ }
// copy on cancel/failure so that any files that were created will be removed below
std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
@@ -286,11 +318,14 @@ Session::import_audiofiles (import_status& status)
/* flush the final length(s) to the header(s) */
- for (AudioSources::iterator x = all_new_sources.begin();
- x != all_new_sources.end(); ++x)
+ for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x)
{
(*x)->update_header(0, *now, xnow);
(*x)->done_with_peakfile_writes ();
+
+ /* now that there is data there, requeue the file for analysis */
+
+ Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
}
/* save state so that we don't lose these new Sources */
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index babf1e451f..f57d5b39de 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -32,6 +32,7 @@
#include <ardour/audioengine.h>
#include <ardour/io.h>
+#include <ardour/route.h>
#include <ardour/port.h>
#include <ardour/audio_port.h>
#include <ardour/midi_port.h>
@@ -1800,14 +1801,22 @@ IO::parse_gain_string (const string& str, vector<string>& ports)
}
bool
-IO::set_name (const string& str)
+IO::set_name (const string& requested_name)
{
- if (str == _name) {
+ if (requested_name == _name) {
return true;
}
+ string name;
+ Route *rt;
+ if ( (rt = dynamic_cast<Route *>(this))) {
+ name = Route::ensure_track_or_route_name(requested_name, _session);
+ } else {
+ name = requested_name;
+ }
+
+
/* replace all colons in the name. i wish we didn't have to do this */
- string name = str;
if (replace_all (name, ":", "-")) {
warning << _("you cannot use colons to name objects with I/O connections") << endmsg;
@@ -2224,13 +2233,16 @@ IO::end_pan_touch (uint32_t which)
}
void
-IO::automation_snapshot (nframes_t now)
+IO::automation_snapshot (nframes_t now, bool force)
{
- Automatable::automation_snapshot (now);
+ Automatable::automation_snapshot (now, force);
if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
_panner->snapshot (now);
}
+
+ _panner->snapshot (now);
+ _last_automation_snapshot = now;
}
void
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index da3a812123..65279499ec 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1814,50 +1814,12 @@ Playlist::bump_name (string name, Session &session)
string newname = name;
do {
- newname = Playlist::bump_name_once (newname);
+ newname = bump_name_once (newname);
} while (session.playlist_by_name (newname)!=NULL);
return newname;
}
-string
-Playlist::bump_name_once (string name)
-{
- string::size_type period;
- string newname;
-
- if ((period = name.find_last_of ('.')) == string::npos) {
- newname = name;
- newname += ".1";
- } else {
- int isnumber = 1;
- const char *last_element = name.c_str() + period + 1;
- for (size_t i = 0; i < strlen(last_element); i++) {
- if (!isdigit(last_element[i])) {
- isnumber = 0;
- break;
- }
- }
-
- errno = 0;
- long int version = strtol (name.c_str()+period+1, (char **)NULL, 10);
-
- if (isnumber == 0 || errno != 0) {
- // last_element is not a number, or is too large
- newname = name;
- newname += ".1";
- } else {
- char buf[32];
-
- snprintf (buf, sizeof(buf), "%ld", version+1);
-
- newname = name.substr (0, period+1);
- newname += buf;
- }
- }
-
- return newname;
-}
layer_t
Playlist::top_layer() const
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 95629f2561..3d218448dd 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -224,6 +224,19 @@ ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
return (*i)->load (session);
}
}
+
+#ifdef VST_SUPPORT
+ /* hmm, we didn't find it. could be because in older versions of Ardour.
+ we used to store the name of a VST plugin, not its unique ID. so try
+ again.
+ */
+
+ for (i = plugs.begin(); i != plugs.end(); ++i) {
+ if (identifier == (*i)->name){
+ return (*i)->load (session);
+ }
+ }
+#endif
return PluginPtr ((Plugin*) 0);
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 2193a69908..508f09a480 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -957,14 +957,14 @@ Region::adjust_to_sync (nframes_t pos)
// cerr << "adjusting pos = " << pos << " to sync at " << _sync_position << " offset = " << offset << " with dir = " << sync_dir << endl;
if (sync_dir > 0) {
- if (max_frames - pos > offset) {
+ if (pos > offset) {
pos -= offset;
+ } else {
+ pos = 0;
}
} else {
- if (pos > offset) {
+ if (max_frames - pos > offset) {
pos += offset;
- } else {
- pos = 0;
}
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index fd0d99e87a..560946d9da 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -46,6 +46,9 @@
#include <ardour/amp.h>
#include <ardour/meter.h>
#include <ardour/buffer_set.h>
+#include <ardour/mix.h>
+#include <ardour/profile.h>
+
#include "i18n.h"
using namespace std;
@@ -190,6 +193,20 @@ Route::sync_order_keys ()
}
}
+string
+Route::ensure_track_or_route_name(string name, Session &session)
+{
+ string newname = name;
+
+ while (session.route_by_name (newname)!=NULL)
+ {
+ newname = bump_name_once (newname);
+ }
+
+ return newname;
+}
+
+
void
Route::inc_gain (gain_t fraction, void *src)
{
@@ -843,8 +860,8 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
reset_panner ();
}
-
processors_changed (); /* EMIT SIGNAL */
+
return 0;
}
@@ -2291,7 +2308,7 @@ Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_f
Glib::RWLock::ReaderLock lm (_processor_lock);
if (!did_locate) {
- automation_snapshot (now);
+ automation_snapshot (now, true);
}
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
@@ -2398,7 +2415,7 @@ Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nfra
if (lm.locked()) {
// automation snapshot can also be called from the non-rt context
// and it uses the processor list, so we take the lock out here
- automation_snapshot (_session.transport_frame());
+ automation_snapshot (_session.transport_frame(), false);
}
}
@@ -2569,12 +2586,15 @@ Route::set_latency_delay (nframes_t longest_session_latency)
}
void
-Route::automation_snapshot (nframes_t now)
+Route::automation_snapshot (nframes_t now, bool force)
{
- IO::automation_snapshot (now);
+ if (!force && !should_snapshot(now)) {
+ return;
+ }
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
- (*i)->automation_snapshot (now);
+ // IO::automation_snapshot (now, force); ?
+ (*i)->automation_snapshot (now, force);
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 5a3144b828..4cfcda992e 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -504,9 +504,13 @@ Session::when_engine_running ()
/* we don't want to run execute this again */
+ BootMessage (_("Set block size and sample rate"));
+
set_block_size (_engine.frames_per_cycle());
set_frame_rate (_engine.frame_rate());
+ BootMessage (_("Using configuration"));
+
Config->map_parameters (mem_fun (*this, &Session::config_changed));
/* every time we reconnect, recompute worst case output latencies */
@@ -562,6 +566,8 @@ Session::when_engine_running ()
error << _("cannot setup Click I/O") << endmsg;
}
+ BootMessage (_("Compute I/O Latencies"));
+
set_worst_io_latencies ();
if (_clicking) {
@@ -572,6 +578,8 @@ Session::when_engine_running ()
to the physical outputs currently available
*/
+ BootMessage (_("Set up standard connections"));
+
/* ONE: MONO */
for (uint32_t np = 0; np < n_physical_outputs; ++np) {
@@ -672,11 +680,15 @@ Session::when_engine_running ()
}
add_bundle (c);
}
+
+ BootMessage (_("Connect ports"));
hookup_io ();
/* catch up on send+insert cnts */
+ BootMessage (_("Catch up with send/insert state"));
+
insert_cnt = 0;
for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
@@ -704,14 +716,17 @@ Session::when_engine_running ()
_state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
-
/* hook us up to the engine */
+ BootMessage (_("Connect to engine"));
+
_engine.set_session (this);
#ifdef HAVE_LIBLO
/* and to OSC */
+ BootMessage (_("OSC startup"));
+
osc->set_session (*this);
#endif
@@ -2546,41 +2561,54 @@ Session::region_name (string& result, string base, bool newlevel) const
void
Session::add_region (boost::shared_ptr<Region> region)
{
+ vector<boost::shared_ptr<Region> > v;
+ v.push_back (region);
+ add_regions (v);
+}
+
+void
+Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
+{
bool added = false;
{
Glib::Mutex::Lock lm (region_lock);
- if (region == 0) {
- error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
- } else {
-
- RegionList::iterator x;
-
- for (x = regions.begin(); x != regions.end(); ++x) {
-
- if (region->region_list_equivalent (x->second)) {
- break;
- }
- }
-
- if (x == regions.end()) {
-
- pair<RegionList::key_type,RegionList::mapped_type> entry;
-
- entry.first = region->id();
- entry.second = region;
+ for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
+
+ boost::shared_ptr<Region> region = *ii;
+
+ if (region == 0) {
- pair<RegionList::iterator,bool> x = regions.insert (entry);
+ error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
+ } else {
- if (!x.second) {
- return;
+ RegionList::iterator x;
+
+ for (x = regions.begin(); x != regions.end(); ++x) {
+
+ if (region->region_list_equivalent (x->second)) {
+ break;
+ }
}
-
- added = true;
- }
-
+
+ if (x == regions.end()) {
+
+ pair<RegionList::key_type,RegionList::mapped_type> entry;
+
+ entry.first = region->id();
+ entry.second = region;
+
+ pair<RegionList::iterator,bool> x = regions.insert (entry);
+
+ if (!x.second) {
+ return;
+ }
+
+ added = true;
+ }
+ }
}
}
@@ -2591,9 +2619,33 @@ Session::add_region (boost::shared_ptr<Region> region)
set_dirty();
if (added) {
- region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
- region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
- RegionAdded (region); /* EMIT SIGNAL */
+
+ vector<boost::weak_ptr<Region> > v;
+ boost::shared_ptr<Region> first_r;
+
+ for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
+
+ boost::shared_ptr<Region> region = *ii;
+
+ if (region == 0) {
+
+ error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
+
+ } else {
+ v.push_back (region);
+
+ if (!first_r) {
+ first_r = region;
+ }
+ }
+
+ region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
+ region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
+ }
+
+ if (!v.empty()) {
+ RegionsAdded (v); /* EMIT SIGNAL */
+ }
}
}
@@ -2680,18 +2732,12 @@ Session::destroy_region (boost::shared_ptr<Region> region)
vector<boost::shared_ptr<Source> > srcs;
{
- boost::shared_ptr<AudioRegion> aregion;
-
- if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
- return 0;
- }
-
- if (aregion->playlist()) {
- aregion->playlist()->destroy_region (region);
+ if (region->playlist()) {
+ region->playlist()->destroy_region (region);
}
- for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
- srcs.push_back (aregion->source (n));
+ for (uint32_t n = 0; n < region->n_channels(); ++n) {
+ srcs.push_back (region->source (n));
}
}
@@ -2699,17 +2745,10 @@ Session::destroy_region (boost::shared_ptr<Region> region)
for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
- if (!(*i)->used()) {
- boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
-
- if (afs) {
- (afs)->mark_for_remove ();
- }
-
+ (*i)->mark_for_remove ();
(*i)->drop_references ();
cerr << "source was not used by any playlist\n";
- }
}
return 0;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index af4be07dc4..c4448640fd 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -350,11 +350,15 @@ Session::second_stage_init (bool new_session)
return -1;
}
+ BootMessage (_("Reset Remote Controls"));
+
//send_full_time_code ();
_engine.transport_locate (0);
deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
+ BootMessage (_("Reset Control Protocols"));
+
ControlProtocolManager::instance().set_session (*this);
if (new_session) {
@@ -364,7 +368,6 @@ Session::second_stage_init (bool new_session)
}
_state_of_the_state = Clean;
-
DirtyChanged (); /* EMIT SIGNAL */
@@ -374,6 +377,8 @@ Session::second_stage_init (bool new_session)
state_was_pending = false;
}
+ BootMessage (_("Session loading complete"));
+
return 0;
}
@@ -1373,6 +1378,8 @@ Session::load_routes (const XMLNode& node)
return -1;
}
+ BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
+
new_routes.push_back (route);
}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index d422698f30..e6318f5503 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -1267,9 +1267,9 @@ Session::engine_halted ()
void
Session::xrun_recovery ()
{
- if (Config->get_stop_recording_on_xrun() && actively_recording()) {
+ Xrun (transport_frame()); //EMIT SIGNAL
- HaltOnXrun (); /* EMIT SIGNAL */
+ if (Config->get_stop_recording_on_xrun() && actively_recording()) {
/* it didn't actually halt, but we need
to handle things in the same way.
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 7941eb693b..f08d08b86e 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -195,6 +195,7 @@ Source::set_been_analysed (bool yn)
}
if (yn) {
+ load_transients (get_transients_path());
AnalysisChanged(); // EMIT SIGNAL
}
}
@@ -265,3 +266,4 @@ Source::check_for_analysis_data_on_disk ()
set_been_analysed (ok);
return ok;
}
+
diff --git a/libs/ardour/transient_detector.cc b/libs/ardour/transient_detector.cc
index b92bf5fb2d..d24c4c9442 100644
--- a/libs/ardour/transient_detector.cc
+++ b/libs/ardour/transient_detector.cc
@@ -6,18 +6,20 @@ using namespace Vamp;
using namespace ARDOUR;
using namespace std;
-string TransientDetector::_op_id;
+/* need a static initializer function for this */
+
+string TransientDetector::_op_id = X_("libardourvampplugins:percussiononsets:2");
TransientDetector::TransientDetector (float sr)
: AudioAnalyser (sr, X_("libardourvampplugins:percussiononsets"))
{
- if (_op_id.empty()) {
- _op_id = X_("libardourvampplugins:percussiononsets");
-
- // XXX this should load the above-named plugin and get the current version
+ /* update the op_id */
- _op_id += ":2";
- }
+ _op_id = X_("libardourvampplugins:percussiononsets");
+
+ // XXX this should load the above-named plugin and get the current version
+
+ _op_id += ":2";
}
TransientDetector::~TransientDetector()
diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc
index cfd38c5099..99a6dbbc88 100644
--- a/libs/ardour/utils.cc
+++ b/libs/ardour/utils.cc
@@ -86,6 +86,45 @@ legalize_for_path (string str)
}
#endif
+string bump_name_once(std::string name)
+{
+ string::size_type period;
+ string newname;
+
+ if ((period = name.find_last_of ('.')) == string::npos) {
+ newname = name;
+ newname += ".1";
+ } else {
+ int isnumber = 1;
+ const char *last_element = name.c_str() + period + 1;
+ for (size_t i = 0; i < strlen(last_element); i++) {
+ if (!isdigit(last_element[i])) {
+ isnumber = 0;
+ break;
+ }
+ }
+
+ errno = 0;
+ long int version = strtol (name.c_str()+period+1, (char **)NULL, 10);
+
+ if (isnumber == 0 || errno != 0) {
+ // last_element is not a number, or is too large
+ newname = name;
+ newname += ".1";
+ } else {
+ char buf[32];
+
+ snprintf (buf, sizeof(buf), "%ld", version+1);
+
+ newname = name.substr (0, period+1);
+ newname += buf;
+ }
+ }
+
+ return newname;
+
+}
+
ostream&
operator<< (ostream& o, const BBT_Time& bbt)
{
@@ -289,6 +328,8 @@ string_to_edit_mode (string str)
return Splice;
} else if (str == _("Slide Edit")) {
return Slide;
+ } else if (str == _("Lock Edit")) {
+ return Lock;
}
fatal << string_compose (_("programming error: unknown edit mode string \"%1\""), str) << endmsg;
/*NOTREACHED*/
@@ -302,6 +343,9 @@ edit_mode_to_string (EditMode mode)
case Slide:
return _("Slide Edit");
+ case Lock:
+ return _("Lock Edit");
+
default:
case Splice:
return _("Splice Edit");