summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-09-10 15:03:30 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-09-10 15:03:30 +0000
commit68e943265edf04e63a8e8b8f62bab20f99d9c637 (patch)
treeff8941a59662fc0c4622944b65f7b2d5e3bdd0c3 /libs
parente4372df05b7d74a6b80dbbf4b6c00cc2b31c4723 (diff)
merge from 2.0-ongoing @ 3581
git-svn-id: svn://localhost/ardour2/branches/3.0@3711 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/appleutility/CAAudioUnit.cpp40
-rw-r--r--libs/appleutility/CAAudioUnit.h1
-rw-r--r--libs/appleutility/SConscript2
-rw-r--r--libs/ardour/SConscript5
-rw-r--r--libs/ardour/ardour/ardour.h9
-rw-r--r--libs/ardour/ardour/audio_track.h4
-rw-r--r--libs/ardour/ardour/audio_unit.h40
-rw-r--r--libs/ardour/ardour/audioengine.h49
-rw-r--r--libs/ardour/ardour/auto_bundle.h2
-rw-r--r--libs/ardour/ardour/buffer.h2
-rw-r--r--libs/ardour/ardour/bundle.h5
-rw-r--r--libs/ardour/ardour/configuration_vars.h2
-rw-r--r--libs/ardour/ardour/io.h1
-rw-r--r--libs/ardour/ardour/meter.h1
-rw-r--r--libs/ardour/ardour/midi_track.h4
-rw-r--r--libs/ardour/ardour/onset_detector.h56
-rw-r--r--libs/ardour/ardour/osc.h21
-rw-r--r--libs/ardour/ardour/plugin.h27
-rw-r--r--libs/ardour/ardour/plugin_insert.h7
-rw-r--r--libs/ardour/ardour/plugin_manager.h25
-rw-r--r--libs/ardour/ardour/port.h2
-rw-r--r--libs/ardour/ardour/port_insert.h5
-rw-r--r--libs/ardour/ardour/processor.h5
-rw-r--r--libs/ardour/ardour/route.h8
-rw-r--r--libs/ardour/ardour/send.h9
-rw-r--r--libs/ardour/ardour/session.h39
-rw-r--r--libs/ardour/ardour/track.h4
-rw-r--r--libs/ardour/ardour/user_bundle.h2
-rw-r--r--libs/ardour/audio_diskstream.cc6
-rw-r--r--libs/ardour/audio_library.cc2
-rw-r--r--libs/ardour/audio_track.cc15
-rw-r--r--libs/ardour/audio_unit.cc522
-rw-r--r--libs/ardour/audioengine.cc39
-rw-r--r--libs/ardour/audioregion.cc9
-rw-r--r--libs/ardour/audiosource.cc2
-rw-r--r--libs/ardour/auto_bundle.cc8
-rw-r--r--libs/ardour/configuration.cc1
-rw-r--r--libs/ardour/crossfade.cc1
-rw-r--r--libs/ardour/globals.cc15
-rw-r--r--libs/ardour/import.cc13
-rw-r--r--libs/ardour/io.cc209
-rw-r--r--libs/ardour/location.cc11
-rw-r--r--libs/ardour/lv2_plugin.cc1
-rw-r--r--libs/ardour/meter.cc7
-rw-r--r--libs/ardour/midi_track.cc14
-rw-r--r--libs/ardour/onset_detector.cc126
-rw-r--r--libs/ardour/osc.cc22
-rw-r--r--libs/ardour/panner.cc10
-rw-r--r--libs/ardour/plugin.cc19
-rw-r--r--libs/ardour/plugin_insert.cc127
-rw-r--r--libs/ardour/plugin_manager.cc123
-rw-r--r--libs/ardour/po/sv_SE.po4
-rw-r--r--libs/ardour/port_insert.cc40
-rw-r--r--libs/ardour/processor.cc13
-rw-r--r--libs/ardour/rb_effect.cc138
-rw-r--r--libs/ardour/recent_sessions.cc4
-rw-r--r--libs/ardour/region.cc2
-rw-r--r--libs/ardour/region_factory.cc8
-rw-r--r--libs/ardour/route.cc254
-rw-r--r--libs/ardour/send.cc41
-rw-r--r--libs/ardour/session.cc134
-rw-r--r--libs/ardour/session_butler.cc35
-rw-r--r--libs/ardour/session_command.cc2
-rw-r--r--libs/ardour/session_export.cc84
-rw-r--r--libs/ardour/session_process.cc24
-rw-r--r--libs/ardour/session_state.cc48
-rw-r--r--libs/ardour/session_transport.cc30
-rw-r--r--libs/ardour/sndfilesource.cc72
-rw-r--r--libs/ardour/source_factory.cc6
-rw-r--r--libs/ardour/track.cc5
-rw-r--r--libs/ardour/user_bundle.cc14
-rw-r--r--libs/ardour/utils.cc1
-rw-r--r--libs/ardour/vst_plugin.cc12
-rw-r--r--libs/cairomm/SConscript2
-rw-r--r--libs/clearlooks/SConscript2
-rw-r--r--libs/fst/SConscript2
-rw-r--r--libs/glibmm2/SConscript2
-rw-r--r--libs/glibmm2/glib/glibmmconfig.h4
-rw-r--r--libs/gtkmm2/atk/SConscript2
-rw-r--r--libs/gtkmm2/gdk/SConscript2
-rw-r--r--libs/gtkmm2/gtk/SConscript2
-rw-r--r--libs/gtkmm2/pango/SConscript2
-rw-r--r--libs/gtkmm2ext/SConscript4
-rw-r--r--libs/gtkmm2ext/barcontroller.cc2
-rw-r--r--libs/gtkmm2ext/binding_proxy.cc8
-rw-r--r--libs/gtkmm2ext/fastmeter.cc2
-rw-r--r--libs/gtkmm2ext/gtk_ui.cc1
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/barcontroller.h4
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/bindable_button.h13
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/binding_proxy.h9
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/gtk_ui.h2
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/hexentry.h58
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/pathlist.h63
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/slider_controller.h10
-rw-r--r--libs/gtkmm2ext/hexentry.cc111
-rw-r--r--libs/gtkmm2ext/pathlist.cc124
-rw-r--r--libs/gtkmm2ext/slider_controller.cc6
-rw-r--r--libs/libgnomecanvasmm/SConscript2
-rw-r--r--libs/libsndfile/SConscript2
-rw-r--r--libs/midi++2/SConscript2
-rw-r--r--libs/midi++2/midi.cc1
-rw-r--r--libs/pbd/SConscript2
-rw-r--r--libs/pbd/base_ui.cc9
-rw-r--r--libs/pbd/enumwriter.cc6
-rw-r--r--libs/pbd/fpu.cc2
-rw-r--r--libs/pbd/mountpoint.cc1
-rw-r--r--libs/pbd/pathscanner.cc1
-rw-r--r--libs/pbd/pbd/functor_command.h15
-rw-r--r--libs/pbd/pool.cc1
-rw-r--r--libs/pbd/stacktrace.cc2
-rw-r--r--libs/pbd/undo.cc2
-rw-r--r--libs/sigc++2/SConscript1
-rwxr-xr-xlibs/sigc++2/missing61
-rw-r--r--libs/soundtouch/AAFilter.cpp6
-rw-r--r--libs/soundtouch/FIFOSampleBuffer.cpp6
-rw-r--r--libs/soundtouch/FIFOSamplePipe.h4
-rw-r--r--libs/soundtouch/FIRFilter.cpp6
-rw-r--r--libs/soundtouch/RateTransposer.cpp8
-rw-r--r--libs/soundtouch/SConscript2
-rw-r--r--libs/soundtouch/TDStretch.cpp10
-rw-r--r--libs/surfaces/control_protocol/SConscript3
-rw-r--r--libs/surfaces/control_protocol/basic_ui.cc13
-rw-r--r--libs/surfaces/control_protocol/control_protocol/basic_ui.h2
-rw-r--r--libs/surfaces/frontier/tranzport/SConscript2
-rw-r--r--libs/surfaces/generic_midi/SConscript2
-rw-r--r--libs/surfaces/mackie/SConscript2
-rw-r--r--libs/surfaces/powermate/SConscript2
-rw-r--r--libs/surfaces/powermate/powermate.cc6
-rw-r--r--libs/surfaces/tranzport/SConscript2
-rw-r--r--libs/surfaces/tranzport/screen.cc1
-rw-r--r--libs/vamp-plugins/Onset.cpp280
-rw-r--r--libs/vamp-plugins/Onset.h73
-rw-r--r--libs/vamp-plugins/SConscript24
-rw-r--r--libs/vamp-plugins/plugins.cpp3
-rw-r--r--libs/vamp-sdk/SConscript2
-rw-r--r--libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp2
-rw-r--r--libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp2
137 files changed, 2519 insertions, 1141 deletions
diff --git a/libs/appleutility/CAAudioUnit.cpp b/libs/appleutility/CAAudioUnit.cpp
index 9244877d29..aaf57f233d 100644
--- a/libs/appleutility/CAAudioUnit.cpp
+++ b/libs/appleutility/CAAudioUnit.cpp
@@ -328,6 +328,46 @@ bool CAAudioUnit::CanDo ( int inChannelsIn,
return ValidateChannelPair (inChannelsIn, inChannelsOut, info.mChanInfo, (dataSize / sizeof (AUChannelInfo)));
}
+int CAAudioUnit::GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt)
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+
+ if (result)
+ {
+ if (Comp().Desc().IsEffect())
+ {
+ return 1;
+ }
+ else
+ {
+ // the au should either really tell us about this
+ // or we will assume the worst
+ return -1;
+ }
+ }
+
+ *chaninfo = (AUChannelInfo*) malloc (dataSize);
+ cnt = dataSize / sizeof (AUChannelInfo);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ *chaninfo, &dataSize);
+
+ if (result) { return -1; }
+ return 0;
+}
+
+
bool CAAudioUnit::ValidateChannelPair (int inChannelsIn,
int inChannelsOut,
const AUChannelInfo * info,
diff --git a/libs/appleutility/CAAudioUnit.h b/libs/appleutility/CAAudioUnit.h
index 6bc31bf30b..810b81be2f 100644
--- a/libs/appleutility/CAAudioUnit.h
+++ b/libs/appleutility/CAAudioUnit.h
@@ -218,6 +218,7 @@ public:
bool HasChannelLayouts (AudioUnitScope inScope,
AudioUnitElement inEl) const;
+ int GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt);
bool GetChannelLayouts (AudioUnitScope inScope,
AudioUnitElement inEl,
ChannelTagVector &outChannelVector) const;
diff --git a/libs/appleutility/SConscript b/libs/appleutility/SConscript
index bddca04032..c4f65ec81e 100644
--- a/libs/appleutility/SConscript
+++ b/libs/appleutility/SConscript
@@ -7,7 +7,7 @@ import glob
appleutility_files = glob.glob('*.cpp')
Import('env install_prefix')
-appleutility = env.Copy()
+appleutility = env.Clone()
appleutility.Append(LINKFLAGS='-framework AudioToolbox')
appleutility.Append(LINKFLAGS='-framework AudioUnit')
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 44f4718384..ca6fc0553e 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-ardour = env.Copy()
+ardour = env.Clone()
#
# this defines the version number of libardour
@@ -95,6 +95,7 @@ mtc_slave.cc
midi_clock_slave.cc
named_selection.cc
note.cc
+onset_detector.cc
panner.cc
parameter.cc
pcm_utils.cc
@@ -357,7 +358,7 @@ env['BUILDERS']['SharedAsmObject'] = Builder (action = '$CXX -c -fPIC $SOURCE -o
always_sse_objects = []
-sse_env = ardour.Copy()
+sse_env = ardour.Clone()
sse_env.Append (CXXFLAGS="-msse")
if env['FPU_OPTIMIZATION']:
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h
index fecd0fcf4e..fd873f9a6f 100644
--- a/libs/ardour/ardour/ardour.h
+++ b/libs/ardour/ardour/ardour.h
@@ -32,6 +32,8 @@
#include <ardour/configuration.h>
#include <ardour/types.h>
+// #include <jack/jack.h> need this to inline jack_get_microseconds
+
namespace MIDI {
class MachineControl;
class Port;
@@ -57,7 +59,12 @@ namespace ARDOUR {
const layer_t max_layer = UCHAR_MAX;
microseconds_t get_microseconds ();
-
+/* {
+ JACK has exported this functionality for a long time now
+ but inlining this causes problems
+ return (microseconds_t) jack_get_time();
+ }
+*/
Change new_change ();
extern Change StartChanged;
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 3546545329..fe7dcb58ff 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -58,8 +58,8 @@ class AudioTrack : public Track
void freeze (InterThreadInfo&);
void unfreeze ();
- void bounce (InterThreadInfo&);
- void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+ boost::shared_ptr<Region> bounce (InterThreadInfo&);
+ boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
int set_state(const XMLNode& node);
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
index dc9a52d5d3..497954092f 100644
--- a/libs/ardour/ardour/audio_unit.h
+++ b/libs/ardour/ardour/audio_unit.h
@@ -100,11 +100,12 @@ class AUPlugin : public ARDOUR::Plugin
bool has_editor () const;
- bool fixed_io() const { return false; }
- int32_t can_support_input_configuration (int32_t in);
- int32_t compute_output_streams (int32_t nplugins);
- uint32_t output_streams() const;
- uint32_t input_streams() const;
+ bool reconfigurable_io() const { return true; }
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ int32_t count_for_configuration (const ChanCount& in, ChanCount out) const;
+ bool configure_io (ChanCount in, ChanCount& out);
+ ChanCount output_streams() const;
+ ChanCount input_streams() const;
boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
boost::shared_ptr<CAComponent> get_comp () const { return comp; }
@@ -118,18 +119,19 @@ class AUPlugin : public ARDOUR::Plugin
boost::shared_ptr<CAComponent> comp;
boost::shared_ptr<CAAudioUnit> unit;
- AudioStreamBasicDescription streamFormat;
bool initialized;
- int format_set;
+ int32_t input_channels;
+ int32_t output_channels;
+ std::vector<std::pair<int,int> > io_configs;
AudioBufferList* buffers;
UInt32 global_elements;
UInt32 output_elements;
UInt32 input_elements;
- int set_output_format ();
- int set_input_format ();
- int set_stream_format (int scope, uint32_t cnt);
+ int set_output_format (AudioStreamBasicDescription&);
+ int set_input_format (AudioStreamBasicDescription&);
+ int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
int _set_block_size (nframes_t nframes);
void discover_parameters ();
@@ -142,10 +144,15 @@ class AUPlugin : public ARDOUR::Plugin
std::vector<AUParameterDescriptor> descriptors;
void init ();
+
};
typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
+struct AUPluginCachedInfo {
+ std::vector<std::pair<int,int> > io_configs;
+};
+
class AUPluginInfo : public PluginInfo {
public:
AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
@@ -153,16 +160,29 @@ class AUPluginInfo : public PluginInfo {
PluginPtr load (Session& session);
+ AUPluginCachedInfo cache;
+
static PluginInfoList discover ();
static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker);
static std::string stringify_descriptor (const CAComponentDescription&);
+ static int load_cached_info ();
+
private:
boost::shared_ptr<CAComponentDescription> descriptor;
+ UInt32 version;
static void discover_music (PluginInfoList&);
static void discover_fx (PluginInfoList&);
static void discover_by_description (PluginInfoList&, CAComponentDescription&);
+ static Glib::ustring au_cache_path ();
+
+ typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
+ static CachedInfoMap cached_info;
+
+ static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
+ static void add_cached_info (const std::string&, AUPluginCachedInfo&);
+ static void save_cached_info ();
};
typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index e1d5e50cc2..89abc6669a 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -130,13 +130,13 @@ class AudioEngine : public sigc::trackable
const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
- uint32_t n_physical_outputs () const;
- uint32_t n_physical_inputs () const;
-
bool can_request_hardware_monitoring ();
- void get_physical_outputs (std::vector<std::string>&);
- void get_physical_inputs (std::vector<std::string>&);
+ uint32_t n_physical_outputs (DataType type) const;
+ uint32_t n_physical_inputs (DataType type) const;
+
+ void get_physical_outputs (DataType type, std::vector<std::string>&);
+ void get_physical_inputs (DataType type, std::vector<std::string>&);
std::string get_nth_physical_output (DataType type, uint32_t n) {
return get_nth_physical (type, n, JackPortIsInput);
@@ -152,7 +152,7 @@ class AudioEngine : public sigc::trackable
/** Caller may not delete the object pointed to by the return value
*/
- Port *get_port_by_name (const std::string& name, bool keep = true) const;
+ Port *get_port_by_name (const std::string& name, bool keep = true);
enum TransportState {
TransportStopped = JackTransportStopped,
@@ -204,27 +204,28 @@ class AudioEngine : public sigc::trackable
std::string make_port_name_non_relative (std::string);
private:
- ARDOUR::Session *session;
- jack_client_t *_jack;
- std::string jack_client_name;
- mutable Glib::Mutex _process_lock;
- Glib::Cond session_removed;
- bool session_remove_pending;
- bool _running;
- bool _has_run;
- nframes_t _buffer_size;
- nframes_t _frame_rate;
+ ARDOUR::Session* session;
+ jack_client_t* _jack;
+ std::string jack_client_name;
+ Glib::Mutex _process_lock;
+ Glib::Cond session_removed;
+ bool session_remove_pending;
+ bool _running;
+ bool _has_run;
+ nframes_t _buffer_size;
+ nframes_t _frame_rate;
/// number of frames between each check for changes in monitor input
- nframes_t monitor_check_interval;
+ nframes_t monitor_check_interval;
/// time of the last monitor check in frames
- nframes_t last_monitor_check;
+ nframes_t last_monitor_check;
/// the number of frames processed since start() was called
- nframes_t _processed_frames;
- bool _freewheeling;
- bool _freewheel_thread_registered;
- sigc::slot<int,nframes_t> freewheel_action;
- bool reconnect_on_halt;
- int _usecs_per_cycle;
+ nframes_t _processed_frames;
+ bool _freewheeling;
+ bool _freewheel_pending;
+ bool _freewheel_thread_registered;
+ sigc::slot<int,nframes_t> freewheel_action;
+ bool reconnect_on_halt;
+ int _usecs_per_cycle;
SerializedRCUManager<Ports> ports;
diff --git a/libs/ardour/ardour/auto_bundle.h b/libs/ardour/ardour/auto_bundle.h
index 685a083e8d..9df26a449b 100644
--- a/libs/ardour/ardour/auto_bundle.h
+++ b/libs/ardour/ardour/auto_bundle.h
@@ -32,7 +32,7 @@ class AutoBundle : public Bundle {
AutoBundle (bool i = true);
AutoBundle (std::string const &, bool i = true);
- uint32_t nchannels () const;
+ ChanCount nchannels () const;
const PortList& channel_ports (uint32_t) const;
void set_channels (uint32_t);
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
index fd94360226..72df6c7fd6 100644
--- a/libs/ardour/ardour/buffer.h
+++ b/libs/ardour/ardour/buffer.h
@@ -21,8 +21,10 @@
#include <cstdlib>
#include <cassert>
+#include <cstring>
#include <iostream>
#include <boost/utility.hpp>
+
#include <ardour/types.h>
#include <ardour/data_type.h>
#include <ardour/runtime_functions.h>
diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h
index ba92063b30..46ba13152e 100644
--- a/libs/ardour/ardour/bundle.h
+++ b/libs/ardour/ardour/bundle.h
@@ -22,7 +22,9 @@
#include <string>
#include <sigc++/signal.h>
+
#include "ardour/data_type.h"
+#include "ardour/chan_count.h"
namespace ARDOUR {
@@ -37,12 +39,13 @@ class Bundle {
Bundle () : _type (DataType::AUDIO) {}
Bundle (bool i) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
+
virtual ~Bundle() {}
/**
* @return Number of channels that this Bundle has.
*/
- virtual uint32_t nchannels () const = 0;
+ virtual ChanCount nchannels () const = 0;
virtual const PortList& channel_ports (uint32_t) const = 0;
void set_name (std::string const & n) {
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
index 7a7a2ce419..1f455dc308 100644
--- a/libs/ardour/ardour/configuration_vars.h
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -124,6 +124,7 @@ CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true)
CONFIG_VARIABLE (bool, primary_clock_delta_edit_cursor, "primary-clock-delta-edit-cursor", false)
CONFIG_VARIABLE (bool, secondary_clock_delta_edit_cursor, "secondary-clock-delta-edit-cursor", false)
CONFIG_VARIABLE (bool, show_track_meters, "show-track-meters", true)
+CONFIG_VARIABLE (bool, locate_while_waiting_for_sync, "locate-while-waiting-for-sync", false)
/* timecode and sync */
@@ -159,6 +160,7 @@ CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", tru
CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
+CONFIG_VARIABLE (bool, name_new_markers, "name-new-markers", false)
CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
CONFIG_VARIABLE (long, font_scale, "font-scale", 102400)
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 83b6378dae..b44e131d8a 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -368,6 +368,7 @@ class IO : public Automatable, public Latent
int create_ports (const XMLNode&);
int make_connections (const XMLNode&);
+ boost::shared_ptr<Bundle> find_possible_bundle (const string &desired_name, const string &default_name, const string &connection_type_name);
void setup_peak_meters ();
void meter ();
diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h
index e19c0a51ca..112f306ccb 100644
--- a/libs/ardour/ardour/meter.h
+++ b/libs/ardour/ardour/meter.h
@@ -40,6 +40,7 @@ public:
void reset ();
void reset_max ();
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
bool configure_io (ChanCount in, ChanCount out);
/** Compute peaks */
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index 500502ac4b..6e4677df22 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -65,8 +65,8 @@ public:
void freeze (InterThreadInfo&);
void unfreeze ();
- void bounce (InterThreadInfo&);
- void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+ boost::shared_ptr<Region> bounce (InterThreadInfo&);
+ boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
int set_state(const XMLNode& node);
diff --git a/libs/ardour/ardour/onset_detector.h b/libs/ardour/ardour/onset_detector.h
new file mode 100644
index 0000000000..9243653d94
--- /dev/null
+++ b/libs/ardour/ardour/onset_detector.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2008 Paul Davis
+
+ 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.
+
+*/
+
+#ifndef __ardour_onset_detector_h__
+#define __ardour_onset_detector_h__
+
+#include <ardour/audioanalyser.h>
+
+namespace ARDOUR {
+
+class AudioSource;
+class Session;
+
+class OnsetDetector : public AudioAnalyser
+{
+
+ public:
+ OnsetDetector (float sample_rate);
+ ~OnsetDetector();
+
+ static std::string operational_identifier();
+
+ void set_silence_threshold (float);
+ void set_peak_threshold (float);
+ void set_function (int);
+
+ int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
+
+ static void cleanup_onsets (AnalysisFeatureList&, float sr, float gap_msecs);
+
+ protected:
+ AnalysisFeatureList* current_results;
+ int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
+
+ static std::string _op_id;
+};
+
+} /* namespace */
+
+#endif /* __ardour_audioanalyser_h__ */
diff --git a/libs/ardour/ardour/osc.h b/libs/ardour/ardour/osc.h
index 3f1ce03445..d7c2f4bd85 100644
--- a/libs/ardour/ardour/osc.h
+++ b/libs/ardour/ardour/osc.h
@@ -54,12 +54,13 @@ class OSC : public BasicUI, public sigc::trackable
lo_server _osc_server;
lo_server _osc_unix_server;
std::string _osc_unix_socket_path;
- std::string _osc_url_file;
+ std::string _osc_url_file;
pthread_t _osc_thread;
int _request_pipe[2];
static void * _osc_receiver(void * arg);
void osc_receiver();
+ void send(); // This should accept an OSC payload
bool init_osc_thread ();
void terminate_osc_thread ();
@@ -69,6 +70,11 @@ class OSC : public BasicUI, public sigc::trackable
void session_going_away ();
+ // Handlers for "Application Hook" signals
+ void session_loaded( ARDOUR::Session& );
+ void session_exported( std::string, std::string );
+ // end "Application Hook" handles
+
std::string get_server_url ();
std::string get_unix_server_url ();
@@ -101,18 +107,19 @@ class OSC : public BasicUI, public sigc::trackable
PATH_CALLBACK(rec_enable_toggle);
PATH_CALLBACK(toggle_all_rec_enables);
-#define PATH_CALLBACK1(name,type) \
+#define PATH_CALLBACK1(name,type,optional) \
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
} \
int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \
- if (argc > 0) { \
- name (argv[0]->type); \
- }\
- return 0; \
+ if (argc > 0) { \
+ name (optional argv[0]->type); \
+ } \
+ return 0; \
}
- PATH_CALLBACK1(set_transport_speed,f);
+ PATH_CALLBACK1(set_transport_speed,f,);
+ PATH_CALLBACK1(access_action,s,&);
};
}
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index 73f89f1a91..fec044e885 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -145,6 +145,33 @@ class Plugin : public PBD::StatefulDestructible, public Latent
virtual bool has_editor() const = 0;
+ sigc::signal<void,uint32_t,float> ParameterChanged;
+
+ /* NOTE: this block of virtual methods looks like the interface
+ to a Processor, but Plugin does not inherit from Processor.
+ It is therefore not required that these precisely match
+ the interface, but it is likely that they will evolve together.
+ */
+
+ /* this returns true if the plugin can change its inputs or outputs on demand.
+ LADSPA, LV2 and VST plugins cannot do this. AudioUnits can.
+ */
+
+ virtual bool reconfigurable_io() const { return false; }
+
+ /* this is only called if reconfigurable_io() returns true */
+ virtual bool configure_io (ChanCount in, ChanCount out) { return true; }
+
+ /* specific types of plugins can overload this. As of September 2008, only
+ AUPlugin does this.
+ */
+ virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return false; }
+ virtual ChanCount output_streams() const;
+ virtual ChanCount input_streams() const;
+
+ PBD::Controllable *get_nth_control (uint32_t, bool do_not_create = false);
+ void make_nth_control (uint32_t, const XMLNode&);
+
PluginInfoPtr get_info() { return _info; }
void set_info (const PluginInfoPtr inf) { _info = inf; }
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
index 42c53c487c..c19d113256 100644
--- a/libs/ardour/ardour/plugin_insert.h
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -69,13 +69,12 @@ class PluginInsert : public Processor
bool set_count (uint32_t num);
uint32_t get_count () const { return _plugins.size(); }
- virtual bool can_support_input_configuration (ChanCount in) const;
- virtual ChanCount output_for_input_configuration (ChanCount in) const;
- virtual bool configure_io (ChanCount in, ChanCount out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool configure_io (ChanCount in, ChanCount out);
bool is_generator() const;
- void set_parameter (Parameter param, float val);
+ void set_parameter (Parameter param, float val);
float get_parameter (Parameter param);
float default_parameter_value (Parameter param);
diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h
index 892c8bd75a..858decd0e5 100644
--- a/libs/ardour/ardour/plugin_manager.h
+++ b/libs/ardour/ardour/plugin_manager.h
@@ -23,6 +23,7 @@
#include <list>
#include <map>
#include <string>
+#include <set>
#include <ardour/types.h>
#include <ardour/plugin.h>
@@ -54,7 +55,31 @@ class PluginManager {
static PluginManager* the_manager() { return _manager; }
+ void load_favorites ();
+ void save_favorites ();
+ void add_favorite (ARDOUR::PluginType type, std::string unique_id);
+ void remove_favorite (ARDOUR::PluginType type, std::string unique_id);
+ bool is_a_favorite_plugin (const PluginInfoPtr&);
+
private:
+ struct FavoritePlugin {
+ ARDOUR::PluginType type;
+ std::string unique_id;
+
+ FavoritePlugin (ARDOUR::PluginType t, std::string id)
+ : type (t), unique_id (id) {}
+
+ bool operator==(const FavoritePlugin& other) const {
+ return other.type == type && other.unique_id == unique_id;
+ }
+
+ bool operator<(const FavoritePlugin& other) const {
+ return other.type < type || other.unique_id < unique_id;
+ }
+ };
+ typedef std::set<FavoritePlugin> FavoritePluginList;
+ FavoritePluginList favorites;
+
ARDOUR::PluginInfoList _vst_plugin_info;
ARDOUR::PluginInfoList _ladspa_plugin_info;
ARDOUR::PluginInfoList _lv2_plugin_info;
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
index 93c34da16d..084022541d 100644
--- a/libs/ardour/ardour/port.h
+++ b/libs/ardour/ardour/port.h
@@ -23,7 +23,7 @@
#include <set>
#include <vector>
#include <string>
-
+#include <cstring>
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h
index 1743040bf5..72f02ff9c7 100644
--- a/libs/ardour/ardour/port_insert.h
+++ b/libs/ardour/ardour/port_insert.h
@@ -58,9 +58,8 @@ class PortInsert : public IOProcessor
ChanCount output_streams() const;
ChanCount input_streams() const;
- virtual bool can_support_input_configuration (ChanCount in) const;
- virtual ChanCount output_for_input_configuration (ChanCount in) const;
- virtual bool configure_io (ChanCount in, ChanCount out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
+ bool configure_io (ChanCount in, ChanCount out);
uint32_t bit_slot() const { return bitslot; }
diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h
index d3e95e8ebf..8c4ac8dfe5 100644
--- a/libs/ardour/ardour/processor.h
+++ b/libs/ardour/ardour/processor.h
@@ -80,7 +80,7 @@ class Processor : public Automatable, public Latent
virtual void activate () { _active = true; ActiveChanged.emit(); }
virtual void deactivate () { _active = false; ActiveChanged.emit(); }
- virtual bool configure_io (ChanCount in, ChanCount out) { _configured_input = in; return (_configured = true); }
+ virtual bool configure_io (ChanCount in, ChanCount out);
/* Derived classes should override these, or processor appears as an in-place pass-through */
@@ -91,8 +91,7 @@ class Processor : public Automatable, public Latent
* and write to their output parameter */
virtual bool is_out_of_place () const { return false; }
- virtual bool can_support_input_configuration (ChanCount in) const { return true; }
- virtual ChanCount output_for_input_configuration (ChanCount in) const { return in; }
+ virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const = 0;
virtual ChanCount output_streams() const { return _configured_input; }
virtual ChanCount input_streams () const { return _configured_input; }
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index c7c0b77102..fb98cb57a7 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -359,8 +359,8 @@ class Route : public IO
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);
- int reset_plugin_counts (ProcessorStreams*); /* locked */
- int _reset_plugin_counts (ProcessorStreams*); /* unlocked */
+ int reset_processor_counts (ProcessorStreams*); /* locked */
+ int _reset_processor_counts (ProcessorStreams*); /* unlocked */
/* processor I/O channels and plugin count handling */
@@ -372,8 +372,8 @@ class Route : public IO
ProcessorCount (boost::shared_ptr<ARDOUR::Processor> ins) : processor(ins) {}
};
- int32_t apply_some_plugin_counts (std::list<ProcessorCount>& iclist);
- bool check_some_plugin_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
+ int32_t apply_some_processor_counts (std::list<ProcessorCount>& iclist);
+ bool check_some_processor_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
void set_deferred_state ();
void add_processor_from_xml (const XMLNode&);
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
index 1ee8bbceca..d5078bd7df 100644
--- a/libs/ardour/ardour/send.h
+++ b/libs/ardour/ardour/send.h
@@ -57,16 +57,17 @@ class Send : public IOProcessor
int set_state(const XMLNode& node);
uint32_t pans_required() const { return _configured_input.n_audio(); }
+ void expect_inputs (const ChanCount&);
- virtual bool can_support_input_configuration (ChanCount in) const;
- virtual ChanCount output_for_input_configuration (ChanCount in) const;
- virtual bool configure_io (ChanCount in, ChanCount out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool configure_io (ChanCount in, ChanCount out);
static uint32_t how_many_sends();
private:
bool _metering;
- uint32_t bitslot;
+ ChanCount expected_inputs;
+ uint32_t bitslot;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 00cbc9922e..08315c3010 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -434,15 +434,18 @@ class Session : public PBD::StatefulDestructible
nframes_t worst_input_latency () const { return _worst_input_latency; }
nframes_t worst_track_latency () const { return _worst_track_latency; }
- int save_state (string snapshot_name, bool pending = false);
- int restore_state (string snapshot_name);
- int save_template (string template_name);
- int save_history (string snapshot_name = "");
- int restore_history (string snapshot_name);
- void remove_state (string snapshot_name);
- void rename_state (string old_name, string new_name);
+ int save_state (std::string snapshot_name, bool pending = false);
+ int restore_state (std::string snapshot_name);
+ int save_template (std::string template_name);
+ int save_history (std::string snapshot_name = "");
+ int restore_history (std::string snapshot_name);
+ void remove_state (std::string snapshot_name);
+ void rename_state (std::string old_name, std::string new_name);
void remove_pending_capture_state ();
+ static int rename_template (std::string old_name, std::string new_name);
+ static int delete_template (std::string name);
+
sigc::signal<void,string> StateSaved;
sigc::signal<void> StateReady;
@@ -579,7 +582,7 @@ class Session : public PBD::StatefulDestructible
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;
+ int region_name (string& result, string base = string(""), bool newlevel = false);
string new_region_name (string);
string path_from_region_name (DataType type, string name, string identifier);
@@ -616,9 +619,11 @@ class Session : public PBD::StatefulDestructible
SlaveSource post_export_slave;
nframes_t post_export_position;
- int start_export (ARDOUR::ExportSpecification&);
- int stop_export (ARDOUR::ExportSpecification&);
- void finalize_audio_export ();
+ int pre_export ();
+ int start_export (ARDOUR::ExportSpecification&);
+ int stop_export (ARDOUR::ExportSpecification&);
+ void finalize_export ();
+ static sigc::signal<void, std::string, std::string> Exported;
void add_source (boost::shared_ptr<Source>);
void remove_source (boost::weak_ptr<Source>);
@@ -706,9 +711,8 @@ class Session : public PBD::StatefulDestructible
/* flattening stuff */
- int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite,
- vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot);
-
+ boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end, bool overwrite, vector<boost::shared_ptr<Source> >&,
+ InterThreadInfo& wot);
int freeze (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
@@ -910,7 +914,7 @@ class Session : public PBD::StatefulDestructible
void reset_playback_load_min ();
void reset_capture_load_min ();
- float read_data_rate () const;
+ float read_data_rate () const; // in usec
float write_data_rate () const;
/* ranges */
@@ -1072,6 +1076,7 @@ class Session : public PBD::StatefulDestructible
void set_slave_source (SlaveSource);
bool _exporting;
+
int prepare_to_export (ARDOUR::ExportSpecification&);
void prepare_diskstreams ();
@@ -1393,6 +1398,7 @@ class Session : public PBD::StatefulDestructible
void set_play_loop (bool yn);
void overwrite_some_buffers (Diskstream*);
void flush_all_inserts ();
+ int micro_locate (nframes_t distance);
void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void force_locate (nframes_t frame, bool with_roll = false);
@@ -1457,6 +1463,9 @@ class Session : public PBD::StatefulDestructible
/* REGION MANAGEMENT */
+ std::map<std::string,uint32_t> region_name_map;
+ void update_region_name_map (boost::shared_ptr<Region>);
+
mutable Glib::Mutex region_lock;
typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList;
RegionList regions;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 4d5545c0dc..fedd83ba68 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -76,8 +76,8 @@ class Track : public Route
virtual void freeze (InterThreadInfo&) = 0;
virtual void unfreeze () = 0;
- virtual void bounce (InterThreadInfo&) = 0;
- virtual void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
+ virtual boost::shared_ptr<Region> bounce (InterThreadInfo&) = 0;
+ virtual boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
XMLNode& get_state();
XMLNode& get_template();
diff --git a/libs/ardour/ardour/user_bundle.h b/libs/ardour/ardour/user_bundle.h
index 954e93d5d1..c33ddeaed9 100644
--- a/libs/ardour/ardour/user_bundle.h
+++ b/libs/ardour/ardour/user_bundle.h
@@ -35,7 +35,7 @@ class UserBundle : public Bundle, public PBD::Stateful {
UserBundle (std::string const &);
UserBundle (XMLNode const &, bool);
- uint32_t nchannels () const;
+ ChanCount nchannels () const;
const ARDOUR::PortList& channel_ports (uint32_t) const;
void add_channel ();
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 091e1df30f..2953c9e074 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -399,7 +399,7 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram
/* if per-track or global rec-enable turned on while the other was already on, we've started recording */
if (((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record)) ||
- (((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled())))) {
+ ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
/* starting to record: compute first+last frames */
@@ -524,7 +524,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
commit_should_unlock = false;
- if (!_io->active()) {
+ if (!_io || !_io->active()) {
_processed = true;
return 0;
}
@@ -835,7 +835,7 @@ AudioDiskstream::commit (nframes_t nframes)
{
bool need_butler = false;
- if (!_io->active()) {
+ if (!_io || !_io->active()) {
return false;
}
diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc
index a35846ab29..cd473d933f 100644
--- a/libs/ardour/audio_library.cc
+++ b/libs/ardour/audio_library.cc
@@ -22,6 +22,7 @@
#include <libxml/uri.h>
#include <lrdf.h>
+#include <glibmm/miscutils.h>
#include <glibmm/convert.h>
@@ -52,6 +53,7 @@ AudioLibrary::AudioLibrary ()
// workaround for possible bug in raptor that crashes when saving to a
// non-existant file.
+
touch_file(sfdb_file_path.to_string());
lrdf_read_file(src.c_str());
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 53f918ec4e..cd05e5fc86 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -743,21 +743,18 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
return 0;
}
-void
+boost::shared_ptr<Region>
AudioTrack::bounce (InterThreadInfo& itt)
{
vector<boost::shared_ptr<Source> > srcs;
- _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
- itt.done = true;
+ return _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), false, srcs, itt);
}
-
-void
+boost::shared_ptr<Region>
AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
{
vector<boost::shared_ptr<Source> > srcs;
- _session.write_one_audio_track (*this, start, end, false, srcs, itt);
- itt.done = true;
+ return _session.write_one_track (*this, start, end, false, srcs, itt);
}
void
@@ -798,7 +795,9 @@ AudioTrack::freeze (InterThreadInfo& itt)
return;
}
- if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) {
+ boost::shared_ptr<Region> res;
+
+ if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
return;
}
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index b941bc10bb..4862ddcd12 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -24,7 +24,10 @@
#include <pbd/whitespace.h>
#include <glibmm/thread.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+#include <ardour/ardour.h>
#include <ardour/audioengine.h>
#include <ardour/io.h>
#include <ardour/audio_unit.h>
@@ -43,6 +46,8 @@ using namespace std;
using namespace PBD;
using namespace ARDOUR;
+AUPluginInfo::CachedInfoMap AUPluginInfo::cached_info;
+
static OSStatus
_render_callback(void *userData,
AudioUnitRenderActionFlags *ioActionFlags,
@@ -120,28 +125,12 @@ AUPlugin::init ()
unit->GetElementCount (kAudioUnitScope_Input, input_elements);
unit->GetElementCount (kAudioUnitScope_Output, output_elements);
- // set up the basic stream format. these fields do not change
-
- streamFormat.mSampleRate = _session.frame_rate();
- streamFormat.mFormatID = kAudioFormatLinearPCM;
- streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
-
-#ifdef __LITTLE_ENDIAN__
- /* relax */
-#else
- streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
-#endif
-
- streamFormat.mBitsPerChannel = 32;
- streamFormat.mFramesPerPacket = 1;
-
- // subject to later modification as we discover channel counts
-
- streamFormat.mBytesPerPacket = 4;
- streamFormat.mBytesPerFrame = 4;
- streamFormat.mChannelsPerFrame = 1;
+ /* these keep track of *configured* channel set up,
+ not potential set ups.
+ */
- format_set = 0;
+ input_channels = -1;
+ output_channels = -1;
if (_set_block_size (_session.get_block_size())) {
error << _("AUPlugin: cannot set processing block size") << endmsg;
@@ -396,42 +385,233 @@ AUPlugin::_set_block_size (nframes_t nframes)
return 0;
}
-int32_t
-AUPlugin::can_support_input_configuration (int32_t in)
-{
- streamFormat.mChannelsPerFrame = in;
+int32_t
+AUPlugin::configure_io (ChanCount in, ChanCount out)
+{
+ AudioStreamBasicDescription streamFormat;
+
+ streamFormat.mSampleRate = _session.frame_rate();
+ streamFormat.mFormatID = kAudioFormatLinearPCM;
+ streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
+
+#ifdef __LITTLE_ENDIAN__
+ /* relax */
+#else
+ streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+
+ streamFormat.mBitsPerChannel = 32;
+ streamFormat.mFramesPerPacket = 1;
+
/* apple says that for non-interleaved data, these
values always refer to a single channel.
*/
streamFormat.mBytesPerPacket = 4;
streamFormat.mBytesPerFrame = 4;
- if (set_input_format () == 0) {
- return 1;
- } else {
+ streamFormat.mChannelsPerFrame = in.n_audio();
+
+ if (set_input_format (streamFormat) != 0) {
+ return -1;
+ }
+
+ streamFormat.mChannelsPerFrame = out.n_audio();
+
+ if (set_output_format (streamFormat) != 0) {
return -1;
}
+
+ return Plugin::configure_io (in, out);
+}
+
+bool
+AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
+{
+ int32_t ret = count_for_configuration (in, out);
+ return ret >= 0;
+}
+
+int32_t
+AUPlugin::count_for_configuration(ChanCount cin, ChanCount& out) const
+{
+ // XXX as of May 13th 2008, AU plugin support returns a count of either 1 or -1. We never
+ // attempt to multiply-instantiate plugins to meet io configurations.
+
+ int32_t plugcnt = -1;
+ AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
+ int32_t in = cin.n_audio(); /* XXX handle MIDI one day ??? */
+
+ vector<pair<int,int> >& io_configs = pinfo->cache.io_configs;
+
+ for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
+
+ int32_t possible_in = i->first;
+ int32_t possible_out = i->second;
+
+ if (possible_out == 0) {
+ warning << string_compose (_("AU %1 has zero outputs - configuration ignored"), name()) << endmsg;
+ continue;
+ }
+
+ if (possible_in == 0) {
+
+ /* instrument plugin, always legal but throws away inputs ...
+ */
+
+ if (possible_out == -1) {
+ /* out much match in (UNLIKELY!!) */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ /* any configuration possible, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in == -1) {
+
+ /* wildcard for input */
+
+ if (possible_out == -1) {
+ /* out much match in */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ /* any configuration possible, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in == -2) {
+
+ if (possible_out == -1) {
+ /* any configuration possible, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ error << string_compose (_("AU plugin %1 has illegal IO configuration (-2,-2)"), name())
+ << endmsg;
+ plugcnt = -1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in < -2) {
+
+ /* explicit variable number of inputs */
+
+ if (in > -possible_in) {
+ /* request is too large */
+ plugcnt = -1;
+ }
+
+ if (possible_out == -1) {
+ /* out must match in */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ error << string_compose (_("AU plugin %1 has illegal IO configuration (-2,-2)"), name())
+ << endmsg;
+ plugcnt = -1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in == in) {
+
+ /* exact number of inputs ... must match obviously */
+
+ if (possible_out == -1) {
+ /* out must match in */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ /* any output configuration, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = -1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ }
+
+ /* no fit */
+ return plugcnt;
}
int
-AUPlugin::set_input_format ()
+AUPlugin::set_input_format (AudioStreamBasicDescription& fmt)
{
- return set_stream_format (kAudioUnitScope_Input, input_elements);
+ return set_stream_format (kAudioUnitScope_Input, input_elements, fmt);
}
int
-AUPlugin::set_output_format ()
+AUPlugin::set_output_format (AudioStreamBasicDescription& fmt)
{
- return set_stream_format (kAudioUnitScope_Output, output_elements);
+ if (set_stream_format (kAudioUnitScope_Output, output_elements, fmt) != 0) {
+ return -1;
+ }
+
+ if (buffers) {
+ free (buffers);
+ buffers = 0;
+ }
+
+ buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) +
+ fmt.mChannelsPerFrame * sizeof(AudioBuffer));
+
+ Glib::Mutex::Lock em (_session.engine().process_lock());
+ IO::PortCountChanged (ChanCount (DataType::AUDIO, fmt.mChannelsPerFrame));
+
+ return 0;
}
int
-AUPlugin::set_stream_format (int scope, uint32_t cnt)
+AUPlugin::set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription& fmt)
{
OSErr result;
for (uint32_t i = 0; i < cnt; ++i) {
- if ((result = unit->SetFormat (scope, i, streamFormat)) != 0) {
+ if ((result = unit->SetFormat (scope, i, fmt)) != 0) {
error << string_compose (_("AUPlugin: could not set stream format for %1/%2 (err = %3)"),
(scope == kAudioUnitScope_Input ? "input" : "output"), i, result) << endmsg;
return -1;
@@ -439,60 +619,44 @@ AUPlugin::set_stream_format (int scope, uint32_t cnt)
}
if (scope == kAudioUnitScope_Input) {
- format_set |= 0x1;
+ input_channels = fmt.mChannelsPerFrame;
} else {
- format_set |= 0x2;
+ output_channels = fmt.mChannelsPerFrame;
}
return 0;
}
-int32_t
-AUPlugin::compute_output_streams (int32_t nplugins)
-{
- /* we will never replicate AU plugins - either they can do the I/O we need
- or not. thus, we can ignore nplugins entirely.
- */
-
- if (set_output_format() == 0) {
- if (buffers) {
- free (buffers);
- buffers = 0;
- }
-
- buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) +
- streamFormat.mChannelsPerFrame * sizeof(AudioBuffer));
-
- Glib::Mutex::Lock em (_session.engine().process_lock());
- IO::MoreOutputs (streamFormat.mChannelsPerFrame);
+ChanCount
+AUPlugin::input_streams() const
+{
+ ChanCount in;
- return streamFormat.mChannelsPerFrame;
+ if (input_channels < 0) {
+ warning << string_compose (_("AUPlugin: %1 input_streams() called without any format set!"), name()) << endmsg;
+ in.set_audio (1);
} else {
- return -1;
+ in.set_audio (input_channels);
}
+
+ return in;
}
-uint32_t
+
+ChanCount
AUPlugin::output_streams() const
{
- if (!(format_set & 0x2)) {
+ ChanCount out;
+
+ if (output_channels < 0) {
warning << string_compose (_("AUPlugin: %1 output_streams() called without any format set!"), name()) << endmsg;
- return 1;
+ out.set_audio (1);
+ } else {
+ out.set_audio (output_channels);
}
- return streamFormat.mChannelsPerFrame;
-}
-
-
-uint32_t
-AUPlugin::input_streams() const
-{
- if (!(format_set & 0x1)) {
- warning << _("AUPlugin: input_streams() called without any format set!") << endmsg;
- return 1;
- }
- return streamFormat.mChannelsPerFrame;
+ return out;
}
OSStatus
@@ -679,13 +843,25 @@ AUPluginInfo::load (Session& session)
}
catch (failed_constructor &err) {
- return PluginPtr ((Plugin*) 0);
+ return PluginPtr ();
}
}
+Glib::ustring
+AUPluginInfo::au_cache_path ()
+{
+ return Glib::build_filename (ARDOUR::get_user_ardour_path(), "au_cache");
+}
+
PluginInfoList
AUPluginInfo::discover ()
{
+ XMLTree tree;
+
+ if (!Glib::file_test (au_cache_path(), Glib::FILE_TEST_EXISTS)) {
+ ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)"));
+ }
+
PluginInfoList plugs;
discover_fx (plugs);
@@ -839,17 +1015,211 @@ AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescrip
info->type = ARDOUR::AudioUnit;
info->unique_id = stringify_descriptor (*info->descriptor);
- /* mark the plugin as having flexible i/o */
+ /* XXX not sure of the best way to handle plugin versioning yet
+ */
+
+ CAComponent cacomp (*info->descriptor);
+
+ if (cacomp.GetResourceVersion (info->version) != noErr) {
+ info->version = 0;
+ }
- info->n_inputs = -1;
- info->n_outputs = -1;
+ if (cached_io_configuration (info->unique_id, info->version, cacomp, info->cache, info->name)) {
+
+ /* here we have to map apple's wildcard system to a simple pair
+ of values.
+ */
+
+ info->n_inputs = ChanCount (DataType::AUDIO, info->cache.io_configs.front().first);
+ info->n_outputs = ChanCount (DataType::AUDIO, info->cache.io_configs.front().second);
+
+ if (info->cache.io_configs.size() > 1) {
+ cerr << "ODD: variable IO config for " << info->unique_id << endl;
+ }
+
+ plugs.push_back (info);
- plugs.push_back (info);
+ } else {
+ error << string_compose (_("Cannot get I/O configuration info for AU %1"), info->name) << endmsg;
+ }
comp = FindNextComponent (comp, &desc);
}
}
+bool
+AUPluginInfo::cached_io_configuration (const std::string& unique_id,
+ UInt32 version,
+ CAComponent& comp,
+ AUPluginCachedInfo& cinfo,
+ const std::string& name)
+{
+ std::string id;
+ char buf[32];
+
+ /* concatenate unique ID with version to provide a key for cached info lookup.
+ this ensures we don't get stale information, or should if plugin developers
+ follow Apple "guidelines".
+ */
+
+ snprintf (buf, sizeof (buf), "%u", version);
+ id = unique_id;
+ id += '/';
+ id += buf;
+
+ CachedInfoMap::iterator cim = cached_info.find (id);
+
+ if (cim != cached_info.end()) {
+ cinfo = cim->second;
+ return true;
+ }
+
+ CAAudioUnit unit;
+ AUChannelInfo* channel_info;
+ UInt32 cnt;
+ int ret;
+
+ ARDOUR::BootMessage (string_compose (_("Checking AudioUnit: %1"), name));
+
+ if (CAAudioUnit::Open (comp, unit) != noErr) {
+ return false;
+ }
+
+ if ((ret = unit.GetChannelInfo (&channel_info, cnt)) < 0) {
+ return false;
+ }
+
+ if (ret > 0) {
+ /* no explicit info available */
+
+ cinfo.io_configs.push_back (pair<int,int> (-1, -1));
+
+ } else {
+
+ /* store each configuration */
+
+ for (uint32_t n = 0; n < cnt; ++n) {
+ cinfo.io_configs.push_back (pair<int,int> (channel_info[n].inChannels,
+ channel_info[n].outChannels));
+ }
+
+ free (channel_info);
+ }
+
+ add_cached_info (id, cinfo);
+ save_cached_info ();
+
+ return true;
+}
+
+void
+AUPluginInfo::add_cached_info (const std::string& id, AUPluginCachedInfo& cinfo)
+{
+ cached_info[id] = cinfo;
+}
+
+void
+AUPluginInfo::save_cached_info ()
+{
+ XMLNode* node;
+
+ node = new XMLNode (X_("AudioUnitPluginCache"));
+
+ for (map<string,AUPluginCachedInfo>::iterator i = cached_info.begin(); i != cached_info.end(); ++i) {
+ XMLNode* parent = new XMLNode (X_("plugin"));
+ parent->add_property ("id", i->first);
+ node->add_child_nocopy (*parent);
+
+ for (vector<pair<int, int> >::iterator j = i->second.io_configs.begin(); j != i->second.io_configs.end(); ++j) {
+
+ XMLNode* child = new XMLNode (X_("io"));
+ char buf[32];
+
+ snprintf (buf, sizeof (buf), "%d", j->first);
+ child->add_property (X_("in"), buf);
+ snprintf (buf, sizeof (buf), "%d", j->second);
+ child->add_property (X_("out"), buf);
+ parent->add_child_nocopy (*child);
+ }
+
+ }
+
+ Glib::ustring path = au_cache_path ();
+ XMLTree tree;
+
+ tree.set_root (node);
+
+ if (!tree.write (path)) {
+ error << string_compose (_("could not save AU cache to %1"), path) << endmsg;
+ unlink (path.c_str());
+ }
+}
+
+int
+AUPluginInfo::load_cached_info ()
+{
+ Glib::ustring path = au_cache_path ();
+ XMLTree tree;
+
+ if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
+ return 0;
+ }
+
+ tree.read (path);
+ const XMLNode* root (tree.root());
+
+ if (root->name() != X_("AudioUnitPluginCache")) {
+ return -1;
+ }
+
+ cached_info.clear ();
+
+ const XMLNodeList children = root->children();
+
+ for (XMLNodeConstIterator iter = children.begin(); iter != children.end(); ++iter) {
+
+ const XMLNode* child = *iter;
+
+ if (child->name() == X_("plugin")) {
+
+ const XMLNode* gchild;
+ const XMLNodeList gchildren = child->children();
+ const XMLProperty* prop = child->property (X_("id"));
+
+ if (!prop) {
+ continue;
+ }
+
+ std::string id = prop->value();
+
+ for (XMLNodeConstIterator giter = gchildren.begin(); giter != gchildren.end(); giter++) {
+
+ gchild = *giter;
+
+ if (gchild->name() == X_("io")) {
+
+ int in;
+ int out;
+ const XMLProperty* iprop;
+ const XMLProperty* oprop;
+
+ if (((iprop = gchild->property (X_("in"))) != 0) &&
+ ((oprop = gchild->property (X_("out"))) != 0)) {
+ in = atoi (iprop->value());
+ out = atoi (iprop->value());
+
+ AUPluginCachedInfo cinfo;
+ cinfo.io_configs.push_back (pair<int,int> (in, out));
+ add_cached_info (id, cinfo);
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
void
AUPluginInfo::get_names (CAComponentDescription& comp_desc, std::string& name, Glib::ustring& maker)
{
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index a3f5eb9fd1..76c0de9b24 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -70,13 +70,12 @@ AudioEngine::AudioEngine (string client_name)
last_monitor_check = 0;
monitor_check_interval = max_frames;
_processed_frames = 0;
- _freewheeling = false;
_usecs_per_cycle = 0;
_jack = 0;
_frame_rate = 0;
_buffer_size = 0;
- _freewheeling = false;
_freewheel_thread_registered = false;
+ _freewheeling = false;
m_meter_thread = 0;
g_atomic_int_set (&m_meter_exit, 0);
@@ -84,6 +83,7 @@ AudioEngine::AudioEngine (string client_name)
if (connect_to_jack (client_name)) {
throw NoBackendAvailable ();
}
+
Port::set_engine (this);
}
@@ -331,8 +331,6 @@ AudioEngine::process_callback (nframes_t nframes)
if (_freewheeling) {
/* emit the Freewheel signal and stop freewheeling in the event of trouble */
if (Freewheel (nframes)) {
- cerr << "Freewheeling returned non-zero!\n";
- _freewheeling = false;
jack_set_freewheel (_jack, false);
}
@@ -847,7 +845,7 @@ AudioEngine::frames_per_cycle ()
* Note this can return NULL, it will NOT create a port if it is not found (any more).
*/
Port *
-AudioEngine::get_port_by_name (const string& portname, bool keep) const
+AudioEngine::get_port_by_name (const string& portname, bool keep)
{
Glib::Mutex::Lock lm (_process_lock);
@@ -923,7 +921,7 @@ AudioEngine::can_request_hardware_monitoring ()
uint32_t
-AudioEngine::n_physical_outputs () const
+AudioEngine::n_physical_outputs (DataType type) const
{
const char ** ports;
uint32_t i = 0;
@@ -932,7 +930,7 @@ AudioEngine::n_physical_outputs () const
return 0;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
return 0;
}
@@ -943,7 +941,7 @@ AudioEngine::n_physical_outputs () const
}
uint32_t
-AudioEngine::n_physical_inputs () const
+AudioEngine::n_physical_inputs (DataType type) const
{
const char ** ports;
uint32_t i = 0;
@@ -952,7 +950,7 @@ AudioEngine::n_physical_inputs () const
return 0;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
return 0;
}
@@ -964,7 +962,7 @@ AudioEngine::n_physical_inputs () const
}
void
-AudioEngine::get_physical_inputs (vector<string>& ins)
+AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
{
const char ** ports;
uint32_t i = 0;
@@ -973,7 +971,7 @@ AudioEngine::get_physical_inputs (vector<string>& ins)
return;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
return;
}
@@ -986,7 +984,7 @@ AudioEngine::get_physical_inputs (vector<string>& ins)
}
void
-AudioEngine::get_physical_outputs (vector<string>& outs)
+AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
{
const char ** ports;
uint32_t i = 0;
@@ -995,7 +993,7 @@ AudioEngine::get_physical_outputs (vector<string>& outs)
return;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
return;
}
@@ -1123,11 +1121,18 @@ AudioEngine::freewheel (bool onoff)
{
if (_jack) {
- if (onoff) {
- _freewheel_thread_registered = false;
- }
+ if (onoff != _freewheeling) {
- return jack_set_freewheel (_jack, onoff);
+ if (onoff) {
+ _freewheel_thread_registered = false;
+ }
+
+ return jack_set_freewheel (_jack, onoff);
+
+ } else {
+ /* already doing what has been asked for */
+ return 0;
+ }
} else {
return -1;
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index f5f04eac6d..cbf2e44c5f 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -1243,6 +1243,15 @@ AudioRegion::speed_mismatch (float sr) const
void
AudioRegion::source_offset_changed ()
{
+ /* XXX this fixes a crash that should not occur. It does occur
+ becauses regions are not being deleted when a session
+ is unloaded. That bug must be fixed.
+ */
+
+ if (_sources.empty()) {
+ return;
+ }
+
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
if (afs && afs->destructive()) {
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index 01dea08d3e..8e68b31587 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -214,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 || (statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
+ if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
// empty
_peaks_built = false;
} else {
diff --git a/libs/ardour/auto_bundle.cc b/libs/ardour/auto_bundle.cc
index 9da32bbb7a..fc70768601 100644
--- a/libs/ardour/auto_bundle.cc
+++ b/libs/ardour/auto_bundle.cc
@@ -13,17 +13,17 @@ ARDOUR::AutoBundle::AutoBundle (std::string const & n, bool i)
}
-uint32_t
+ARDOUR::ChanCount
ARDOUR::AutoBundle::nchannels () const
{
Glib::Mutex::Lock lm (_ports_mutex);
- return _ports.size ();
+ return ChanCount (type(), _ports.size ());
}
const ARDOUR::PortList&
ARDOUR::AutoBundle::channel_ports (uint32_t c) const
{
- assert (c < nchannels());
+ assert (c < nchannels().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
return _ports[c];
@@ -39,7 +39,7 @@ ARDOUR::AutoBundle::set_channels (uint32_t n)
void
ARDOUR::AutoBundle::set_port (uint32_t c, std::string const & p)
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
_ports[c].resize (1);
diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc
index b164d418ab..56dfd99f02 100644
--- a/libs/ardour/configuration.cc
+++ b/libs/ardour/configuration.cc
@@ -22,6 +22,7 @@
#include <glib.h>
#include <glib/gstdio.h> /* for g_stat() */
+#include <glibmm/miscutils.h>
#include <pbd/failed_constructor.h>
#include <pbd/xml++.h>
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index f3dfa28165..213e7504b0 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -84,7 +84,6 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
{
_in = in;
_out = out;
-
_anchor_point = ap;
_follow_overlap = false;
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 1397a7d959..3401d8c48a 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -30,6 +30,10 @@
#include <fst.h>
#endif
+#ifdef HAVE_AUDIOUNITS
+#include <ardour/audio_unit.h>
+#endif
+
#ifdef __SSE__
#include <xmmintrin.h>
#endif
@@ -347,6 +351,10 @@ ARDOUR::init (bool use_vst, bool try_optimization)
}
#endif
+#ifdef HAVE_AUDIOUNITS
+ AUPluginInfo::load_cached_info ();
+#endif
+
/* Make VAMP look in our library ahead of anything else */
char *p = getenv ("VAMP_PATH");
@@ -393,11 +401,7 @@ ARDOUR::cleanup ()
microseconds_t
ARDOUR::get_microseconds ()
{
- /* XXX need JACK to export its functionality */
-
- struct timeval now;
- gettimeofday (&now, 0);
- return now.tv_sec * 1000000ULL + now.tv_usec;
+ return (microseconds_t) jack_get_time ();
}
ARDOUR::Change
@@ -431,7 +435,6 @@ 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")) {
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index d79c930e6d..d4afda8b5a 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -459,15 +459,16 @@ Session::import_audiofiles (import_status& status)
if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
afs->update_header(0, *now, xnow);
afs->done_with_peakfile_writes ();
- }
-
- /* now that there is data there, requeue the file for analysis */
- if (Config->get_auto_analyse_audio()) {
- Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
+ /* now that there is data there, requeue the file for analysis */
+
+ if (Config->get_auto_analyse_audio()) {
+ Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
+ }
}
-
+
/* don't create tracks for empty MIDI sources (channels) */
+
if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
x = all_new_sources.erase(x);
} else {
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 5d4b41cf32..1b3c2e2378 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -24,6 +24,7 @@
#include <sigc++/bind.h>
+#include <glibmm.h>
#include <glibmm/thread.h>
#include <pbd/xml++.h>
@@ -358,14 +359,16 @@ IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports)
for (std::vector<UserBundleInfo>::iterator i = list.begin(); i != list.end(); ++i) {
- uint32_t const N = i->bundle->nchannels ();
+ ChanCount const N = i->bundle->nchannels ();
- if (ports.num_ports() < N) {
+ if (ports.num_ports (default_type()) < N.get (default_type())) {
continue;
}
bool ok = true;
- for (uint32_t j = 0; j < N; ++j) {
+ uint32_t n = N.get (default_type());
+
+ for (uint32_t j = 0; j < n; ++j) {
/* Every port on bundle channel j must be connected to our input j */
PortList const pl = i->bundle->channel_ports (j);
for (uint32_t k = 0; k < pl.size(); ++k) {
@@ -730,7 +733,7 @@ IO::add_input_port (string source, void* src, DataType type)
{
Glib::Mutex::Lock lm (io_lock);
- if (n_inputs() >= _input_maximum) {
+ if (_input_maximum.get(type) >= 0 && n_inputs().get (type) >= _input_maximum.get (type)) {
return -1;
}
@@ -1460,16 +1463,12 @@ IO::load_automation (string path)
float version;
LocaleGuard lg (X_("POSIX"));
- fullpath = _session.automation_dir();
- fullpath += path;
+ fullpath = Glib::build_filename(_session.automation_dir(), path);
in.open (fullpath.c_str());
if (!in) {
- fullpath = _session.automation_dir();
- fullpath += _session.snap_name();
- fullpath += '-';
- fullpath += path;
+ fullpath = Glib::build_filename(_session.automation_dir(), _session.snap_name() + '-' + path);
in.open (fullpath.c_str());
@@ -1573,23 +1572,138 @@ IO::ports_became_legal ()
return ret;
}
+boost::shared_ptr<Bundle>
+IO::find_possible_bundle (const string &desired_name, const string &default_name, const string &bundle_type_name)
+{
+ static const string digits = "0123456789";
+
+ boost::shared_ptr<Bundle> c = _session.bundle_by_name (desired_name);
+
+ if (!c) {
+ int bundle_number, mask;
+ string possible_name;
+ bool stereo = false;
+ string::size_type last_non_digit_pos;
+
+ error << string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name, bundle_type_name, _name)
+ << endmsg;
+
+ // find numeric suffix of desired name
+ bundle_number = 0;
+
+ last_non_digit_pos = desired_name.find_last_not_of(digits);
+
+ if (last_non_digit_pos != string::npos) {
+ stringstream s;
+ s << desired_name.substr(last_non_digit_pos);
+ s >> bundle_number;
+ }
+
+ // see if it's a stereo connection e.g. "in 3+4"
+
+ if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
+ int left_bundle_number = 0;
+ string::size_type left_last_non_digit_pos;
+
+ left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
+
+ if (left_last_non_digit_pos != string::npos) {
+ stringstream s;
+ s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
+ s >> left_bundle_number;
+
+ if (left_bundle_number > 0 && left_bundle_number + 1 == bundle_number) {
+ bundle_number--;
+ stereo = true;
+ }
+ }
+ }
+
+ // make 0-based
+ if (bundle_number)
+ bundle_number--;
+
+ // find highest set bit
+ mask = 1;
+ while ((mask <= bundle_number) && (mask <<= 1));
+
+ // "wrap" bundle number into largest possible power of 2
+ // that works...
+
+ while (mask) {
+
+ if (bundle_number & mask) {
+ bundle_number &= ~mask;
+
+ stringstream s;
+ s << default_name << " " << bundle_number + 1;
+
+ if (stereo) {
+ s << "+" << bundle_number + 2;
+ }
+
+ possible_name = s.str();
+
+ if ((c = _session.bundle_by_name (possible_name)) != 0) {
+ break;
+ }
+ }
+ mask >>= 1;
+ }
+ if (c) {
+ info << string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name, possible_name)
+ << endmsg;
+ } else {
+ error << string_compose(_("No %1 bundles available as a replacement"), bundle_type_name)
+ << endmsg;
+ }
+
+ }
+
+ return c;
+
+}
+
int
IO::create_ports (const XMLNode& node)
{
XMLProperty const * prop;
- int num_inputs = 0;
- int num_outputs = 0;
+ ChanCount num_inputs;
+ ChanCount num_outputs;
+
+ if ((prop = node.property ("input-connection")) != 0) {
- if ((prop = node.property ("inputs")) != 0) {
- num_inputs = count (prop->value().begin(), prop->value().end(), '{');
+ boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
+
+ if (!c) {
+ return -1;
+ }
+
+ num_inputs = c->nchannels();
+
+ } else if ((prop = node.property ("inputs")) != 0) {
+
+ num_inputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
+ }
+
+ if ((prop = node.property ("output-connection")) != 0) {
+
+ boost::shared_ptr<Bundle> c = find_possible_bundle(prop->value(), _("out"), _("output"));
+
+ if (!c) {
+ return -1;
+ }
+
+ num_outputs = c->nchannels ();
+
} else if ((prop = node.property ("outputs")) != 0) {
- num_outputs = count (prop->value().begin(), prop->value().end(), '{');
+
+ num_outputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
}
no_panner_reset = true;
- // FIXME: audio-only
- if (ensure_io (ChanCount(DataType::AUDIO, num_inputs), ChanCount(DataType::AUDIO, num_outputs), true, this)) {
+ if (ensure_io (num_inputs, num_outputs, true, this)) {
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
return -1;
}
@@ -1606,17 +1720,35 @@ IO::create_ports (const XMLNode& node)
int
IO::make_connections (const XMLNode& node)
{
- XMLProperty const * prop;
-
- if ((prop = node.property ("inputs")) != 0) {
+
+ const XMLProperty* prop;
+
+ if ((prop = node.property ("input-connection")) != 0) {
+ boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
+
+ if (!c) {
+ return -1;
+ }
+
+ connect_input_ports_to_bundle (c, this);
+
+ } else if ((prop = node.property ("inputs")) != 0) {
if (set_inputs (prop->value())) {
error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
return -1;
}
}
-
- if ((prop = node.property ("outputs")) != 0) {
+ if ((prop = node.property ("output-connection")) != 0) {
+ boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
+
+ if (!c) {
+ return -1;
+ }
+
+ connect_output_ports_to_bundle (c, this);
+
+ } else if ((prop = node.property ("outputs")) != 0) {
if (set_outputs (prop->value())) {
error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
return -1;
@@ -1628,23 +1760,19 @@ IO::make_connections (const XMLNode& node)
if ((*i)->name() == "InputBundle") {
XMLProperty const * prop = (*i)->property ("name");
if (prop) {
- boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value());
+ boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("in"), _("input"));
if (b) {
connect_input_ports_to_bundle (b, this);
- } else {
- error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
}
}
} else if ((*i)->name() == "OutputBundle") {
XMLProperty const * prop = (*i)->property ("name");
if (prop) {
- boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value());
+ boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("out"), _("output"));
if (b) {
connect_output_ports_to_bundle (b, this);
- } else {
- error << string_compose(_("Unknown bundle \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
- }
+ }
}
}
}
@@ -1924,9 +2052,10 @@ IO::connect_input_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
/* Connect to the bundle, not worrying about any connections
that are already made. */
- uint32_t const channels = c->nchannels ();
-
- for (uint32_t n = 0; n < channels; ++n) {
+ ChanCount const channels = c->nchannels ();
+ uint32_t cnt = channels.get (default_type());
+
+ for (uint32_t n = 0; n < cnt; ++n) {
const PortList& pl = c->channel_ports (n);
for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
@@ -1973,9 +2102,10 @@ IO::connect_output_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
/* Connect to the bundle, not worrying about any connections
that are already made. */
- uint32_t const channels = c->nchannels ();
+ ChanCount const channels = c->nchannels ();
+ uint32_t cnt = channels.get (default_type());
- for (uint32_t n = 0; n < channels; ++n) {
+ for (uint32_t n = 0; n < cnt; ++n) {
const PortList& pl = c->channel_ports (n);
@@ -2105,8 +2235,8 @@ IO::GainControl::get_value (void) const
void
IO::setup_peak_meters()
{
- ChanCount max_streams = std::max(_inputs.count(), _outputs.count());
- _meter->configure_io(max_streams, max_streams);
+ ChanCount max_streams = std::max (_inputs.count(), _outputs.count());
+ _meter->configure_io (max_streams, max_streams);
}
/**
@@ -2496,11 +2626,12 @@ void
IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
{
boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
+
if (ab == 0 || ab->ports_are_outputs() == false) {
return;
}
-
- if (ab->nchannels () != n_inputs().n_total ()) {
+
+ if (ab->nchannels().get (default_type()) != n_inputs().n_total ()) {
return;
}
@@ -2552,7 +2683,7 @@ IO::maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<bo
return;
}
- if (ab->nchannels () != n_outputs().n_total ()) {
+ if (ab->nchannels ().get (default_type()) != n_outputs().n_total ()) {
return;
}
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index 0da75810ca..3654e03a9d 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -100,6 +100,7 @@ Location::set_start (nframes_t s)
_end = s;
start_changed(this); /* EMIT SIGNAL */
+ end_changed(this); /* EMIT SIGNAL */
if ( is_start() ) {
@@ -137,7 +138,17 @@ Location::set_end (nframes_t e)
if (_start != e) {
_start = e;
_end = e;
+ start_changed(this); /* EMIT SIGNAL */
end_changed(this); /* EMIT SIGNAL */
+
+ if ( is_start() ) {
+ Session::StartTimeChanged (); /* EMIT SIGNAL */
+ }
+
+ if ( is_end() ) {
+ Session::EndTimeChanged (); /* EMIT SIGNAL */
+ }
+
}
return 0;
}
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 4553458831..a38c851c21 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -23,6 +23,7 @@
#include <cstdlib>
#include <cmath>
+#include <cstring>
#include <pbd/compose.h>
#include <pbd/error.h>
diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc
index e75c1d89ca..aedfd17be8 100644
--- a/libs/ardour/meter.cc
+++ b/libs/ardour/meter.cc
@@ -95,8 +95,9 @@ bool
PeakMeter::configure_io (ChanCount in, ChanCount out)
{
/* we're transparent no matter what. fight the power. */
- if (out != in)
+ if (out != in) {
return false;
+ }
uint32_t limit = in.n_total();
@@ -116,9 +117,7 @@ PeakMeter::configure_io (ChanCount in, ChanCount out)
assert(_visible_peak_power.size() == limit);
assert(_max_peak_power.size() == limit);
- Processor::configure_io(in, out);
-
- return true;
+ return Processor::configure_io (in, out);
}
/** To be driven by the Meter signal from IO.
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 1000e68ba6..efb6e5b8d9 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -661,21 +661,23 @@ MidiTrack::set_latency_delay (nframes_t longest_session_latency)
_diskstream->set_roll_delay (_roll_delay);
}
-void
+boost::shared_ptr<Region>
MidiTrack::bounce (InterThreadInfo& itt)
{
throw;
- //vector<MidiSource*> srcs;
- //_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+ // vector<MidiSource*> srcs;
+ // return _session.write_one_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+ return boost::shared_ptr<Region> ();
}
-void
+boost::shared_ptr<Region>
MidiTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
{
throw;
//vector<MidiSource*> srcs;
- //_session.write_one_midi_track (*this, start, end, false, srcs, itt);
+ //return _session.write_one_track (*this, start, end, false, srcs, itt);
+ return boost::shared_ptr<Region> ();
}
void
@@ -732,7 +734,7 @@ MidiTrack::MidiControl::set_value(float val)
size_t size = 3;
if ( ! _list->automation_playback()) {
- uint8_t ev[3] = { _list->parameter().channel(), int(val), 0.0 };
+ uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
switch(_list->parameter().type()) {
case MidiCCAutomation:
ev[0] += MIDI_CMD_CONTROL;
diff --git a/libs/ardour/onset_detector.cc b/libs/ardour/onset_detector.cc
new file mode 100644
index 0000000000..f58e64ad4a
--- /dev/null
+++ b/libs/ardour/onset_detector.cc
@@ -0,0 +1,126 @@
+#include <ardour/onset_detector.h>
+
+#include "i18n.h"
+
+using namespace Vamp;
+using namespace ARDOUR;
+using namespace std;
+
+/* need a static initializer function for this */
+
+string OnsetDetector::_op_id = X_("libardourvampplugins:aubioonset:2");
+
+OnsetDetector::OnsetDetector (float sr)
+ : AudioAnalyser (sr, X_("libardourvampplugins:aubioonset"))
+{
+ /* update the op_id */
+
+ _op_id = X_("libardourvampplugins:aubioonset");
+
+ // XXX this should load the above-named plugin and get the current version
+
+ _op_id += ":2";
+}
+
+OnsetDetector::~OnsetDetector()
+{
+}
+
+string
+OnsetDetector::operational_identifier()
+{
+ return _op_id;
+}
+
+int
+OnsetDetector::run (const std::string& path, Readable* src, uint32_t channel, AnalysisFeatureList& results)
+{
+ current_results = &results;
+ int ret = analyse (path, src, channel);
+
+ current_results = 0;
+ return ret;
+}
+
+int
+OnsetDetector::use_features (Plugin::FeatureSet& features, ostream* out)
+{
+ const Plugin::FeatureList& fl (features[0]);
+
+ for (Plugin::FeatureList::const_iterator f = fl.begin(); f != fl.end(); ++f) {
+
+ if ((*f).hasTimestamp) {
+
+ if (out) {
+ (*out) << (*f).timestamp.toString() << endl;
+ }
+
+ current_results->push_back (RealTime::realTime2Frame ((*f).timestamp, (nframes_t) floor(sample_rate)));
+ }
+ }
+
+ return 0;
+}
+
+void
+OnsetDetector::set_silence_threshold (float val)
+{
+ if (plugin) {
+ plugin->setParameter ("silencethreshold", val);
+ }
+}
+
+void
+OnsetDetector::set_peak_threshold (float val)
+{
+ if (plugin) {
+ plugin->setParameter ("peakpickthreshold", val);
+ }
+}
+
+void
+OnsetDetector::set_function (int val)
+{
+ if (plugin) {
+ plugin->setParameter ("onsettype", (float) val);
+ }
+}
+
+void
+OnsetDetector::cleanup_onsets (AnalysisFeatureList& t, float sr, float gap_msecs)
+{
+ if (t.empty()) {
+ return;
+ }
+
+ t.sort ();
+
+ /* remove duplicates or other things that are too close */
+
+ AnalysisFeatureList::iterator i = t.begin();
+ AnalysisFeatureList::iterator f, b;
+ const nframes64_t gap_frames = (nframes64_t) floor (gap_msecs * (sr / 1000.0));
+
+ while (i != t.end()) {
+
+ // move front iterator to just past i, and back iterator the same place
+
+ f = i;
+ ++f;
+ b = f;
+
+ // move f until we find a new value that is far enough away
+
+ while ((f != t.end()) && (((*f) - (*i)) < gap_frames)) {
+ ++f;
+ }
+
+ i = f;
+
+ // if f moved forward from b, we had duplicates/too-close points: get rid of them
+
+ if (b != f) {
+ t.erase (b, f);
+ }
+ }
+}
diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc
index b0bd35b8c6..0c58040ad6 100644
--- a/libs/ardour/osc.cc
+++ b/libs/ardour/osc.cc
@@ -28,6 +28,8 @@
#include <unistd.h>
#include <fcntl.h>
+#include <glibmm/miscutils.h>
+
#include <pbd/pthread_utils.h>
#include <pbd/file_utils.h>
@@ -183,6 +185,7 @@ OSC::register_callbacks()
#define REGISTER_CALLBACK(serv,path,types, function) lo_server_add_method (serv, path, types, OSC::_ ## function, this)
REGISTER_CALLBACK (serv, "/ardour/add_marker", "", add_marker);
+ REGISTER_CALLBACK (serv, "/ardour/access_action", "s", access_action);
REGISTER_CALLBACK (serv, "/ardour/loop_toggle", "", loop_toggle);
REGISTER_CALLBACK (serv, "/ardour/goto_start", "", goto_start);
REGISTER_CALLBACK (serv, "/ardour/goto_end", "", goto_end);
@@ -409,6 +412,10 @@ OSC::set_session (Session& s)
{
session = &s;
session->GoingAway.connect (mem_fun (*this, &OSC::session_going_away));
+
+ // "Application Hooks"
+ session_loaded( s );
+ session->Exported.connect( mem_fun( *this, &OSC::session_exported ) );
}
void
@@ -417,6 +424,21 @@ OSC::session_going_away ()
session = 0;
}
+// "Application Hook" Handlers //
+void
+OSC::session_loaded( Session& s ) {
+ lo_address listener = lo_address_new( NULL, "7770" );
+ lo_send( listener, "/session/loaded", "ss", s.path().c_str(), s.name().c_str() );
+}
+
+void
+OSC::session_exported( std::string path, std::string name ) {
+ lo_address listener = lo_address_new( NULL, "7770" );
+ lo_send( listener, "/session/exported", "ss", path.c_str(), name.c_str() );
+}
+
+// end "Application Hook" Handlers //
+
/* path callbacks */
int
diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc
index ca4c51fa97..2163ba5cc0 100644
--- a/libs/ardour/panner.cc
+++ b/libs/ardour/panner.cc
@@ -1115,8 +1115,7 @@ Panner::set_state (const XMLNode& node)
/* automation path is relative */
- automation_path = _session.automation_dir();
- automation_path += prop->value ();
+ automation_path = Glib::build_filename(_session.automation_dir(), prop->value ());
}
return 0;
@@ -1416,11 +1415,8 @@ Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame
void
Panner::set_name (string str)
{
- automation_path = _session.automation_dir();
- automation_path += _session.snap_name();
- automation_path += "-pan-";
- automation_path += legalize_for_path (str);
- automation_path += ".automation";
+ automation_path = Glib::build_filename(_session.automation_dir(),
+ _session.snap_name() + "-pan-" + legalize_for_path (str) + ".automation");
}
int
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 3d218448dd..c52a027915 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -241,3 +241,22 @@ ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
return PluginPtr ((Plugin*) 0);
}
+ChanCount
+Plugin::output_streams () const
+{
+ /* LADSPA & VST should not get here because they do not
+ return "infinite" i/o counts.
+ */
+ return ChanCount::ZERO;
+}
+
+ChanCount
+Plugin::input_streams () const
+{
+ /* LADSPA & VST should not get here because they do not
+ return "infinite" i/o counts.
+ */
+ return ChanCount::ZERO;
+}
+
+
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 26d344dee4..f44a5df003 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -162,19 +162,34 @@ PluginInsert::auto_state_changed (Parameter which)
ChanCount
PluginInsert::output_streams() const
{
- if (_configured)
- return output_for_input_configuration(_configured_input);
- else
- return natural_output_streams();
+ ChanCount out = _plugins.front()->get_info()->n_outputs;
+
+ if (out == ChanCount::INFINITE) {
+
+ return _plugins.front()->output_streams ();
+
+ } else {
+
+ out.set_audio (out.n_audio() * _plugins.size());
+ out.set_midi (out.n_midi() * _plugins.size());
+
+ return out;
+ }
}
ChanCount
PluginInsert::input_streams() const
{
- if (_configured)
- return _configured_input;
- else
- return natural_input_streams();
+ ChanCount in = _plugins[0]->get_info()->n_inputs;
+
+ if (in == ChanCount::INFINITE) {
+ return _plugins[0]->input_streams ();
+ } else {
+ in.set_audio (in.n_audio() * _plugins.size());
+ in.set_midi (in.n_midi() * _plugins.size());
+
+ return in;
+ }
}
ChanCount
@@ -473,31 +488,42 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
bool
PluginInsert::configure_io (ChanCount in, ChanCount out)
{
- ChanCount matching_out = output_for_input_configuration(out);
- if (matching_out != out) {
- _configured = false;
+ if (set_count (count_for_configuration (in, out)) < 0) {
+ return false;
+ }
+
+ /* if we're running replicated plugins, each plugin has
+ the same i/o configuration and we may need to announce how many
+ output streams there are.
+
+ if we running a single plugin, we need to configure it.
+ */
+
+ if (_plugins.front()->configure_io (in, out) < 0) {
return false;
- } else {
- bool success = set_count (count_for_configuration(in, out));
- if (success)
- Processor::configure_io(in, out);
- return success;
}
+
+ return Processor::configure_io (in, out);
}
bool
-PluginInsert::can_support_input_configuration (ChanCount in) const
+PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
+ if (_plugins.front()->reconfigurable_io()) {
+ /* plugin has flexible I/O, so delegate to it */
+ return _plugins.front()->can_support_io_configuration (in, out);
+ }
+
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
ChanCount inputs = _plugins[0]->get_info()->n_inputs;
- /* see output_for_input_configuration below */
if ((inputs.n_total() == 0)
|| (inputs.n_total() == 1 && outputs == inputs)
|| (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|| (inputs.n_midi() == 0 && in.n_midi() == 0)))
|| (inputs == in)) {
+ out = outputs;
return true;
}
@@ -513,60 +539,31 @@ PluginInsert::can_support_input_configuration (ChanCount in) const
}
}
- if (can_replicate && (in.n_total() % inputs.n_total() == 0)) {
- return true;
- } else {
+ if (!can_replicate || (in.n_total() % inputs.n_total() != 0)) {
return false;
}
-}
-
-ChanCount
-PluginInsert::output_for_input_configuration (ChanCount in) const
-{
- ChanCount outputs = _plugins[0]->get_info()->n_outputs;
- ChanCount inputs = _plugins[0]->get_info()->n_inputs;
if (inputs.n_total() == 0) {
/* instrument plugin, always legal, but throws away any existing streams */
- return outputs;
- }
-
- if (inputs.n_total() == 1 && outputs == inputs
+ out = outputs;
+ } else if (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
- || (inputs.n_midi() == 0 && in.n_midi() == 0))) {
- /* mono plugin, replicate as needed to match in */
- return in;
- }
-
- if (inputs == in) {
+ || (inputs.n_midi() == 0 && in.n_midi() == 0))) {
+ /* mono, single-typed plugin, replicate as needed to match in */
+ out = in;
+ } else if (inputs == in) {
/* exact match */
- return outputs;
- }
-
- bool can_replicate = true;
-
- /* if number of inputs is a factor of the requested input
- configuration for every type, we can replicate.
- */
- for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- if (inputs.get(*t) >= in.get(*t) || (in.get(*t) % inputs.get(*t) != 0)) {
- can_replicate = false;
- break;
- }
- }
-
- if (can_replicate && (inputs.n_total() % in.n_total() == 0)) {
- ChanCount output;
-
+ out = outputs;
+ } else {
+ /* replicate - note that we've already verified that
+ the replication count is constant across all data types.
+ */
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- output.set(*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
+ out.set (*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
}
-
- return output;
}
-
- /* sorry */
- return ChanCount();
+
+ return true;
}
/* Number of plugin instances required to support a given channel configuration.
@@ -575,6 +572,12 @@ PluginInsert::output_for_input_configuration (ChanCount in) const
int32_t
PluginInsert::count_for_configuration (ChanCount in, ChanCount out) const
{
+ if (_plugins.front()->reconfigurable_io()) {
+ /* plugin has flexible I/O, so the answer is always 1 */
+ /* this could change if we ever decide to replicate AU's */
+ return 1;
+ }
+
// FIXME: take 'out' into consideration
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc
index 6ff780a25f..e7c2aecd2d 100644
--- a/libs/ardour/plugin_manager.cc
+++ b/libs/ardour/plugin_manager.cc
@@ -24,13 +24,17 @@
#include <cstdio>
#include <lrdf.h>
#include <dlfcn.h>
+#include <cstdlib>
+#include <fstream>
#ifdef VST_SUPPORT
#include <fst.h>
#include <pbd/basename.h>
-#include <string.h>
+#include <cstring>
#endif // VST_SUPPORT
+#include <glibmm/miscutils.h>
+
#include <pbd/pathscanner.h>
#include <ardour/ladspa.h>
@@ -38,6 +42,7 @@
#include <ardour/plugin_manager.h>
#include <ardour/plugin.h>
#include <ardour/ladspa_plugin.h>
+#include <ardour/filesystem_paths.h>
#ifdef HAVE_SLV2
#include <slv2/slv2.h>
@@ -50,6 +55,7 @@
#ifdef HAVE_AUDIOUNITS
#include <ardour/audio_unit.h>
+#include <Carbon/Carbon.h>
#endif
#include <pbd/error.h>
@@ -59,6 +65,7 @@
using namespace ARDOUR;
using namespace PBD;
+using namespace std;
PluginManager* PluginManager::_manager = 0;
@@ -67,6 +74,16 @@ PluginManager::PluginManager ()
char* s;
string lrdf_path;
+ load_favorites ();
+
+#ifdef GTKOSX
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ OSStatus returnCode = TransformProcessType(& psn, kProcessTransformToForegroundApplication);
+ if( returnCode != 0) {
+ error << _("Cannot become GUI app") << endmsg;
+ }
+#endif
+
if ((s = getenv ("LADSPA_RDF_PATH"))){
lrdf_path = s;
}
@@ -487,3 +504,107 @@ PluginManager::vst_discover (string path)
}
#endif // VST_SUPPORT
+
+bool
+PluginManager::is_a_favorite_plugin (const PluginInfoPtr& pi)
+{
+ FavoritePlugin fp (pi->type, pi->unique_id);
+ return find (favorites.begin(), favorites.end(), fp) != favorites.end();
+}
+
+void
+PluginManager::save_favorites ()
+{
+ ofstream ofs;
+ sys::path path = user_config_directory();
+ path /= "favorite_plugins";
+
+ ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
+
+ if (!ofs) {
+ return;
+ }
+
+ for (FavoritePluginList::iterator i = favorites.begin(); i != favorites.end(); ++i) {
+ switch ((*i).type) {
+ case LADSPA:
+ ofs << "LADSPA";
+ break;
+ case AudioUnit:
+ ofs << "AudioUnit";
+ break;
+ case LV2:
+ ofs << "LV2";
+ break;
+ case VST:
+ ofs << "VST";
+ break;
+ }
+
+ ofs << ' ' << (*i).unique_id << endl;
+ }
+
+ ofs.close ();
+}
+
+void
+PluginManager::load_favorites ()
+{
+ sys::path path = user_config_directory();
+ path /= "favorite_plugins";
+ ifstream ifs (path.to_string().c_str());
+
+ if (!ifs) {
+ return;
+ }
+
+ std::string stype;
+ std::string id;
+ PluginType type;
+
+ while (ifs) {
+
+ ifs >> stype;
+ if (!ifs) {
+ break;
+
+ }
+ ifs >> id;
+ if (!ifs) {
+ break;
+ }
+
+ if (stype == "LADSPA") {
+ type = LADSPA;
+ } else if (stype == "AudioUnit") {
+ type = AudioUnit;
+ } else if (stype == "LV2") {
+ type = LV2;
+ } else if (stype == "VST") {
+ type = VST;
+ } else {
+ error << string_compose (_("unknown favorite plugin type \"%1\" - ignored"), stype)
+ << endmsg;
+ continue;
+ }
+
+ add_favorite (type, id);
+ }
+
+ ifs.close ();
+}
+
+void
+PluginManager::add_favorite (PluginType t, string id)
+{
+ FavoritePlugin fp (t, id);
+ pair<FavoritePluginList::iterator,bool> res = favorites.insert (fp);
+ cerr << "Added " << t << " " << id << " success ? " << res.second << endl;
+}
+
+void
+PluginManager::remove_favorite (PluginType t, string id)
+{
+ FavoritePlugin fp (t, id);
+ favorites.erase (fp);
+}
diff --git a/libs/ardour/po/sv_SE.po b/libs/ardour/po/sv_SE.po
index ddc7f108bb..58be548f8e 100644
--- a/libs/ardour/po/sv_SE.po
+++ b/libs/ardour/po/sv_SE.po
@@ -1972,6 +1972,10 @@ msgstr "Fogredigering"
msgid "Slide Edit"
msgstr "Glidredigering"
+#: libs/ardour/utils.cc:372 libs/ardour/utils.cc:388
+msgid "Lock Edit"
+msgstr "LÃ¥st redigering"
+
#: libs/ardour/utils.cc:309
msgid "programming error: unknown edit mode string \"%1\""
msgstr ""
diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc
index e14835b083..8c33d989dd 100644
--- a/libs/ardour/port_insert.cc
+++ b/libs/ardour/port_insert.cc
@@ -173,43 +173,12 @@ PortInsert::signal_latency() const
}
bool
-PortInsert::can_support_input_configuration (ChanCount in) const
-{
- if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
-
- /* not configured yet */
-
- return true; /* we can support anything the first time we're asked */
-
- } else {
-
- /* the "input" config for a port insert corresponds to how
- many output ports it will have.
- */
-
- if (_io->output_maximum() == in) {
-
- return true;
- }
- }
-
- return false;
-}
-
-ChanCount
-PortInsert::output_for_input_configuration (ChanCount in) const
-{
- return in;
-}
-
-bool
PortInsert::configure_io (ChanCount in, ChanCount out)
{
/* do not allow configuration to be changed outside the range of
the last request config. or something like that.
*/
-
/* this is a bit odd:
the number of inputs we are required to handle corresponds
@@ -224,12 +193,11 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
_io->set_input_maximum (out);
_io->set_input_minimum (out);
- bool success = (_io->ensure_io (out, in, false, this) == 0);
-
- if (success)
- return Processor::configure_io(in, out);
- else
+ if (_io->ensure_io (out, in, false, this) != 0) {
return false;
+ }
+
+ return Processor::configure_io (in, out);
}
ChanCount
diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc
index cea33fbe32..486a75703b 100644
--- a/libs/ardour/processor.cc
+++ b/libs/ardour/processor.cc
@@ -272,3 +272,16 @@ Processor::set_state (const XMLNode& node)
return 0;
}
+bool
+Processor::configure_io (ChanCount in, ChanCount out)
+{
+ /* this class assumes static output stream count.
+ Derived classes must override, and must set "out"
+ to reflect "in" before calling this.
+ */
+
+ _configured_input = in;
+ _configured = true;
+
+ return true;
+}
diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc
index 4daf5cb33a..9d8ac311b7 100644
--- a/libs/ardour/rb_effect.cc
+++ b/libs/ardour/rb_effect.cc
@@ -74,21 +74,89 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
nframes_t pos = 0;
int avail = 0;
- // note: this_time_fraction is a ratio of original length. 1.0 = no change,
- // 0.5 is half as long, 2.0 is twice as long, etc.
+ cerr << "RBEffect: source region: position = " << region->position()
+ << ", start = " << region->start()
+ << ", length = " << region->length()
+ << ", ancestral_start = " << region->ancestral_start()
+ << ", ancestral_length = " << region->ancestral_length()
+ << ", stretch " << region->stretch()
+ << ", shift " << region->shift() << endl;
+
+ /*
+ We have two cases to consider:
+
+ 1. The region has not been stretched before.
+
+ In this case, we just want to read region->length() frames
+ from region->start().
+
+ We will create a new region of region->length() *
+ tsr.time_fraction frames. The new region will have its
+ start set to 0 (because it has a new audio file that begins
+ at the start of the stretched area) and its ancestral_start
+ set to region->start() (so that we know where to begin
+ reading if we want to stretch it again).
+
+ 2. The region has been stretched before.
+
+ The region starts at region->start() frames into its
+ (possibly previously stretched) source file. But we don't
+ want to read from its source file; we want to read from the
+ file it was originally stretched from.
+
+ The region's source begins at region->ancestral_start()
+ frames into its master source file. Thus, we need to start
+ reading at region->ancestral_start() + (region->start() /
+ region->stretch()) frames into the master source. This
+ value will also become the ancestral_start for the new
+ region.
+
+ We cannot use region->ancestral_length() to establish how
+ many frames to read, because it won't be up to date if the
+ region has been trimmed since it was last stretched. We
+ must read region->length() / region->stretch() frames and
+ stretch them by tsr.time_fraction * region->stretch(), for
+ a new region of region->length() * tsr.time_fraction
+ frames.
+
+ Case 1 is of course a special case of 2, where
+ region->ancestral_start() == 0 and region->stretch() == 1.
+
+ When we ask to read from a region, we supply a position on
+ the global timeline. The read function calculates the
+ offset into the source as (position - region->position()) +
+ region->start(). This calculation is used regardless of
+ whether we are reading from a master or
+ previously-stretched region. In order to read from a point
+ n frames into the master source, we need to provide n -
+ region->start() + region->position() as our position
+ argument to master_read_at().
+
+ Note that region->ancestral_length() is not used.
+
+ I hope this is clear.
+ */
+
+ double stretch = region->stretch() * tsr.time_fraction;
+ double shift = region->shift() * tsr.pitch_fraction;
- double this_time_fraction = tsr.time_fraction * region->stretch ();
- double this_pitch_fraction = tsr.pitch_fraction * region->shift ();
+ nframes_t read_start = region->ancestral_start() +
+ nframes_t(region->start() / (double)region->stretch());
- RubberBandStretcher stretcher (session.frame_rate(), region->n_channels(),
- (RubberBandStretcher::Options) tsr.opts,
- this_time_fraction, this_pitch_fraction);
+ nframes_t read_duration =
+ nframes_t(region->length() / (double)region->stretch());
+
+ uint32_t channels = region->n_channels();
+
+ RubberBandStretcher stretcher
+ (session.frame_rate(), channels,
+ (RubberBandStretcher::Options) tsr.opts, stretch, shift);
tsr.progress = 0.0f;
tsr.done = false;
- uint32_t channels = region->n_channels();
- nframes_t duration = region->ancestral_length();
+ stretcher.setExpectedInputDuration(read_duration);
+ stretcher.setDebugLevel(1);
stretcher.setExpectedInputDuration(duration);
stretcher.setDebugLevel(1);
@@ -97,14 +165,14 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
digits just to disambiguate close but not identical FX
*/
- if (this_time_fraction == 1.0) {
- snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_pitch_fraction * 100.0f));
- } else if (this_pitch_fraction == 1.0) {
- snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_time_fraction * 100.0f));
+ if (stretch == 1.0) {
+ snprintf (suffix, sizeof (suffix), "@%d", (int) floor (shift * 100.0f));
+ } else if (shift == 1.0) {
+ snprintf (suffix, sizeof (suffix), "@%d", (int) floor (stretch * 100.0f));
} else {
snprintf (suffix, sizeof (suffix), "@%d-%d",
- (int) floor (this_time_fraction * 100.0f),
- (int) floor (this_pitch_fraction * 100.0f));
+ (int) floor (stretch * 100.0f),
+ (int) floor (shift * 100.0f));
}
/* create new sources */
@@ -131,22 +199,26 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
done = 0;
try {
- while (pos < duration && !tsr.cancel) {
+ while (pos < read_duration && !tsr.cancel) {
nframes_t this_read = 0;
for (uint32_t i = 0; i < channels; ++i) {
this_read = 0;
+
nframes_t this_time;
+ this_time = min(bufsize, read_duration - pos);
- this_time = min(bufsize, duration - pos);
-
+ nframes_t this_position;
+ this_position = read_start + pos -
+ region->start() + region->position();
+
this_read = region->master_read_at
(buffers[i],
buffers[i],
gain_buffer,
- pos + region->position(),
+ this_position,
this_time,
i);
@@ -161,15 +233,15 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
pos += this_read;
done += this_read;
- tsr.progress = ((float) done / duration) * 0.25;
+ tsr.progress = ((float) done / read_duration) * 0.25;
- stretcher.study(buffers, this_read, pos == duration);
+ stretcher.study(buffers, this_read, pos == read_duration);
}
done = 0;
pos = 0;
- while (pos < duration && !tsr.cancel) {
+ while (pos < read_duration && !tsr.cancel) {
nframes_t this_read = 0;
@@ -177,14 +249,17 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
this_read = 0;
nframes_t this_time;
-
- this_time = min(bufsize, duration - pos);
+ this_time = min(bufsize, read_duration - pos);
+
+ nframes_t this_position;
+ this_position = read_start + pos -
+ region->start() + region->position();
this_read = region->master_read_at
(buffers[i],
buffers[i],
gain_buffer,
- pos + region->position(),
+ this_position,
this_time,
i);
@@ -199,9 +274,9 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
pos += this_read;
done += this_read;
- tsr.progress = 0.25 + ((float) done / duration) * 0.75;
+ tsr.progress = 0.25 + ((float) done / read_duration) * 0.75;
- stretcher.process(buffers, this_read, pos == duration);
+ stretcher.process(buffers, this_read, pos == read_duration);
int avail = 0;
@@ -261,10 +336,11 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) {
- (*x)->set_ancestral_data (region->ancestral_start(),
- region->ancestral_length(),
- this_time_fraction,
- this_pitch_fraction );
+
+ (*x)->set_ancestral_data (read_start,
+ read_duration,
+ stretch,
+ shift);
(*x)->set_master_sources (region->get_master_sources());
}
diff --git a/libs/ardour/recent_sessions.cc b/libs/ardour/recent_sessions.cc
index 9b8668dd88..d7f5ad132f 100644
--- a/libs/ardour/recent_sessions.cc
+++ b/libs/ardour/recent_sessions.cc
@@ -22,7 +22,11 @@
#include <unistd.h>
#include <fstream>
#include <algorithm>
+
+#include <glibmm/miscutils.h>
+
#include <pbd/error.h>
+
#include <ardour/configuration.h>
#include <ardour/filesystem_paths.h>
#include <ardour/recent_sessions.h>
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index a6d153f359..6676222b54 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -185,6 +185,7 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
_sync_position = other->_sync_position;
}
+
for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) {
if (unique_srcs.find (*i) == unique_srcs.end()) {
(*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
@@ -388,6 +389,7 @@ Region::set_name (const std::string& str)
void
Region::set_length (nframes_t len, void *src)
{
+ //cerr << "Region::set_length() len = " << len << endl;
if (_flags & Locked) {
return;
}
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index 84d8167240..88925a7f16 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -72,7 +72,7 @@ RegionFactory::create (boost::shared_ptr<const Region> region)
{
boost::shared_ptr<const AudioRegion> ar;
boost::shared_ptr<const MidiRegion> mr;
-
+
if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
boost::shared_ptr<Region> ret (new AudioRegion (ar));
/* pure copy constructor - no CheckNewRegion emitted */
@@ -101,7 +101,11 @@ boost::shared_ptr<Region>
RegionFactory::create (Session& session, XMLNode& node, bool yn)
{
boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn);
- CheckNewRegion (r);
+
+ if (r) {
+ CheckNewRegion (r);
+ }
+
return r;
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index e655efedb2..638c026056 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -813,7 +813,7 @@ Route::set_mute (bool yn, void *src)
int
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return 1;
@@ -827,8 +827,15 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
//processor->set_default_type(_default_type);
+ _processors.push_back (processor);
+
+ if (_reset_processor_counts (err)) {
+ _processors.pop_back ();
+ _reset_processor_counts (0); // it worked before we tried to add it ...
+ return -1;
+ }
+
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
- pi->set_count (1);
if (pi->natural_input_streams() == ChanCount::ZERO) {
/* generator plugin */
@@ -841,15 +848,22 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
// Set up processor list channels. This will set processor->[input|output]_streams(),
// configure redirect ports properly, etc.
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
_processors.pop_back ();
- _reset_plugin_counts (0); // it worked before we tried to add it ...
+ _reset_processor_counts (0); // it worked before we tried to add it ...
return -1;
}
// Ensure peak vector sizes before the plugin is activated
- ChanCount potential_max_streams = max(processor->input_streams(), processor->output_streams());
- _meter->configure_io(potential_max_streams, potential_max_streams);
+
+ ChanCount potential_max_streams;
+
+ potential_max_streams.set (DataType::AUDIO, max (processor->input_streams().n_audio(),
+ processor->output_streams().n_audio()));
+ potential_max_streams.set (DataType::MIDI, max (processor->input_streams().n_midi(),
+ processor->output_streams().n_midi()));
+
+ _meter->configure_io (potential_max_streams, potential_max_streams);
processor->activate ();
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
@@ -857,7 +871,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
_user_latency = 0;
}
- if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+ if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
reset_panner ();
}
@@ -869,7 +883,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
int
Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return 1;
@@ -896,14 +910,14 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
}
// Ensure peak vector sizes before the plugin is activated
- _meter->configure_io(potential_max_streams, potential_max_streams);
+ _meter->configure_io (potential_max_streams, potential_max_streams);
_processors.push_back (*i);
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
++existing_end;
_processors.erase (existing_end, _processors.end());
- _reset_plugin_counts (0); // it worked before we tried to add it ...
+ _reset_processor_counts (0); // it worked before we tried to add it ...
return -1;
}
@@ -914,7 +928,7 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
_user_latency = 0;
}
- if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+ if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
reset_panner ();
}
@@ -1064,7 +1078,7 @@ Route::pre_fader_streams() const
void
Route::clear_processors (Placement p)
{
- const ChanCount old_rmo = processor_max_outs;
+ const ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return;
@@ -1088,7 +1102,7 @@ Route::clear_processors (Placement p)
}
/* FIXME: can't see how this test can ever fire */
- if (processor_max_outs != old_rmo) {
+ if (processor_max_outs != old_pmo) {
reset_panner ();
}
@@ -1100,7 +1114,7 @@ Route::clear_processors (Placement p)
int
Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return 1;
@@ -1118,7 +1132,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
ProcessorList::iterator tmp;
- /* move along, see failure case for reset_plugin_counts()
+ /* move along, see failure case for reset_processor_counts()
where we may need to reprocessor the processor.
*/
@@ -1152,30 +1166,29 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
return 1;
}
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
/* get back to where we where */
_processors.insert (i, processor);
/* we know this will work, because it worked before :) */
- _reset_plugin_counts (0);
+ _reset_processor_counts (0);
return -1;
}
- bool foo = false;
+ _have_internal_generator = false;
for (i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
if (pi->is_generator()) {
- foo = true;
+ _have_internal_generator = true;
+ break;
}
}
}
-
- _have_internal_generator = foo;
}
- if (old_rmo != processor_max_outs) {
+ if (old_pmo != processor_max_outs) {
reset_panner ();
}
@@ -1186,27 +1199,32 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
}
int
-Route::reset_plugin_counts (ProcessorStreams* err)
+Route::reset_processor_counts (ProcessorStreams* err)
{
Glib::RWLock::WriterLock lm (_processor_lock);
- return _reset_plugin_counts (err);
+ return _reset_processor_counts (err);
}
int
-Route::_reset_plugin_counts (ProcessorStreams* err)
+Route::_reset_processor_counts (ProcessorStreams* err)
{
ProcessorList::iterator r;
- map<Placement,list<ProcessorCount> > processor_map;
- ChanCount initial_streams;
- ChanCount post_fader_input;
+ uint32_t insert_cnt = 0;
+ uint32_t send_cnt = 0;
+ map<Placement,list<ProcessorCount> > proc_map;
+ ProcessorList::iterator prev;
+ ChanCount initial_streams = n_inputs ();
+ ChanCount previous_initial_streams = n_inputs ();
int ret = -1;
+ uint32_t max_audio = 0;
+ uint32_t max_midi = 0;
- /* Process each placement in order, checking to see if we
- can really do what has been requested.
- */
+ processor_max_outs.reset ();
- /* divide processors up by placement so we get the signal flow
+ /* Step 1: build a map that links each insert to an in/out channel count
+
+ Divide inserts up by placement so we get the signal flow
properly modelled. we need to do this because the _processors
list is not sorted by placement, and because other reasons may
exist now or in the future for this separate treatment.
@@ -1216,60 +1234,146 @@ Route::_reset_plugin_counts (ProcessorStreams* err)
for (r = _processors.begin(); r != _processors.end(); ++r) {
- boost::shared_ptr<Processor> processor;
+ boost::shared_ptr<PluginInsert> plugin_insert;
+ boost::shared_ptr<PortInsert> port_insert;
+
+ if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert>(*r)) != 0) {
+
+ ++insert_cnt;
+ proc_map[(*r)->placement()].push_back (ProcessorCount (*r));
+
+ /* reset plugin counts back to one for now so
+ that we have a predictable, controlled
+ state to try to configure.
+ */
- if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) {
- processor_map[processor->placement()].push_back (ProcessorCount (processor));
+ plugin_insert->set_count (1);
+
+ } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert>(*r)) != 0) {
+
+ ++insert_cnt;
+ proc_map[(*r)->placement()].push_back (ProcessorCount (*r));
+
+ } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
+ ++send_cnt;
}
}
+ if (insert_cnt == 0) {
+ if (send_cnt) {
+ goto recompute;
+ } else {
+ ret = 0;
+ goto streamcount;
+ }
+ }
+
+ /* Now process each placement in order, checking to see if we
+ can really do what has been requested.
+ */
+
/* A: PreFader */
- if ( ! check_some_plugin_counts (processor_map[PreFader], n_inputs (), err)) {
+ if (check_some_processor_counts (proc_map[PreFader], n_inputs (), err)) {
goto streamcount;
}
- post_fader_input = (err ? err->count : n_inputs());
+ if (!proc_map[PreFader].empty()) {
+ previous_initial_streams = n_inputs ();
+ for (list<ProcessorCount>::iterator i = proc_map[PreFader].begin(); i != proc_map[PreFader].end(); i++) {
+ if (i->processor->can_support_io_configuration (previous_initial_streams, initial_streams) < 0) {
+ goto streamcount;
+ }
+ previous_initial_streams = initial_streams;
+ }
+ }
/* B: PostFader */
- if ( ! check_some_plugin_counts (processor_map[PostFader], post_fader_input, err)) {
+ if (check_some_processor_counts (proc_map[PostFader], initial_streams, err)) {
goto streamcount;
}
+ if (!proc_map[PostFader].empty()) {
+ for (list<ProcessorCount>::iterator i = proc_map[PostFader].begin(); i != proc_map[PostFader].end(); i++) {
+ if (i->processor->can_support_io_configuration (previous_initial_streams, initial_streams) < 0) {
+ goto streamcount;
+ }
+ previous_initial_streams = initial_streams;
+ }
+ }
+
/* OK, everything can be set up correctly, so lets do it */
- apply_some_plugin_counts (processor_map[PreFader]);
- apply_some_plugin_counts (processor_map[PostFader]);
+ apply_some_processor_counts (proc_map[PreFader]);
+ apply_some_processor_counts (proc_map[PostFader]);
/* recompute max outs of any processor */
ret = 0;
- streamcount:
- processor_max_outs.reset();
+ recompute:
- for (r = _processors.begin(); r != _processors.end(); ++r) {
- processor_max_outs = max ((*r)->output_streams (), processor_max_outs);
+ processor_max_outs.reset ();
+ prev = _processors.end();
+
+ for (r = _processors.begin(); r != _processors.end(); prev = r, ++r) {
+ boost::shared_ptr<Send> s;
+
+ if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
+ if (r == _processors.begin()) {
+ s->expect_inputs (n_inputs());
+ } else {
+ s->expect_inputs ((*prev)->output_streams());
+ }
+
+ } else {
+
+ /* don't pay any attention to send output configuration, since it doesn't
+ affect the route.
+ */
+
+ max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
+ max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
+ }
}
+ processor_max_outs.set (DataType::AUDIO, max_audio);
+ processor_max_outs.set (DataType::MIDI, max_midi);
+
+ /* we're done */
return 0;
+
+ streamcount:
+ for (r = _processors.begin(); r != _processors.end(); ++r) {
+ max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
+ max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
+ }
+
+ processor_max_outs.set (DataType::AUDIO, max_audio);
+ processor_max_outs.set (DataType::MIDI, max_midi);
+
+ return ret;
}
int32_t
-Route::apply_some_plugin_counts (list<ProcessorCount>& iclist)
+Route::apply_some_processor_counts (list<ProcessorCount>& iclist)
{
list<ProcessorCount>::iterator i;
-
+
for (i = iclist.begin(); i != iclist.end(); ++i) {
-
- cerr << "now applying for " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl;
- if ((*i).processor->configure_io ((*i).in, (*i).out)) {
+ ProcessorCount& pc (*i);
+
+ cerr << "now applying for " << (*i).processor->name() << " in = " << pc.in.n_audio() << " out = " << pc.out.n_audio() << endl;
+
+ if (pc.processor->configure_io (pc.in, pc.out)) {
return -1;
}
+
/* make sure that however many we have, they are all active */
- (*i).processor->activate ();
+
+ pc.processor->activate ();
}
return 0;
@@ -1281,7 +1385,7 @@ Route::apply_some_plugin_counts (list<ProcessorCount>& iclist)
* Otherwise, \a err is set to the output of the list.
*/
bool
-Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err)
+Route::check_some_processor_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err)
{
list<ProcessorCount>::iterator i;
size_t index = 0;
@@ -1291,12 +1395,11 @@ Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount require
err->count = required_inputs;
}
- for (i = iclist.begin(); i != iclist.end(); ++i) {
-
+ for (i = iclist.begin(); i != iclist.end(); ++i, ++index) {
cerr << "Checking whether " << (*i).processor->name() << " can support " << required_inputs.n_audio() << " inputs\n";
- if ((*i).processor->can_support_input_configuration (required_inputs) < 0) {
+ if (!(*i).processor->can_support_io_configuration (required_inputs, (*i).out)) {
if (err) {
err->index = index;
err->count = required_inputs;
@@ -1305,20 +1408,7 @@ Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount require
}
(*i).in = required_inputs;
- (*i).out = (*i).processor->output_for_input_configuration (required_inputs);
-
- cerr << "config looks like " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl;
-
required_inputs = (*i).out;
-
- ++index;
- }
-
- if (err) {
- if (!iclist.empty()) {
- err->index = index;
- err->count = iclist.back().processor->output_for_input_configuration(required_inputs);
- }
}
return true;
@@ -1327,7 +1417,7 @@ Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount require
int
Route::copy_processors (const Route& other, Placement placement, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
ProcessorList to_be_deleted;
@@ -1362,7 +1452,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream
/* reset plugin stream handling */
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
/* FAILED COPY ATTEMPT: we have to restore order */
@@ -1383,7 +1473,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream
/* restore the natural order */
_processors = the_copy;
- processor_max_outs = old_rmo;
+ processor_max_outs = old_pmo;
/* we failed, even though things are OK again */
@@ -1397,7 +1487,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream
}
}
- if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+ if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
reset_panner ();
}
@@ -1457,7 +1547,7 @@ Route::sort_processors (ProcessorStreams* err)
{
ProcessorSorter comparator;
Glib::RWLock::WriterLock lm (_processor_lock);
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
/* the sweet power of C++ ... */
@@ -1465,9 +1555,9 @@ Route::sort_processors (ProcessorStreams* err)
_processors.sort (comparator);
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
_processors = as_it_was_before;
- processor_max_outs = old_rmo;
+ processor_max_outs = old_pmo;
return -1;
}
}
@@ -2334,7 +2424,7 @@ void
Route::input_change_handler (IOChange change, void *ignored)
{
if (change & ConfigurationChanged) {
- reset_plugin_counts (0);
+ reset_processor_counts (0);
}
}
@@ -2346,7 +2436,7 @@ Route::output_change_handler (IOChange change, void *ignored)
_control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().n_audio()), true, this);
}
- reset_plugin_counts (0);
+ reset_processor_counts (0);
}
}
@@ -2540,6 +2630,11 @@ Route::update_total_latency ()
}
}
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+ cerr << _name << ": internal redirect latency = " << _own_latency << endl;
+#endif
+
set_port_latency (_own_latency);
if (!_user_latency) {
@@ -2558,6 +2653,11 @@ Route::update_total_latency ()
signal_latency_changed (); /* EMIT SIGNAL */
}
+#ifdef DEBUG_LATENCY
+ cerr << _name << ": input latency = " << input_latency() << " total = "
+ << _own_latency << endl;
+#endif
+
return _own_latency;
}
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 736a443c72..a80e99a1ee 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -156,13 +156,13 @@ Send::set_metering (bool yn)
}
bool
-Send::can_support_input_configuration (ChanCount in) const
+Send::can_support_io_configuration (const ChanCount& in, ChanCount& out_is_ignored) const
{
if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
/* not configured yet */
- return true; /* we can support anything the first time we're asked */
+ return 1; /* we can support anything the first time we're asked */
} else {
@@ -171,42 +171,35 @@ Send::can_support_input_configuration (ChanCount in) const
*/
if (_io->output_maximum() == in) {
-
- return true;
+ return 1;
}
}
- return false;
-}
-
-ChanCount
-Send::output_for_input_configuration (ChanCount in) const
-{
- // from the internal (Insert) perspective a Send does not modify its input whatsoever
- return in;
+ return -1;
}
bool
Send::configure_io (ChanCount in, ChanCount out)
{
/* we're transparent no matter what. fight the power. */
- if (out != in)
+
+ if (out != in) {
return false;
+ }
_io->set_output_maximum (in);
_io->set_output_minimum (in);
_io->set_input_maximum (ChanCount::ZERO);
_io->set_input_minimum (ChanCount::ZERO);
- bool success = _io->ensure_io (ChanCount::ZERO, in, false, this) == 0;
-
- if (success) {
- Processor::configure_io(in, out);
- _io->reset_panner();
- return true;
- } else {
+ if (_io->ensure_io (ChanCount::ZERO, in, false, this) != 0) {
return false;
}
+
+ Processor::configure_io(in, out);
+ _io->reset_panner();
+
+ return true;
}
ChanCount
@@ -226,3 +219,11 @@ Send::input_streams() const
}
+void
+Send::expect_inputs (const ChanCount& expected)
+{
+ if (expected != expected_inputs) {
+ expected_inputs = expected;
+ _io->reset_panner ();
+ }
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 1124b8960f..311e272903 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -115,9 +115,9 @@ sigc::signal<void> Session::SendFeedback;
sigc::signal<void> Session::SMPTEOffsetChanged;
sigc::signal<void> Session::StartTimeChanged;
sigc::signal<void> Session::EndTimeChanged;
-
sigc::signal<void> Session::AutoBindingOn;
sigc::signal<void> Session::AutoBindingOff;
+sigc::signal<void, std::string, std::string> Session::Exported;
Session::Session (AudioEngine &eng,
const string& fullpath,
@@ -140,6 +140,7 @@ Session::Session (AudioEngine &eng,
diskstreams (new DiskstreamList),
routes (new RouteList),
auditioner ((Auditioner*) 0),
+ _total_free_4k_blocks (0),
_bundle_xml_node (0),
_click_io ((IO*) 0),
main_outs (0)
@@ -152,8 +153,8 @@ Session::Session (AudioEngine &eng,
cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
- n_physical_outputs = _engine.n_physical_outputs();
- n_physical_inputs = _engine.n_physical_inputs();
+ n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
+ n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
first_stage_init (fullpath, snapshot_name);
@@ -210,6 +211,7 @@ Session::Session (AudioEngine &eng,
midi_requests (16),
diskstreams (new DiskstreamList),
routes (new RouteList),
+ _total_free_4k_blocks (0),
_bundle_xml_node (0),
main_outs (0)
@@ -222,8 +224,8 @@ Session::Session (AudioEngine &eng,
cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
- n_physical_outputs = _engine.n_physical_outputs();
- n_physical_inputs = _engine.n_physical_inputs();
+ n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
+ n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
if (n_physical_inputs) {
n_physical_inputs = max (requested_physical_in, n_physical_inputs);
@@ -1086,6 +1088,12 @@ Session::handle_locations_changed (Locations::LocationList& locations)
set_loop = true;
}
+ if (location->is_start()) {
+ start_location = location;
+ }
+ if (location->is_end()) {
+ end_location = location;
+ }
}
if (!set_loop) {
@@ -1523,16 +1531,16 @@ Session::new_midi_track (TrackMode mode, uint32_t how_many)
}
}
- /*
+#if 0
vector<string> physinputs;
vector<string> physoutputs;
+
+ _engine.get_physical_outputs (DataType::MIDI, physoutputs);
+ _engine.get_physical_inputs (DataType::MIDI, physinputs);
uint32_t nphysical_in;
uint32_t nphysical_out;
-
- _engine.get_physical_outputs (physoutputs);
- _engine.get_physical_inputs (physinputs);
- control_id = ntracks() + nbusses() + 1;
- */
+ control_id = ntracks() + nbusses();
+#endif
while (how_many) {
@@ -1555,7 +1563,7 @@ Session::new_midi_track (TrackMode mode, uint32_t how_many)
} while (track_id < (UINT_MAX-1));
/*
- if (Config->get_input_auto_connect() & AutoConnectPhysical) {
+ if (Config->get_input_auto_connect() & AutoConnectPhysical) {
nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
} else {
nphysical_in = 0;
@@ -1703,8 +1711,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
uint32_t nphysical_in;
uint32_t nphysical_out;
- _engine.get_physical_outputs (physoutputs);
- _engine.get_physical_inputs (physinputs);
+ _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
+ _engine.get_physical_inputs (DataType::AUDIO, physinputs);
control_id = ntracks() + nbusses() + 1;
while (how_many) {
@@ -1889,8 +1897,8 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
vector<string> physinputs;
vector<string> physoutputs;
- _engine.get_physical_outputs (physoutputs);
- _engine.get_physical_inputs (physinputs);
+ _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
+ _engine.get_physical_inputs (DataType::AUDIO, physinputs);
control_id = ntracks() + nbusses() + 1;
while (how_many) {
@@ -2418,6 +2426,8 @@ Session::get_maximum_extent () const
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ if ((*i)->destructive()) //ignore tape tracks when getting max extents
+ continue;
boost::shared_ptr<Playlist> pl = (*i)->playlist();
if ((me = pl->get_maximum_extent()) > max) {
max = me;
@@ -2509,7 +2519,7 @@ Session::new_region_name (string old)
}
int
-Session::region_name (string& result, string base, bool newlevel) const
+Session::region_name (string& result, string base, bool newlevel)
{
char buf[16];
string subbase;
@@ -2521,15 +2531,11 @@ Session::region_name (string& result, string base, bool newlevel) const
Glib::Mutex::Lock lm (region_lock);
snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
-
-
result = "region.";
result += buf;
} else {
- /* XXX this is going to be slow. optimize me later */
-
if (newlevel) {
subbase = base;
} else {
@@ -2543,37 +2549,25 @@ Session::region_name (string& result, string base, bool newlevel) const
}
- bool name_taken = true;
-
{
Glib::Mutex::Lock lm (region_lock);
- for (int n = 1; n < 5000; ++n) {
-
- result = subbase;
- snprintf (buf, sizeof (buf), ".%d", n);
- result += buf;
+ map<string,uint32_t>::iterator x;
- name_taken = false;
+ result = subbase;
- for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- if (i->second->name() == result) {
- name_taken = true;
- break;
- }
- }
+ if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
+ result += ".1";
+ region_name_map[subbase] = 1;
+ } else {
+ x->second++;
+ snprintf (buf, sizeof (buf), ".%d", x->second);
- if (!name_taken) {
- break;
- }
+ result += buf;
}
}
-
- if (name_taken) {
- fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
- /*NOTREACHED*/
- }
}
+
return 0;
}
@@ -2635,7 +2629,7 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
add the region to the region list.
*/
- set_dirty();
+ set_dirty ();
if (added) {
@@ -2660,6 +2654,8 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
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)));
+
+ update_region_name_map (region);
}
if (!v.empty()) {
@@ -2669,6 +2665,25 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
}
void
+Session::update_region_name_map (boost::shared_ptr<Region> region)
+{
+ string::size_type last_period = region->name().find_last_of ('.');
+
+ if (last_period != string::npos && last_period < region->name().length() - 1) {
+
+ string base = region->name().substr (0, last_period);
+ string number = region->name().substr (last_period+1);
+ map<string,uint32_t>::iterator x;
+
+ /* note that if there is no number, we get zero from atoi,
+ which is just fine
+ */
+
+ region_name_map[base] = atoi (number);
+ }
+}
+
+void
Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
{
boost::shared_ptr<Region> region (weak_region.lock ());
@@ -2681,6 +2696,10 @@ Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_regio
/* relay hidden changes */
RegionHiddenChange (region);
}
+
+ if (what_changed & NameChanged) {
+ update_region_name_map (region);
+ }
}
void
@@ -4022,11 +4041,11 @@ Session::freeze (InterThreadInfo& itt)
return 0;
}
-int
-Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
- bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
+boost::shared_ptr<Region>
+Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
+ bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
{
- int ret = -1;
+ boost::shared_ptr<Region> result;
boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<AudioFileSource> fsource;
uint32_t x;
@@ -4038,6 +4057,13 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
BufferSet buffers;
SessionDirectory sdir(get_best_session_directory_for_new_source ());
const string sound_dir = sdir.sound_path().to_string();
+ nframes_t len = end - start;
+
+ if (end <= start) {
+ error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
+ end, start) << endmsg;
+ return result;
+ }
// any bigger than this seems to cause stack overflows in called functions
const nframes_t chunk_size = (128 * 1024)/4;
@@ -4142,21 +4168,19 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
/* construct a region to represent the bounced material */
- boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
- region_name_from_path (srcs.front()->name(), true));
-
- ret = 0;
+ result = RegionFactory::create (srcs, 0, srcs.front()->length(),
+ region_name_from_path (srcs.front()->name(), true));
}
out:
- if (ret) {
+ if (!result) {
for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
if (afs) {
afs->mark_for_remove ();
}
-
+
(*src)->drop_references ();
}
@@ -4171,7 +4195,7 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
g_atomic_int_set (&processing_prohibited, 0);
- return ret;
+ return result;
}
BufferSet&
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index ec5de23caf..eac71fb5d1 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -171,7 +171,8 @@ Session::butler_thread_work ()
uint32_t err = 0;
int32_t bytes;
bool compute_io;
- struct timeval begin, end;
+ microseconds_t begin, end;
+
struct pollfd pfd[1];
bool disk_work_outstanding = false;
DiskstreamList::iterator i;
@@ -248,7 +249,7 @@ Session::butler_thread_work ()
bytes = 0;
compute_io = true;
- gettimeofday (&begin, 0);
+ begin = get_microseconds();
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
@@ -295,17 +296,16 @@ Session::butler_thread_work ()
}
if (compute_io) {
- gettimeofday (&end, 0);
-
- double b = begin.tv_sec + (begin.tv_usec/1000000.0);
- double e = end.tv_sec + (end.tv_usec / 1000000.0);
-
- _read_data_rate = bytes / (e - b);
+ end = get_microseconds();
+ if(end-begin > 0) {
+ _read_data_rate = (float) bytes / (float) (end - begin);
+ } else { _read_data_rate = 0; // infinity better
+ }
}
bytes = 0;
compute_io = true;
- gettimeofday (&begin, 0);
+ begin = get_microseconds();
for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
@@ -349,12 +349,13 @@ Session::butler_thread_work ()
}
if (compute_io) {
- gettimeofday (&end, 0);
-
- double b = begin.tv_sec + (begin.tv_usec/1000000.0);
- double e = end.tv_sec + (end.tv_usec / 1000000.0);
-
- _write_data_rate = bytes / (e - b);
+ // there are no apparent users for this calculation?
+ end = get_microseconds();
+ if(end-begin > 0) {
+ _write_data_rate = (float) bytes / (float) (end - begin);
+ } else {
+ _write_data_rate = 0; // Well, infinity would be better
+ }
}
if (!disk_work_outstanding) {
@@ -421,7 +422,7 @@ Session::read_data_rate () const
/* disk i/o in excess of 10000MB/sec indicate the buffer cache
in action. ignore it.
*/
- return _read_data_rate > 10485760000.0f ? 0.0f : _read_data_rate;
+ return _read_data_rate > 10485.7600000f ? 0.0f : _read_data_rate;
}
float
@@ -430,7 +431,7 @@ Session::write_data_rate () const
/* disk i/o in excess of 10000MB/sec indicate the buffer cache
in action. ignore it.
*/
- return _write_data_rate > 10485760000.0f ? 0.0f : _write_data_rate;
+ return _write_data_rate > 10485.7600000f ? 0.0f : _write_data_rate;
}
uint32_t
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index e8670e7199..72bc3f23d7 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -72,7 +72,7 @@ Session::memento_command_factory(XMLNode *n)
before = new XMLNode(*n->children().front());
after = new XMLNode(*n->children().back());
child = before;
- }
+ }
if (!child)
{
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index 49b6d9b150..0111e4ed0b 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -254,6 +254,12 @@ ExportSpecification::prepare (nframes_t blocksize, nframes_t frate)
output_data = (void*) malloc (sample_bytes * out_samples_max);
}
+ pos = start_frame;
+ end_frame = end_frame;
+ total_frames = end_frame - start_frame;
+ running = true;
+ do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
+
return 0;
}
@@ -436,14 +442,10 @@ Session::start_export (ExportSpecification& spec)
return -1;
}
- spec.pos = spec.start_frame;
- spec.end_frame = spec.end_frame;
- spec.total_frames = spec.end_frame - spec.start_frame;
- spec.running = true;
- spec.do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
-
spec.freewheel_connection = _engine.Freewheel.connect (sigc::bind (mem_fun (*this, &Session::process_export), &spec));
+ cerr << "Start export at pos = " << spec.pos << endl;
+
return _engine.freewheel (true);
}
@@ -455,14 +457,14 @@ Session::stop_export (ExportSpecification& spec)
spec.freewheel_connection.disconnect ();
spec.clear (); /* resets running/stop etc */
+ Exported (spec.path, name());
+
return 0;
}
-int
-Session::prepare_to_export (ExportSpecification& spec)
+int
+Session::pre_export ()
{
- int ret = -1;
-
wait_till_butler_finished ();
/* take everyone out of awrite to avoid disasters */
@@ -475,6 +477,27 @@ Session::prepare_to_export (ExportSpecification& spec)
}
}
+ /* make sure we are actually rolling */
+
+ if (get_record_enabled()) {
+ disable_record (false);
+ }
+
+ /* no slaving */
+
+ post_export_slave = Config->get_slave_source ();
+ post_export_position = _transport_frame;
+
+ Config->set_slave_source (None);
+
+ return 0;
+}
+
+int
+Session::prepare_to_export (ExportSpecification& spec)
+{
+ int ret = -1;
+
/* get everyone to the right position */
{
@@ -490,22 +513,21 @@ Session::prepare_to_export (ExportSpecification& spec)
}
}
- /* make sure we are actually rolling */
+ cerr << "Everybdy is at " << spec.start_frame << endl;
- if (get_record_enabled()) {
- disable_record (false);
- }
+ /* we just did the core part of a locate() call above, but
+ for the sake of any GUI, put the _transport_frame in
+ the right place too.
+ */
+ _transport_frame = spec.start_frame;
_exporting = true;
-
- /* no slaving */
-
- post_export_slave = Config->get_slave_source ();
- post_export_position = _transport_frame;
-
- Config->set_slave_source (None);
- /* get transport ready */
+ /* get transport ready. note how this is calling butler functions
+ from a non-butler thread. we waited for the butler to stop
+ what it was doing earlier in Session::pre_export() and nothing
+ since then has re-awakened it.
+ */
set_transport_speed (1.0, false);
butler_transport_work ();
@@ -528,6 +550,10 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
int ret = -1;
nframes_t this_nframes;
+ cerr << "Export process at pos = " << spec->pos << " _exporting = "
+ << _exporting << " running = " << spec->running << " stop = "
+ << spec->stop << endl;
+
/* This is not required to be RT-safe because we are running while freewheeling */
if (spec->do_freewheel == false) {
@@ -545,12 +571,14 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
if (!_exporting) {
/* finished, but still freewheeling */
- process_without_events (nframes);
+ cerr << "\tExport ... not exporting yet, no_roll() for " << nframes <<endl;
+ no_roll (nframes, 0);
return 0;
}
-
+
if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) {
- process_without_events (nframes);
+ cerr << "\tExport ... not running or at end, no_roll() for " << nframes <<endl;
+ no_roll (nframes, 0);
return stop_export (*spec);
}
@@ -604,6 +632,8 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
}
}
+ cerr << "\tprocess " << nframes << endl;
+
if (spec->process (nframes)) {
goto out;
}
@@ -611,6 +641,8 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
spec->pos += nframes;
spec->progress = 1.0 - (((float) spec->end_frame - spec->pos) / spec->total_frames);
+ cerr << "\t@ " << spec->pos << " prog = " << spec->progress << endl;
+
/* and we're good to go */
ret = 0;
@@ -629,7 +661,7 @@ Session::process_export (nframes_t nframes, ExportSpecification* spec)
}
void
-Session::finalize_audio_export ()
+Session::finalize_export ()
{
_engine.freewheel (false);
_exporting = false;
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index d6890b31ae..abe802548a 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -867,18 +867,38 @@ Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset)
if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
+ /* generate silence up to the sync point, then
+ adjust nframes + offset to reflect whatever
+ is left to do.
+ */
+
no_roll (sync_offset, 0);
nframes -= sync_offset;
offset += sync_offset;
waiting_for_sync_offset = false;
if (nframes == 0) {
- return true; // done
+ return true; // done, nothing left to process
}
} else {
+
+ /* sync offset point is not within this process()
+ cycle, so just generate silence. and don't bother
+ with any fancy stuff here, just the minimal silence.
+ */
+
+ g_atomic_int_inc (&processing_prohibited);
no_roll (nframes, 0);
- return true; // done
+ g_atomic_int_dec_and_test (&processing_prohibited);
+
+ if (Config->get_locate_while_waiting_for_sync()) {
+ if (micro_locate (nframes)) {
+ /* XXX ERROR !!! XXX */
+ }
+ }
+
+ return true; // done, nothing left to process
}
return false;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index c228f3c47b..8ebf3ab07b 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -432,8 +432,9 @@ Session::setup_raid_path (string path)
AudioFileSource::set_search_path (sound_search_path.to_string ());
SMFSource::set_search_path (midi_search_path.to_string ());
+
// reset the round-robin soundfile path thingie
-
+
last_rr_session_dir = session_dirs.begin();
}
@@ -1794,6 +1795,43 @@ Session::save_template (string template_name)
return 0;
}
+int
+Session::rename_template (string old_name, string new_name)
+{
+ sys::path old_path (user_template_directory());
+ old_path /= old_name + template_suffix;
+
+ sys::path new_path(user_template_directory());
+ new_path /= new_name + template_suffix;
+
+ if (sys::exists (new_path)) {
+ warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
+ new_path.to_string()) << endmsg;
+ return -1;
+ }
+
+ try {
+ sys::rename (old_path, new_path);
+ return 0;
+ } catch (...) {
+ return -1;
+ }
+}
+
+int
+Session::delete_template (string name)
+{
+ sys::path path = user_template_directory();
+ path /= name + template_suffix;
+
+ try {
+ sys::remove (path);
+ return 0;
+ } catch (...) {
+ return -1;
+ }
+}
+
void
Session::refresh_disk_space ()
{
@@ -2009,17 +2047,13 @@ Session::XMLNamedSelectionFactory (const XMLNode& node)
string
Session::automation_dir () const
{
- string res = _path;
- res += "automation/";
- return res;
+ return Glib::build_filename (_path, "automation");
}
string
Session::analysis_dir () const
{
- string res = _path;
- res += "analysis/";
- return res;
+ return Glib::build_filename (_path, "analysis");
}
int
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 61a741d0fb..cc94595f8c 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -138,7 +138,7 @@ Session::realtime_stop (bool abort)
// FIXME: where should this really be? [DR]
//send_full_time_code();
- deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
+ deliver_mmc (MIDI::MachineControl::cmdStop, 0);
deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
if (_transport_speed < 0.0f) {
@@ -658,6 +658,25 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush,
}
}
+int
+Session::micro_locate (nframes_t distance)
+{
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ if (!(*i)->can_internal_playback_seek (distance)) {
+ return -1;
+ }
+ }
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ (*i)->internal_playback_seek (distance);
+ }
+
+ _transport_frame += distance;
+ return 0;
+}
+
void
Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
{
@@ -1314,6 +1333,11 @@ Session::update_latency_compensation (bool with_stop, bool abort)
_worst_track_latency = 0;
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+ cerr << "\n---------------------------------\nUPDATE LATENCY\n";
+#endif
+
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
@@ -1340,6 +1364,10 @@ Session::update_latency_compensation (bool with_stop, bool abort)
_engine.update_total_latencies ();
}
+#ifdef DEBUG_LATENCY
+ cerr << "\tworst was " << _worst_track_latency << endl;
+#endif
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_latency_delay (_worst_track_latency);
}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index ab090381b4..b6efe27d36 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -20,15 +20,18 @@
#include <cstring>
#include <cerrno>
#include <climits>
+#include <cstdarg>
#include <pwd.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <glibmm/miscutils.h>
+
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/utils.h>
+#include <ardour/version.h>
#include "i18n.h"
@@ -44,6 +47,22 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou
AudioFileSource::Removable|
AudioFileSource::RemovableIfEmpty|
AudioFileSource::CanRename);
+
+static void
+snprintf_bounded_null_filled (char* target, size_t target_size, char* fmt, ...)
+{
+ char buf[target_size+1];
+ va_list ap;
+
+ va_start (ap, fmt);
+ vsnprintf (buf, target_size+1, fmt, ap);
+ va_end (ap);
+
+ memset (target, 0, target_size);
+ memcpy (target, buf, target_size);
+
+}
+
SndFileSource::SndFileSource (Session& s, const XMLNode& node)
: AudioFileSource (s, node)
{
@@ -140,21 +159,8 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
_broadcast_info = new SF_BROADCAST_INFO;
memset (_broadcast_info, 0, sizeof (*_broadcast_info));
- snprintf (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
-
- struct utsname utsinfo;
-
- if (uname (&utsinfo)) {
- error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
- return;
- }
-
- snprintf (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour:%s:%s:%s:%s:%s)",
- Glib::get_real_name().c_str(),
- utsinfo.nodename,
- utsinfo.sysname,
- utsinfo.release,
- utsinfo.version);
+ snprintf_bounded_null_filled (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
+ snprintf_bounded_null_filled (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour %s)", Glib::get_real_name().c_str());
_broadcast_info->version = 1;
_broadcast_info->time_reference_low = 0;
@@ -162,7 +168,7 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
/* XXX do something about this field */
- snprintf (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
+ snprintf_bounded_null_filled (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
/* coding history is added by libsndfile */
@@ -533,25 +539,25 @@ SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow
/* random code is 9 digits */
int random_code = random() % 999999999;
+
+ snprintf_bounded_null_filled (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
+ Config->get_bwf_country_code().c_str(),
+ Config->get_bwf_organization_code().c_str(),
+ bwf_serial_number,
+ now.tm_hour,
+ now.tm_min,
+ now.tm_sec,
+ random_code);
- snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
- Config->get_bwf_country_code().c_str(),
- Config->get_bwf_organization_code().c_str(),
- bwf_serial_number,
- now.tm_hour,
- now.tm_min,
- now.tm_sec,
- random_code);
-
- snprintf (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
- 1900 + now.tm_year,
- now.tm_mon,
- now.tm_mday);
+ snprintf_bounded_null_filled (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
+ 1900 + now.tm_year,
+ now.tm_mon + 1, // move from 0..11 to 1..12
+ now.tm_mday);
- snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
- now.tm_hour,
- now.tm_min,
- now.tm_sec);
+ snprintf_bounded_null_filled (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
+ now.tm_hour,
+ now.tm_min,
+ now.tm_sec);
/* now update header position taking header offset into account */
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 5338997659..0b7c0f3d9e 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -129,10 +129,12 @@ SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks)
DataType type = DataType::AUDIO;
const XMLProperty* prop = node.property("type");
- if (prop) {
- type = DataType(prop->value());
+ if (!prop) {
+ return boost::shared_ptr<Source>();
}
+ type = DataType (prop->value());
+
if (type == DataType::AUDIO) {
try {
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 052105cc85..ed52fd70a9 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -104,6 +104,11 @@ Track::update_total_latency ()
}
}
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+ cerr << _name << ": internal redirect (final) latency = " << _own_latency << endl;
+#endif
+
set_port_latency (_own_latency);
if (old != _own_latency) {
diff --git a/libs/ardour/user_bundle.cc b/libs/ardour/user_bundle.cc
index 471d823496..b9d115bc40 100644
--- a/libs/ardour/user_bundle.cc
+++ b/libs/ardour/user_bundle.cc
@@ -23,17 +23,17 @@ ARDOUR::UserBundle::UserBundle (XMLNode const & x, bool i)
}
}
-uint32_t
+ARDOUR::ChanCount
ARDOUR::UserBundle::nchannels () const
{
Glib::Mutex::Lock lm (_ports_mutex);
- return _ports.size ();
+ return ChanCount (type(), _ports.size ());
}
const ARDOUR::PortList&
ARDOUR::UserBundle::channel_ports (uint32_t n) const
{
- assert (n < nchannels ());
+ assert (n < nchannels ().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
return _ports[n];
@@ -42,7 +42,7 @@ ARDOUR::UserBundle::channel_ports (uint32_t n) const
void
ARDOUR::UserBundle::add_port_to_channel (uint32_t c, std::string const & p)
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
PortsWillChange (c);
@@ -57,7 +57,7 @@ ARDOUR::UserBundle::add_port_to_channel (uint32_t c, std::string const & p)
void
ARDOUR::UserBundle::remove_port_from_channel (uint32_t c, std::string const & p)
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
PortsWillChange (c);
@@ -75,7 +75,7 @@ ARDOUR::UserBundle::remove_port_from_channel (uint32_t c, std::string const & p)
bool
ARDOUR::UserBundle::port_attached_to_channel (uint32_t c, std::string const & p) const
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
return std::find (_ports[c].begin(), _ports[c].end(), p) != _ports[c].end();
@@ -110,7 +110,7 @@ ARDOUR::UserBundle::set_channels (uint32_t n)
void
ARDOUR::UserBundle::remove_channel (uint32_t r)
{
- assert (r < nchannels ());
+ assert (r < nchannels ().get (type()));
ConfigurationWillChange ();
diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc
index 58443bd005..1906d92b88 100644
--- a/libs/ardour/utils.cc
+++ b/libs/ardour/utils.cc
@@ -25,6 +25,7 @@
#include <cmath>
#include <cctype>
#include <string>
+#include <cstring>
#include <cerrno>
#include <iostream>
#include <sys/types.h>
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 47b5cb4fba..11169a74de 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -20,16 +20,19 @@
#include <algorithm>
#include <vector>
#include <string>
-#include <ctype.h>
+#include <cctype>
#include <cstdlib>
#include <cstdio> // so libraptor doesn't complain
#include <cmath>
#include <dirent.h>
-#include <string.h> // for memmove
+#include <cstring> // for memmove
#include <sys/stat.h>
#include <cerrno>
+#include <glibmm/ustring.h>
+#include <glibmm/miscutils.h>
+
#include <lrdf.h>
#include <fst.h>
@@ -156,13 +159,12 @@ VSTPlugin::get_state()
/* save it to a file */
- string path;
+ Glib::ustring path = Glib::build_filename (get_user_ardour_path (), "vst");
struct stat sbuf;
sys::path user_vst_directory(user_config_directory());
user_vst_directory /= "vst";
-
path = user_vst_directory.to_string();
if (stat (path.c_str(), &sbuf)) {
@@ -187,7 +189,7 @@ VSTPlugin::get_state()
return *root;
}
- path += "something";
+ path = Glib::build_filename (path, "something");
/* store information */
diff --git a/libs/cairomm/SConscript b/libs/cairomm/SConscript
index 3af7019e52..cb3dfa9c1a 100644
--- a/libs/cairomm/SConscript
+++ b/libs/cairomm/SConscript
@@ -8,7 +8,7 @@ cairomm_files = glob.glob('cairomm/*.cc')
Import('env libraries install_prefix')
-cairomm = env.Copy()
+cairomm = env.Clone()
cairomm.Merge([libraries['cairo']])
cairomm.Append(CXXFLAGS='-DHAVE_CONFIG_H')
diff --git a/libs/clearlooks/SConscript b/libs/clearlooks/SConscript
index 3b496fb3f1..bd460f971e 100644
--- a/libs/clearlooks/SConscript
+++ b/libs/clearlooks/SConscript
@@ -19,7 +19,7 @@ libclearlooks_files = [
Import ('env install_prefix')
-clearlooks = env.Copy()
+clearlooks = env.Clone()
clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0 cairo` ',
LINKFLAGS = ' `pkg-config --libs gtk+-2.0 cairo` ')
diff --git a/libs/fst/SConscript b/libs/fst/SConscript
index bdffd959b5..576283d73c 100644
--- a/libs/fst/SConscript
+++ b/libs/fst/SConscript
@@ -8,7 +8,7 @@ import glob
fst_src = glob.glob('*.c')
Import('env install_prefix')
-fst = env.Copy(CC="winegcc")
+fst = env.Clone(CC="winegcc")
fst.Append (CPPPATH=".")
if fst['VST']:
diff --git a/libs/glibmm2/SConscript b/libs/glibmm2/SConscript
index 66434396a3..bbf65ad228 100644
--- a/libs/glibmm2/SConscript
+++ b/libs/glibmm2/SConscript
@@ -9,7 +9,7 @@ glibmm2_files = glob.glob('glib/glibmm/*.cc')
Import('env libraries install_prefix')
-glibmm2 = env.Copy()
+glibmm2 = env.Clone()
glibmm2.Merge([libraries['sigc2'], libraries['glib2']])
glibmm2.Append(LIBPATH='#libs/glibmm2',
CPPPATH='#libs/glibmm2/glib')
diff --git a/libs/glibmm2/glib/glibmmconfig.h b/libs/glibmm2/glib/glibmmconfig.h
index 4e4bfa308f..140cc376af 100644
--- a/libs/glibmm2/glib/glibmmconfig.h
+++ b/libs/glibmm2/glib/glibmmconfig.h
@@ -1,4 +1,4 @@
-/* glib/glibmmconfig.h. Generated from glibmmconfig.h.in by configure. */
+/* glib/glibmmconfig.h. Generated by configure. */
#ifndef _GLIBMM_CONFIG_H
#define _GLIBMM_CONFIG_H 1
@@ -78,7 +78,7 @@
#ifdef GLIBMM_DLL
#if defined(GLIBMM_BUILD) && defined(_WINDLL)
/* Do not dllexport as it is handled by gendef on MSVC */
- #define GLIBMM_API
+ #define GLIBMM_API
#elif !defined(GLIBMM_BUILD)
#define GLIBMM_API __declspec(dllimport)
#else
diff --git a/libs/gtkmm2/atk/SConscript b/libs/gtkmm2/atk/SConscript
index c1e5fb849e..b1f479c386 100644
--- a/libs/gtkmm2/atk/SConscript
+++ b/libs/gtkmm2/atk/SConscript
@@ -7,7 +7,7 @@ import glob
atkmm_files = glob.glob('atkmm/*.cc')
Import('env libraries install_prefix')
-atkmm = env.Copy()
+atkmm = env.Clone()
atkmm.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'] ])
libatkmm = atkmm.SharedLibrary('atkmm', atkmm_files)
diff --git a/libs/gtkmm2/gdk/SConscript b/libs/gtkmm2/gdk/SConscript
index dca82665dc..4155cc74ba 100644
--- a/libs/gtkmm2/gdk/SConscript
+++ b/libs/gtkmm2/gdk/SConscript
@@ -7,7 +7,7 @@ import glob
gdkmm2_files = glob.glob('gdkmm/*.cc')
Import('env libraries install_prefix')
-gdkmm2 = env.Copy()
+gdkmm2 = env.Clone()
gdkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['cairomm']])
gdkmm2.Append(CXXFLAGS=["-Ilibs/gtkmm2/gtk", "-DGLIBMM_EXCEPTIONS_ENABLED"])
diff --git a/libs/gtkmm2/gtk/SConscript b/libs/gtkmm2/gtk/SConscript
index 32e45a131e..217ce5d48c 100644
--- a/libs/gtkmm2/gtk/SConscript
+++ b/libs/gtkmm2/gtk/SConscript
@@ -7,7 +7,7 @@ import glob
gtkmm2_files = glob.glob('gtkmm/*.cc')
Import('env libraries install_prefix')
-gtkmm2 = env.Copy()
+gtkmm2 = env.Clone()
gtkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['atkmm'], libraries['gdkmm2'], libraries['cairomm'], libraries['gtk2-unix-print'] ])
gtkmm2.Append(CXXFLAGS = ['-DGLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED', '-DGLIBMM_PROPERTIES_ENABLED', '-DGLIBMM_EXCEPTIONS_ENABLED'])
diff --git a/libs/gtkmm2/pango/SConscript b/libs/gtkmm2/pango/SConscript
index 02d75193a0..4b7bae8d1d 100644
--- a/libs/gtkmm2/pango/SConscript
+++ b/libs/gtkmm2/pango/SConscript
@@ -7,7 +7,7 @@ import glob
pangomm_files = glob.glob('pangomm/*.cc')
Import('env libraries install_prefix')
-pangomm = env.Copy()
+pangomm = env.Clone()
pangomm.Merge([libraries['glibmm2'], libraries['pango'], libraries['sigc2'], libraries['cairomm'], libraries['cairo'], libraries['pangocairo'] ])
if pangomm['IS_OSX']:
diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript
index a0ef88e6d1..3a3bd351d7 100644
--- a/libs/gtkmm2ext/SConscript
+++ b/libs/gtkmm2ext/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix libraries i18n')
-gtkmm2ext = env.Copy()
+gtkmm2ext = env.Clone()
gtkmm2ext.Merge ([
libraries['sigc2'],
libraries['pbd'],
@@ -48,9 +48,7 @@ fastmeter.cc
focus_entry.cc
grouped_buttons.cc
gtk_ui.cc
-hexentry.cc
idle_adjustment.cc
-pathlist.cc
pixfader.cc
pixscroller.cc
popup.cc
diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc
index a3b2a13bf5..90954e57b3 100644
--- a/libs/gtkmm2ext/barcontroller.cc
+++ b/libs/gtkmm2ext/barcontroller.cc
@@ -36,7 +36,7 @@ using namespace Gtk;
using namespace Gtkmm2ext;
BarController::BarController (Gtk::Adjustment& adj,
- PBD::Controllable& mc,
+ boost::shared_ptr<PBD::Controllable> mc,
sigc::slot<void,char*,unsigned int> lc)
: adjustment (adj),
diff --git a/libs/gtkmm2ext/binding_proxy.cc b/libs/gtkmm2ext/binding_proxy.cc
index 90f95f82ef..6c60deaa8f 100644
--- a/libs/gtkmm2ext/binding_proxy.cc
+++ b/libs/gtkmm2ext/binding_proxy.cc
@@ -31,7 +31,7 @@ using namespace Gtkmm2ext;
using namespace std;
using namespace PBD;
-BindingProxy::BindingProxy (Controllable& c)
+BindingProxy::BindingProxy (boost::shared_ptr<Controllable> c)
: prompter (0),
controllable (c),
bind_button (2),
@@ -65,7 +65,7 @@ bool
BindingProxy::button_press_handler (GdkEventButton *ev)
{
if ((ev->state & bind_statemask) && ev->button == bind_button) {
- if (Controllable::StartLearning (&controllable)) {
+ if (Controllable::StartLearning (controllable.get())) {
string prompt = _("operate controller now");
if (prompter == 0) {
prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false);
@@ -73,7 +73,7 @@ BindingProxy::button_press_handler (GdkEventButton *ev)
}
prompter->set_text (prompt);
prompter->touch (); // shows popup
- learning_connection = controllable.LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
+ learning_connection = controllable->LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
}
return true;
}
@@ -95,7 +95,7 @@ bool
BindingProxy::prompter_hiding (GdkEventAny *ev)
{
learning_connection.disconnect ();
- Controllable::StopLearning (&controllable);
+ Controllable::StopLearning (controllable.get());
return false;
}
diff --git a/libs/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc
index 63c36558f1..bdd8919d36 100644
--- a/libs/gtkmm2ext/fastmeter.cc
+++ b/libs/gtkmm2ext/fastmeter.cc
@@ -25,7 +25,7 @@
#include <gtkmm2ext/fastmeter.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm/style.h>
-#include <string.h>
+#include <cstring>
#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc
index f00c6cd1e1..4ca23b0240 100644
--- a/libs/gtkmm2ext/gtk_ui.cc
+++ b/libs/gtkmm2ext/gtk_ui.cc
@@ -65,7 +65,6 @@ UI::UI (string namestr, int *argc, char ***argv)
: AbstractUI<UIRequest> (namestr, true)
{
theMain = new Main (argc, argv);
- tips = new Tooltips;
_active = false;
diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
index fe67e9ecec..5e9a6fed90 100644
--- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
@@ -34,7 +34,7 @@ class BarController : public Gtk::Frame
public:
typedef sigc::slot<void,char*,unsigned int> LabelCallback;
- BarController (Gtk::Adjustment& adj, PBD::Controllable&, LabelCallback lc = LabelCallback());
+ BarController (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable>, LabelCallback lc = LabelCallback());
virtual ~BarController () {}
@@ -63,7 +63,7 @@ class BarController : public Gtk::Frame
/* export this to allow direct connection to button events */
Gtk::Widget& event_widget() { return darea; }
- PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
protected:
Gtk::Adjustment& adjustment;
diff --git a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
index 1cde32c5ba..844dc27d08 100644
--- a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
+++ b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
@@ -32,9 +32,9 @@ namespace PBD {
class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
{
public:
- BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {}
+ BindableToggleButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
- explicit BindableToggleButton (PBD::Controllable& c, const std::string &label)
+ explicit BindableToggleButton (boost::shared_ptr<PBD::Controllable> c, const std::string &label)
: Gtkmm2ext::StatefulToggleButton (label), binding_proxy (c) {}
virtual ~BindableToggleButton() {}
@@ -48,7 +48,8 @@ class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
}
}
- PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
+
private:
BindingProxy binding_proxy;
};
@@ -56,9 +57,9 @@ class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
class BindableButton : public Gtkmm2ext::StatefulButton
{
public:
- BindableButton (PBD::Controllable& c) : binding_proxy (c) {}
+ BindableButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
- explicit BindableButton (PBD::Controllable& c, const std::string &label)
+ explicit BindableButton (boost::shared_ptr<PBD::Controllable> c, const std::string &label)
: Gtkmm2ext::StatefulButton (label), binding_proxy (c) {}
~BindableButton() {}
@@ -72,7 +73,7 @@ class BindableButton : public Gtkmm2ext::StatefulButton
}
}
- PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
private:
BindingProxy binding_proxy;
diff --git a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
index dd9b94319d..ecb95bf815 100644
--- a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
+++ b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
@@ -24,6 +24,7 @@
#include <string>
#include <gtkmm2ext/popup.h>
+#include <boost/shared_ptr.hpp>
namespace PBD {
class Controllable;
@@ -32,7 +33,7 @@ namespace PBD {
class BindingProxy : public sigc::trackable
{
public:
- BindingProxy (PBD::Controllable&);
+ BindingProxy (boost::shared_ptr<PBD::Controllable>);
virtual ~BindingProxy();
void set_bind_button_state (guint button, guint statemask);
@@ -40,11 +41,11 @@ class BindingProxy : public sigc::trackable
bool button_press_handler (GdkEventButton *);
- PBD::Controllable* get_controllable() { return &controllable; }
- protected:
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return controllable; }
+ protected:
Gtkmm2ext::PopUp* prompter;
- PBD::Controllable& controllable;
+ boost::shared_ptr<PBD::Controllable> controllable;
guint bind_button;
guint bind_statemask;
sigc::connection learning_connection;
diff --git a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
index 0c2ff0d798..22ac517672 100644
--- a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
+++ b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
@@ -31,7 +31,6 @@
#include <gtkmm/style.h>
#include <gtkmm/textbuffer.h>
#include <gtkmm/main.h>
-#include <gtkmm/tooltips.h>
#include <gdkmm/color.h>
#include <pbd/abstract_ui.h>
#include <pbd/ringbufferNPT.h>
@@ -150,7 +149,6 @@ class UI : public Receiver, public AbstractUI<UIRequest>
static pthread_t gui_thread;
bool _active;
Gtk::Main *theMain;
- Gtk::Tooltips *tips;
TextViewer *errors;
Glib::RefPtr<Gtk::TextBuffer::Tag> error_ptag;
Glib::RefPtr<Gtk::TextBuffer::Tag> error_mtag;
diff --git a/libs/gtkmm2ext/gtkmm2ext/hexentry.h b/libs/gtkmm2ext/gtkmm2ext/hexentry.h
deleted file mode 100644
index 410f54274e..0000000000
--- a/libs/gtkmm2ext/gtkmm2ext/hexentry.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- Copyright (C) 1999 Paul Barton-Davis
-
- 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.
-
-*/
-
-#ifndef __gtkmm2ext_hexentry_h__
-#define __gtkmm2ext_hexentry_h__
-
-#include <gtkmm.h>
-
-namespace Gtkmm2ext {
-
-class HexEntry : public Gtk::Entry
-
-{
- public:
- /* Take a byte-level representation of a series of hexadecimal
- values and use them to set the displayed text of the entry.
- Eg. if hexbuf[0] = 0xff and hexbuf[1] = 0xa1 and buflen = 2,
- then the text will be set to "ff a1".
- */
-
- void set_hex (unsigned char *hexbuf, unsigned int buflen);
-
- /* puts byte-level representation of current entry text
- into hexbuf, and returns number of bytes written there.
-
- NOTE: this will release the existing memory pointed to
- by hexbuf if buflen indicates that it is not long enough
- to hold the new representation, and hexbuf is not zero.
-
- If the returned length is zero, the contents of hexbuf
- are undefined.
- */
-
- unsigned int get_hex (unsigned char *hexbuf, size_t buflen);
-
- private:
- bool on_key_press_event (GdkEventKey *);
-};
-
-} /* namespace */
-
-#endif /* __gtkmm2ext_hexentry_h__ */
diff --git a/libs/gtkmm2ext/gtkmm2ext/pathlist.h b/libs/gtkmm2ext/gtkmm2ext/pathlist.h
deleted file mode 100644
index f4a5973d5a..0000000000
--- a/libs/gtkmm2ext/gtkmm2ext/pathlist.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- Copyright (C) 2006 Paul Davis
-
- 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.
-
-*/
-
-#ifndef __gtkmm2ext_pathlist_h__
-#define __gtkmm2ext_pathlist_h__
-
-#include <vector>
-#include <string>
-
-#include <gtkmm.h>
-
-namespace Gtkmm2ext {
-
-class PathList : public Gtk::VBox
-{
- public:
- PathList ();
- ~PathList () {};
-
- std::vector<std::string> get_paths ();
- void set_paths (std::vector<std::string> paths);
-
- sigc::signal<void> PathsUpdated;
-
- protected:
- Gtk::Button add_btn;
- Gtk::Button subtract_btn;
-
- void add_btn_clicked ();
- void subtract_btn_clicked ();
-
- private:
- struct PathColumns : public Gtk::TreeModel::ColumnRecord {
- PathColumns() { add (paths); }
- Gtk::TreeModelColumn<std::string> paths;
- };
- PathColumns path_columns;
-
- Glib::RefPtr<Gtk::ListStore> _store;
- Gtk::TreeView _view;
-
- void selection_changed ();
-};
-
-} // namespace Gtkmm2ext
-
-#endif // __gtkmm2ext_pathlist_h__
diff --git a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
index 60c8eef660..46f70dacd8 100644
--- a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
@@ -24,6 +24,8 @@
#include <gtkmm2ext/pixfader.h>
#include <gtkmm2ext/binding_proxy.h>
+#include <boost/shared_ptr.hpp>
+
namespace Gtkmm2ext {
class Pix;
}
@@ -39,9 +41,9 @@ class SliderController : public Gtkmm2ext::PixFader
public:
SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment* adj, int orientation,
- PBD::Controllable&,
+ boost::shared_ptr<PBD::Controllable>,
bool with_numeric = true);
-
+
virtual ~SliderController () {}
void set_value (float);
@@ -64,7 +66,7 @@ class VSliderController : public SliderController
public:
VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- PBD::Controllable&,
+ boost::shared_ptr<PBD::Controllable>,
bool with_numeric = true);
};
@@ -73,7 +75,7 @@ class HSliderController : public SliderController
public:
HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- PBD::Controllable&,
+ boost::shared_ptr<PBD::Controllable>,
bool with_numeric = true);
};
diff --git a/libs/gtkmm2ext/hexentry.cc b/libs/gtkmm2ext/hexentry.cc
deleted file mode 100644
index 9862cac435..0000000000
--- a/libs/gtkmm2ext/hexentry.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- Copyright (C) 2000 Paul Barton-Davis
-
- 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.
-
- $Id$
-*/
-
-#include <stdio.h> /* for sprintf, sigh ... */
-#include <string>
-#include <ctype.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtkmm2ext/hexentry.h>
-
-using namespace std;
-using namespace Gtkmm2ext;
-
-bool
-HexEntry::on_key_press_event (GdkEventKey *ev)
-
-{
- if ((ev->keyval >= GDK_a && ev->keyval <= GDK_f) ||
- (ev->keyval >= GDK_A && ev->keyval <= GDK_A) ||
- (ev->keyval >= GDK_0 && ev->keyval <= GDK_9) ||
- ev->keyval == GDK_space ||
- ev->keyval == GDK_Tab ||
- ev->keyval == GDK_Return ||
- ev->keyval == GDK_BackSpace ||
- ev->keyval == GDK_Delete) {
- return Gtk::Entry::on_key_press_event (ev);
- } else {
- gdk_beep ();
- return FALSE;
- }
-}
-
-
-void
-HexEntry::set_hex (unsigned char *msg, unsigned int len)
-
-{
- /* create a textual representation of the MIDI message */
-
- if (msg && len) {
- char *rep;
-
- rep = new char[(len * 3) + 1];
- for (size_t i = 0; i < len; i++) {
- sprintf (&rep[i*3], "%02x ", msg[i]);
- }
- rep[len * 3] = '\0';
- set_text (rep);
- delete [] rep;
- } else {
- set_text ("");
- }
-}
-
-unsigned int
-HexEntry::get_hex (unsigned char *hexbuf, size_t buflen)
-
-{
- int fetched_len;
- char buf[3];
- string text = get_text();
- string::size_type length = text.length ();
- string::size_type offset;
-
- fetched_len = 0;
- buf[2] = '\0';
- offset = 0;
-
- while (1) {
- offset = text.find_first_of ("abcdef0123456789", offset);
-
- if (offset == string::npos) {
- break;
- }
-
- /* grab two characters, but no more */
-
- buf[0] = text[offset];
-
- if (offset < length - 1) {
- buf[1] = text[offset+1];
- offset += 2;
- } else {
- buf[1] = '\0';
- offset += 1;
- }
-
- hexbuf[fetched_len++] = (char) strtol (buf, 0, 16);
- }
-
- return fetched_len;
-}
-
-
diff --git a/libs/gtkmm2ext/pathlist.cc b/libs/gtkmm2ext/pathlist.cc
deleted file mode 100644
index 7b3448ed5f..0000000000
--- a/libs/gtkmm2ext/pathlist.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- Copyright (C) 2006 Paul Davis
-
- 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 <gtkmm2ext/pathlist.h>
-
-#include "i18n.h"
-
-using namespace std;
-using namespace Gtkmm2ext;
-
-PathList::PathList ()
- :
- add_btn(_("+")),
- subtract_btn(_("-")),
- path_columns(),
- _store(Gtk::ListStore::create(path_columns)),
- _view(_store)
-{
- _view.append_column(_("Paths"), path_columns.paths);
- _view.set_size_request(-1, 100);
- _view.set_headers_visible (false);
-
- Gtk::ScrolledWindow* scroll = manage(new Gtk::ScrolledWindow);
- scroll->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- scroll->add(_view);
-
- add (*scroll);
-
- Gtk::HBox* btn_box = manage(new Gtk::HBox);
- btn_box->add(add_btn);
- btn_box->add(subtract_btn);
-
- add (*btn_box);
-
- add_btn.signal_clicked().connect (mem_fun(*this, &PathList::add_btn_clicked));
- subtract_btn.signal_clicked().connect (mem_fun(*this, &PathList::subtract_btn_clicked));
- _view.get_selection()->signal_changed().connect (mem_fun(*this, &PathList::selection_changed));
-}
-
-vector<string>
-PathList::get_paths ()
-{
- vector<string> paths;
-
- Gtk::TreeModel::Children children(_store->children());
-
- for (Gtk::TreeIter iter = children.begin(); iter != children.end(); ++iter) {
- Gtk::ListStore::Row row = *iter;
-
- paths.push_back(row[path_columns.paths]);
- }
-
- return paths;
-}
-
-void
-PathList::set_paths (vector<string> paths)
-{
- _store->clear();
-
- for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i) {
- Gtk::ListStore::iterator iter = _store->append();
- Gtk::ListStore::Row row = *iter;
- row[path_columns.paths] = *i;
- }
-}
-
-void
-PathList::add_btn_clicked ()
-{
- Gtk::FileChooserDialog path_chooser (_("Path Chooser"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
-
- path_chooser.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_OK);
- path_chooser.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-
- int result = path_chooser.run ();
-
- if (result == Gtk::RESPONSE_OK) {
- string pathname = path_chooser.get_filename();
-
- if (pathname.length ()) {
- Gtk::ListStore::iterator iter = _store->append ();
- Gtk::ListStore::Row row = *iter;
- row[path_columns.paths] = pathname;
-
- PathsUpdated (); // EMIT_SIGNAL
- }
- }
-}
-
-void
-PathList::subtract_btn_clicked ()
-{
- Gtk::ListStore::iterator iter = _view.get_selection()->get_selected();
- _store->erase (iter);
-
- PathsUpdated (); // EMIT_SIGNAL
-}
-
-void
-PathList::selection_changed ()
-{
- if (_view.get_selection()->count_selected_rows ()) {
- subtract_btn.set_sensitive (true);
- } else {
- subtract_btn.set_sensitive (false);
- }
-}
diff --git a/libs/gtkmm2ext/slider_controller.cc b/libs/gtkmm2ext/slider_controller.cc
index 93dfb27ae2..92fd9d078b 100644
--- a/libs/gtkmm2ext/slider_controller.cc
+++ b/libs/gtkmm2ext/slider_controller.cc
@@ -30,7 +30,7 @@ using namespace PBD;
SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj, int orientation,
- Controllable& c,
+ boost::shared_ptr<Controllable> c,
bool with_numeric)
: PixFader (image, *adj, orientation),
@@ -60,7 +60,7 @@ SliderController::on_button_press_event (GdkEventButton *ev)
VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- Controllable& control,
+ boost::shared_ptr<Controllable> control,
bool with_numeric)
: SliderController (image, adj, VERT, control, with_numeric)
@@ -76,7 +76,7 @@ VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- Controllable& control,
+ boost::shared_ptr<Controllable> control,
bool with_numeric)
: SliderController (image, adj, HORIZ, control, with_numeric)
diff --git a/libs/libgnomecanvasmm/SConscript b/libs/libgnomecanvasmm/SConscript
index 7907622287..273fbe84df 100644
--- a/libs/libgnomecanvasmm/SConscript
+++ b/libs/libgnomecanvasmm/SConscript
@@ -7,7 +7,7 @@ import glob
gnomecanvasmm_files = glob.glob('libgnomecanvasmm/*.cc')
Import('env libraries install_prefix')
-gnomecanvasmm = env.Copy()
+gnomecanvasmm = env.Clone()
gnomecanvasmm.Merge([libraries['glibmm2'],
libraries['gtk2'],
libraries['sigc2'],
diff --git a/libs/libsndfile/SConscript b/libs/libsndfile/SConscript
index 63c5285346..70cdb637b1 100644
--- a/libs/libsndfile/SConscript
+++ b/libs/libsndfile/SConscript
@@ -7,7 +7,7 @@ import glob
sndfile_files = glob.glob('src/*.c') + glob.glob('src/GSM610/*.c') + glob.glob('src/G72x/*.c')
Import('env install_prefix libraries use_flac')
-sndfile = env.Copy()
+sndfile = env.Clone()
if use_flac:
sndfile.Merge([libraries['flac'] ])
diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript
index 0915db9f3f..222e9e249a 100644
--- a/libs/midi++2/SConscript
+++ b/libs/midi++2/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env libraries install_prefix')
-midi2 = env.Copy()
+midi2 = env.Clone()
midi2.Merge([ libraries['sigc2'],
libraries['xml'],
libraries['glibmm2'],
diff --git a/libs/midi++2/midi.cc b/libs/midi++2/midi.cc
index 1d45dc57f5..f612b4707a 100644
--- a/libs/midi++2/midi.cc
+++ b/libs/midi++2/midi.cc
@@ -20,6 +20,7 @@
#include <cstring>
#include <string>
+#include <cstring>
#include <cstdlib>
#include <midi++/types.h>
diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript
index 87173f0874..4b65e3ee38 100644
--- a/libs/pbd/SConscript
+++ b/libs/pbd/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env libraries i18n install_prefix')
-pbd = env.Copy()
+pbd = env.Clone()
domain = 'libpbd'
diff --git a/libs/pbd/base_ui.cc b/libs/pbd/base_ui.cc
index 94d039ba86..0dbe6baf52 100644
--- a/libs/pbd/base_ui.cc
+++ b/libs/pbd/base_ui.cc
@@ -21,7 +21,8 @@
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
-#include <errno.h>
+#include <cerrno>
+#include <cstring>
#include <pbd/base_ui.h>
#include <pbd/error.h>
@@ -85,20 +86,20 @@ BaseUI::setup_signal_pipe ()
*/
if (pipe (signal_pipe)) {
- error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, std::strerror (errno))
+ error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, ::strerror (errno))
<< endmsg;
return -1;
}
if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) {
- error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, std::strerror (errno))
+ error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, ::strerror (errno))
<< endmsg;
return -1;
}
if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) {
- error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, std::strerror (errno))
+ error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, ::strerror (errno))
<< endmsg;
return -1;
}
diff --git a/libs/pbd/enumwriter.cc b/libs/pbd/enumwriter.cc
index 7674410ec9..7033e5f3b1 100644
--- a/libs/pbd/enumwriter.cc
+++ b/libs/pbd/enumwriter.cc
@@ -18,10 +18,10 @@
$Id$
*/
-#include <ctype.h>
+#include <cctype>
-#include <string.h>
-#include <stdlib.h>
+#include <cstring>
+#include <cstdlib>
#include <pbd/enumwriter.h>
#include <pbd/error.h>
diff --git a/libs/pbd/fpu.cc b/libs/pbd/fpu.cc
index f6850a57dc..76150824c7 100644
--- a/libs/pbd/fpu.cc
+++ b/libs/pbd/fpu.cc
@@ -1,5 +1,5 @@
#define _XOPEN_SOURCE 600
-#include <stdlib.h>
+#include <cstdlib>
#include <stdint.h>
#include <pbd/fpu.h>
diff --git a/libs/pbd/mountpoint.cc b/libs/pbd/mountpoint.cc
index acc549890a..f273146343 100644
--- a/libs/pbd/mountpoint.cc
+++ b/libs/pbd/mountpoint.cc
@@ -21,6 +21,7 @@
#include <cstdio>
#include <cstring>
#include <string>
+#include <cstring>
#include <limits.h>
#include <pbd/mountpoint.h>
diff --git a/libs/pbd/pathscanner.cc b/libs/pbd/pathscanner.cc
index eb913cc910..e12df5efac 100644
--- a/libs/pbd/pathscanner.cc
+++ b/libs/pbd/pathscanner.cc
@@ -21,6 +21,7 @@
#include <cstring>
#include <cstdlib>
#include <cstdio>
+#include <cstring>
#include <vector>
#include <dirent.h>
diff --git a/libs/pbd/pbd/functor_command.h b/libs/pbd/pbd/functor_command.h
index e335f4418e..e6c07cfdbe 100644
--- a/libs/pbd/pbd/functor_command.h
+++ b/libs/pbd/pbd/functor_command.h
@@ -44,15 +44,11 @@ class FunctorCommand : public Command
typedef typename FunctorMap::iterator FunctorMapIterator;
public:
- FunctorCommand(
- std::string functor,
- obj_type object,
- arg_type b,
- arg_type a
- ) : functor_name(functor),
- object(object),
- before(b),
- after(a)
+ FunctorCommand(std::string functor, obj_type& object, arg_type b, arg_type a)
+ : functor_name(functor)
+ , object(object)
+ , before(b)
+ , after(a)
{
method = find_functor(functor);
@@ -76,6 +72,7 @@ class FunctorCommand : public Command
std::stringstream ss;
XMLNode *node = new XMLNode("FunctorCommand");
+ node->add_property("type_name", typeid(obj_type).name());
node->add_property("functor", functor_name);
ss << before;
node->add_property("before", ss.str());
diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc
index 434429e69d..46de65153e 100644
--- a/libs/pbd/pool.cc
+++ b/libs/pbd/pool.cc
@@ -21,6 +21,7 @@
#include <cstdlib>
#include <iostream>
#include <vector>
+#include <cstdlib>
#include <pbd/pool.h>
#include <pbd/error.h>
diff --git a/libs/pbd/stacktrace.cc b/libs/pbd/stacktrace.cc
index dc9a5e18ab..39dd46be3d 100644
--- a/libs/pbd/stacktrace.cc
+++ b/libs/pbd/stacktrace.cc
@@ -30,7 +30,7 @@ PBD::trace_twb ()
#ifdef HAVE_EXECINFO
#include <execinfo.h>
-#include <stdlib.h>
+#include <cstdlib>
void
PBD::stacktrace (std::ostream& out, int levels)
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index aeff37cce7..f04b4d9431 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -21,6 +21,7 @@
#include <iostream>
#include <string>
#include <sstream>
+#include <time.h>
#include <pbd/undo.h>
#include <pbd/xml++.h>
@@ -34,6 +35,7 @@ using namespace sigc;
UndoTransaction::UndoTransaction ()
: _clearing(false)
{
+ gettimeofday (&_timestamp, 0);
}
UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
diff --git a/libs/sigc++2/SConscript b/libs/sigc++2/SConscript
index 9ac1ef48ee..8d6bc93c24 100644
--- a/libs/sigc++2/SConscript
+++ b/libs/sigc++2/SConscript
@@ -25,6 +25,7 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
'configure', 'configure.ac', 'Makefile.am', 'SConscript',
+ 'config.sub', 'config.guess',
'sigc++/Makefile.in',
'sigc++config.h',
'sigc++config.h.in',
diff --git a/libs/sigc++2/missing b/libs/sigc++2/missing
index 1c8ff7049d..894e786e16 100755
--- a/libs/sigc++2/missing
+++ b/libs/sigc++2/missing
@@ -1,9 +1,9 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
-scriptversion=2006-05-10.23
+scriptversion=2005-06-08.21
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
@@ -33,8 +33,6 @@ if test $# -eq 0; then
fi
run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
@@ -46,7 +44,7 @@ fi
msg="missing on your system"
-case $1 in
+case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
@@ -79,7 +77,6 @@ Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
@@ -109,7 +106,7 @@ esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
-case $1 in
+case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
@@ -138,7 +135,7 @@ esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
-case $1 in
+case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
@@ -167,7 +164,7 @@ WARNING: \`$1' is $msg. You should only need it if
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
- case $f in
+ case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
@@ -195,8 +192,8 @@ WARNING: \`$1' is needed, but is $msg.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
@@ -217,25 +214,25 @@ WARNING: \`$1' $msg. You should only need it if
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
+ if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
- case $LASTARG in
+ case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
+ if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
+ if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
- if test ! -f y.tab.h; then
+ if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
- if test ! -f y.tab.c; then
+ if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
@@ -247,18 +244,18 @@ WARNING: \`$1' is $msg. You should only need it if
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
- if test $# -ne 1; then
+ if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
- case $LASTARG in
+ case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
+ if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
- if test ! -f lex.yy.c; then
+ if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
@@ -270,9 +267,11 @@ WARNING: \`$1' is $msg. You should only need it if
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
@@ -290,17 +289,11 @@ WARNING: \`$1' is $msg. You should only need it if
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
@@ -324,13 +317,13 @@ WARNING: \`$1' is $msg. You should only need it if
fi
firstarg="$1"
if shift; then
- case $firstarg in
+ case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
- case $firstarg in
+ case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
diff --git a/libs/soundtouch/AAFilter.cpp b/libs/soundtouch/AAFilter.cpp
index d135218c54..d77c19d864 100644
--- a/libs/soundtouch/AAFilter.cpp
+++ b/libs/soundtouch/AAFilter.cpp
@@ -41,9 +41,9 @@
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
#include "AAFilter.h"
#include "FIRFilter.h"
diff --git a/libs/soundtouch/FIFOSampleBuffer.cpp b/libs/soundtouch/FIFOSampleBuffer.cpp
index f158ee7949..613d8f9c48 100644
--- a/libs/soundtouch/FIFOSampleBuffer.cpp
+++ b/libs/soundtouch/FIFOSampleBuffer.cpp
@@ -43,10 +43,10 @@
//
////////////////////////////////////////////////////////////////////////////////
-#include <stdlib.h>
+#include <cstdlib>
#include <memory.h>
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
#include <stdexcept>
#include "FIFOSampleBuffer.h"
diff --git a/libs/soundtouch/FIFOSamplePipe.h b/libs/soundtouch/FIFOSamplePipe.h
index d2d54d5274..bf42895c26 100644
--- a/libs/soundtouch/FIFOSamplePipe.h
+++ b/libs/soundtouch/FIFOSamplePipe.h
@@ -48,8 +48,8 @@
#ifndef FIFOSamplePipe_H
#define FIFOSamplePipe_H
-#include <assert.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cstdlib>
#include "STTypes.h"
namespace soundtouch
diff --git a/libs/soundtouch/FIRFilter.cpp b/libs/soundtouch/FIRFilter.cpp
index cc9c40d883..1723195733 100644
--- a/libs/soundtouch/FIRFilter.cpp
+++ b/libs/soundtouch/FIRFilter.cpp
@@ -40,9 +40,9 @@
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
#include <stdexcept>
#include "FIRFilter.h"
#include "cpu_detect.h"
diff --git a/libs/soundtouch/RateTransposer.cpp b/libs/soundtouch/RateTransposer.cpp
index 493d5326f2..3000e37e4a 100644
--- a/libs/soundtouch/RateTransposer.cpp
+++ b/libs/soundtouch/RateTransposer.cpp
@@ -39,10 +39,10 @@
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
+#include <cassert>
+#include <cstdlib>
+#include <cstdio>
+#include <climits>
#include "RateTransposer.h"
#include "AAFilter.h"
diff --git a/libs/soundtouch/SConscript b/libs/soundtouch/SConscript
index 417d00b347..bfd1892212 100644
--- a/libs/soundtouch/SConscript
+++ b/libs/soundtouch/SConscript
@@ -16,7 +16,7 @@ cpu_detect_x86_gcc.cpp
""")
Import('env install_prefix')
-st = env.Copy()
+st = env.Clone()
st.Append(CCFLAGS="-DHAVE_CONFIG_H -D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
libst = st.SharedLibrary('soundtouch', soundtouch_files)
diff --git a/libs/soundtouch/TDStretch.cpp b/libs/soundtouch/TDStretch.cpp
index c71c65967f..d08dbc2028 100644
--- a/libs/soundtouch/TDStretch.cpp
+++ b/libs/soundtouch/TDStretch.cpp
@@ -41,12 +41,12 @@
//
////////////////////////////////////////////////////////////////////////////////
-#include <string.h>
-#include <stdlib.h>
+#include <cstring>
+#include <cstdlib>
#include <memory.h>
-#include <limits.h>
-#include <math.h>
-#include <assert.h>
+#include <climits>
+#include <cmath>
+#include <cassert>
#include "STTypes.h"
#include "cpu_detect.h"
diff --git a/libs/surfaces/control_protocol/SConscript b/libs/surfaces/control_protocol/SConscript
index fcc11dbae3..22cb1f4961 100644
--- a/libs/surfaces/control_protocol/SConscript
+++ b/libs/surfaces/control_protocol/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-cp = env.Copy()
+cp = env.Clone()
#
# this defines the version number of libardour_cp
@@ -38,7 +38,6 @@ cp.Merge ([
libraries['pbd'],
libraries['midi++2'],
libraries['xml'],
- libraries['usb'],
libraries['glib2'],
libraries['glibmm2']
])
diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc
index 44445192be..71d5794805 100644
--- a/libs/surfaces/control_protocol/basic_ui.cc
+++ b/libs/surfaces/control_protocol/basic_ui.cc
@@ -30,6 +30,8 @@
using namespace ARDOUR;
using ARDOUR::nframes_t;
+sigc::signal<void,std::string,std::string> BasicUI::AccessAction;
+
BasicUI::BasicUI (Session& s)
: session (&s)
{
@@ -51,6 +53,17 @@ BasicUI::register_thread (std::string name)
PBD::ThreadCreated (pthread_self(), name);
}
+
+void
+BasicUI::access_action ( std::string action_path )
+{
+ int split_at = action_path.find( "/" );
+ std::string group = action_path.substr( 0, split_at );
+ std::string item = action_path.substr( split_at + 1 );
+
+ AccessAction( group, item );
+}
+
void
BasicUI::loop_toggle ()
{
diff --git a/libs/surfaces/control_protocol/control_protocol/basic_ui.h b/libs/surfaces/control_protocol/control_protocol/basic_ui.h
index 7bc6b25c32..c8b5a2a0b6 100644
--- a/libs/surfaces/control_protocol/control_protocol/basic_ui.h
+++ b/libs/surfaces/control_protocol/control_protocol/basic_ui.h
@@ -42,6 +42,8 @@ class BasicUI {
/* transport control */
void loop_toggle ();
+ void access_action ( std::string action_path );
+ static sigc::signal<void,std::string,std::string> AccessAction;
void goto_start ();
void goto_end ();
void rewind ();
diff --git a/libs/surfaces/frontier/tranzport/SConscript b/libs/surfaces/frontier/tranzport/SConscript
index 099e35de52..0f05e379cc 100644
--- a/libs/surfaces/frontier/tranzport/SConscript
+++ b/libs/surfaces/frontier/tranzport/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-tranzport = env.Copy()
+tranzport = env.Clone()
#
# this defines the version number of libardour_tranzport
diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript
index 051a61f148..833f06923a 100644
--- a/libs/surfaces/generic_midi/SConscript
+++ b/libs/surfaces/generic_midi/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-genericmidi = env.Copy()
+genericmidi = env.Clone()
#
# this defines the version number of libardour_genericmidi
diff --git a/libs/surfaces/mackie/SConscript b/libs/surfaces/mackie/SConscript
index 4882658920..45ce63d3cd 100644
--- a/libs/surfaces/mackie/SConscript
+++ b/libs/surfaces/mackie/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-mackie = env.Copy()
+mackie = env.Clone()
#
# this defines the version number of libardour_mackie
diff --git a/libs/surfaces/powermate/SConscript b/libs/surfaces/powermate/SConscript
index 504edc6031..26ecc511eb 100644
--- a/libs/surfaces/powermate/SConscript
+++ b/libs/surfaces/powermate/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-powermate = env.Copy()
+powermate = env.Clone()
#
# this defines the version number of powermate
diff --git a/libs/surfaces/powermate/powermate.cc b/libs/surfaces/powermate/powermate.cc
index 8b3051af20..6f3cf15456 100644
--- a/libs/surfaces/powermate/powermate.cc
+++ b/libs/surfaces/powermate/powermate.cc
@@ -6,9 +6,9 @@
#include <linux/input.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
+#include <cstring>
+#include <cerrno>
+#include <cstdio>
#include <unistd.h>
#include <fcntl.h>
diff --git a/libs/surfaces/tranzport/SConscript b/libs/surfaces/tranzport/SConscript
index 5e14be31d3..fddd66c95d 100644
--- a/libs/surfaces/tranzport/SConscript
+++ b/libs/surfaces/tranzport/SConscript
@@ -6,7 +6,7 @@ import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-tranzport = env.Copy()
+tranzport = env.Clone()
#
# this defines the version number of libardour_tranzport
diff --git a/libs/surfaces/tranzport/screen.cc b/libs/surfaces/tranzport/screen.cc
index ab19358868..74d6c7d528 100644
--- a/libs/surfaces/tranzport/screen.cc
+++ b/libs/surfaces/tranzport/screen.cc
@@ -18,6 +18,7 @@
*
* */
+#include <cstring>
#include <tranzport_control_protocol.h>
#include <cstring>
diff --git a/libs/vamp-plugins/Onset.cpp b/libs/vamp-plugins/Onset.cpp
new file mode 100644
index 0000000000..d475b11be9
--- /dev/null
+++ b/libs/vamp-plugins/Onset.cpp
@@ -0,0 +1,280 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Vamp feature extraction plugins using Paul Brossier's Aubio library.
+
+ Centre for Digital Music, Queen Mary, University of London.
+ This file copyright 2006 Chris Cannam.
+
+ 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. See the file
+ COPYING included with this distribution for more information.
+
+*/
+
+#include <math.h>
+#include "Onset.h"
+
+using std::string;
+using std::vector;
+using std::cerr;
+using std::endl;
+
+Onset::Onset(float inputSampleRate) :
+ Plugin(inputSampleRate),
+ m_ibuf(0),
+ m_fftgrain(0),
+ m_onset(0),
+ m_pv(0),
+ m_peakpick(0),
+ m_onsetdet(0),
+ m_onsettype(aubio_onset_complex),
+ m_threshold(0.3),
+ m_silence(-90),
+ m_channelCount(1)
+{
+}
+
+Onset::~Onset()
+{
+ if (m_onsetdet) aubio_onsetdetection_free(m_onsetdet);
+ if (m_ibuf) del_fvec(m_ibuf);
+ if (m_onset) del_fvec(m_onset);
+ if (m_fftgrain) del_cvec(m_fftgrain);
+ if (m_pv) del_aubio_pvoc(m_pv);
+ if (m_peakpick) del_aubio_peakpicker(m_peakpick);
+}
+
+string
+Onset::getIdentifier() const
+{
+ return "aubioonset";
+}
+
+string
+Onset::getName() const
+{
+ return "Aubio Onset Detector";
+}
+
+string
+Onset::getDescription() const
+{
+ return "Estimate note onset times";
+}
+
+string
+Onset::getMaker() const
+{
+ return "Paul Brossier (plugin by Chris Cannam)";
+}
+
+int
+Onset::getPluginVersion() const
+{
+ return 1;
+}
+
+string
+Onset::getCopyright() const
+{
+ return "GPL";
+}
+
+bool
+Onset::initialise(size_t channels, size_t stepSize, size_t blockSize)
+{
+ m_channelCount = channels;
+ m_stepSize = stepSize;
+ m_blockSize = blockSize;
+
+ m_ibuf = new_fvec(stepSize, channels);
+ m_onset = new_fvec(1, channels);
+ m_fftgrain = new_cvec(blockSize, channels);
+ m_pv = new_aubio_pvoc(blockSize, stepSize, channels);
+ m_peakpick = new_aubio_peakpicker(m_threshold);
+
+ m_onsetdet = new_aubio_onsetdetection(m_onsettype, blockSize, channels);
+
+ m_delay = Vamp::RealTime::frame2RealTime(4 * stepSize,
+ lrintf(m_inputSampleRate));
+
+ m_lastOnset = Vamp::RealTime::zeroTime - m_delay - m_delay;
+
+ return true;
+}
+
+void
+Onset::reset()
+{
+}
+
+size_t
+Onset::getPreferredStepSize() const
+{
+ return 512;
+}
+
+size_t
+Onset::getPreferredBlockSize() const
+{
+ return 2 * getPreferredStepSize();
+}
+
+Onset::ParameterList
+Onset::getParameterDescriptors() const
+{
+ ParameterList list;
+
+ ParameterDescriptor desc;
+ desc.identifier = "onsettype";
+ desc.name = "Onset Detection Function Type";
+ desc.minValue = 0;
+ desc.maxValue = 6;
+ desc.defaultValue = (int)aubio_onset_complex;
+ desc.isQuantized = true;
+ desc.quantizeStep = 1;
+ desc.valueNames.push_back("Energy Based");
+ desc.valueNames.push_back("Spectral Difference");
+ desc.valueNames.push_back("High-Frequency Content");
+ desc.valueNames.push_back("Complex Domain");
+ desc.valueNames.push_back("Phase Deviation");
+ desc.valueNames.push_back("Kullback-Liebler");
+ desc.valueNames.push_back("Modified Kullback-Liebler");
+ list.push_back(desc);
+
+ desc = ParameterDescriptor();
+ desc.identifier = "peakpickthreshold";
+ desc.name = "Peak Picker Threshold";
+ desc.minValue = 0;
+ desc.maxValue = 1;
+ desc.defaultValue = 0.3;
+ desc.isQuantized = false;
+ list.push_back(desc);
+
+ desc = ParameterDescriptor();
+ desc.identifier = "silencethreshold";
+ desc.name = "Silence Threshold";
+ desc.minValue = -120;
+ desc.maxValue = 0;
+ desc.defaultValue = -90;
+ desc.unit = "dB";
+ desc.isQuantized = false;
+ list.push_back(desc);
+
+ return list;
+}
+
+float
+Onset::getParameter(std::string param) const
+{
+ if (param == "onsettype") {
+ return m_onsettype;
+ } else if (param == "peakpickthreshold") {
+ return m_threshold;
+ } else if (param == "silencethreshold") {
+ return m_silence;
+ } else {
+ return 0.0;
+ }
+}
+
+void
+Onset::setParameter(std::string param, float value)
+{
+ if (param == "onsettype") {
+ switch (lrintf(value)) {
+ case 0: m_onsettype = aubio_onset_energy; break;
+ case 1: m_onsettype = aubio_onset_specdiff; break;
+ case 2: m_onsettype = aubio_onset_hfc; break;
+ case 3: m_onsettype = aubio_onset_complex; break;
+ case 4: m_onsettype = aubio_onset_phase; break;
+ case 5: m_onsettype = aubio_onset_kl; break;
+ case 6: m_onsettype = aubio_onset_mkl; break;
+ }
+ } else if (param == "peakpickthreshold") {
+ m_threshold = value;
+ } else if (param == "silencethreshold") {
+ m_silence = value;
+ }
+}
+
+Onset::OutputList
+Onset::getOutputDescriptors() const
+{
+ OutputList list;
+
+ OutputDescriptor d;
+ d.identifier = "onsets";
+ d.name = "Onsets";
+ d.unit = "";
+ d.hasFixedBinCount = true;
+ d.binCount = 0;
+ d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
+ list.push_back(d);
+
+ d = OutputDescriptor();
+ d.identifier = "detectionfunction";
+ d.name = "Onset Detection Function";
+ d.unit = "";
+ d.hasFixedBinCount = true;
+ d.binCount = m_channelCount;
+ d.hasKnownExtents = false;
+ d.isQuantized = false;
+ d.sampleType = OutputDescriptor::OneSamplePerStep;
+ list.push_back(d);
+
+ return list;
+}
+
+Onset::FeatureSet
+Onset::process(const float *const *inputBuffers,
+ Vamp::RealTime timestamp)
+{
+ for (size_t i = 0; i < m_stepSize; ++i) {
+ for (size_t j = 0; j < m_channelCount; ++j) {
+ fvec_write_sample(m_ibuf, inputBuffers[j][i], j, i);
+ }
+ }
+
+ aubio_pvoc_do(m_pv, m_ibuf, m_fftgrain);
+ aubio_onsetdetection(m_onsetdet, m_fftgrain, m_onset);
+
+ bool isonset = aubio_peakpick_pimrt(m_onset, m_peakpick);
+
+ if (isonset) {
+ if (aubio_silence_detection(m_ibuf, m_silence)) {
+ isonset = false;
+ }
+ }
+
+ FeatureSet returnFeatures;
+
+ if (isonset) {
+ if (timestamp - m_lastOnset >= m_delay) {
+ Feature onsettime;
+ onsettime.hasTimestamp = true;
+ if (timestamp < m_delay) timestamp = m_delay;
+ onsettime.timestamp = timestamp - m_delay;
+ returnFeatures[0].push_back(onsettime);
+ m_lastOnset = timestamp;
+ }
+ }
+ Feature feature;
+ for (size_t j = 0; j < m_channelCount; ++j) {
+ feature.values.push_back(m_onset->data[j][0]);
+ }
+ returnFeatures[1].push_back(feature);
+
+ return returnFeatures;
+}
+
+Onset::FeatureSet
+Onset::getRemainingFeatures()
+{
+ return FeatureSet();
+}
+
diff --git a/libs/vamp-plugins/Onset.h b/libs/vamp-plugins/Onset.h
new file mode 100644
index 0000000000..314e107308
--- /dev/null
+++ b/libs/vamp-plugins/Onset.h
@@ -0,0 +1,73 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Vamp feature extraction plugins using Paul Brossier's Aubio library.
+
+ Centre for Digital Music, Queen Mary, University of London.
+ This file copyright 2006 Chris Cannam.
+
+ 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. See the file
+ COPYING included with this distribution for more information.
+
+*/
+
+#ifndef _ONSET_PLUGIN_H_
+#define _ONSET_PLUGIN_H_
+
+#include <vamp-sdk/Plugin.h>
+#include <aubio/aubio.h>
+
+class Onset : public Vamp::Plugin
+{
+public:
+ Onset(float inputSampleRate);
+ virtual ~Onset();
+
+ bool initialise(size_t channels, size_t stepSize, size_t blockSize);
+ void reset();
+
+ InputDomain getInputDomain() const { return TimeDomain; }
+
+ std::string getIdentifier() const;
+ std::string getName() const;
+ std::string getDescription() const;
+ std::string getMaker() const;
+ int getPluginVersion() const;
+ std::string getCopyright() const;
+
+ ParameterList getParameterDescriptors() const;
+ float getParameter(std::string) const;
+ void setParameter(std::string, float);
+
+ size_t getPreferredStepSize() const;
+ size_t getPreferredBlockSize() const;
+
+ OutputList getOutputDescriptors() const;
+
+ FeatureSet process(const float *const *inputBuffers,
+ Vamp::RealTime timestamp);
+
+ FeatureSet getRemainingFeatures();
+
+protected:
+ fvec_t *m_ibuf;
+ cvec_t *m_fftgrain;
+ fvec_t *m_onset;
+ aubio_pvoc_t *m_pv;
+ aubio_pickpeak_t *m_peakpick;
+ aubio_onsetdetection_t *m_onsetdet;
+ aubio_onsetdetection_type m_onsettype;
+ float m_threshold;
+ float m_silence;
+ size_t m_stepSize;
+ size_t m_blockSize;
+ size_t m_channelCount;
+ Vamp::RealTime m_delay;
+ Vamp::RealTime m_lastOnset;
+};
+
+
+#endif
diff --git a/libs/vamp-plugins/SConscript b/libs/vamp-plugins/SConscript
index 6b8159bd8c..d0796af092 100644
--- a/libs/vamp-plugins/SConscript
+++ b/libs/vamp-plugins/SConscript
@@ -4,17 +4,33 @@ import os
import os.path
import glob
-plugin_files = glob.glob ("*.cpp")
+plugin_files = Split("""
+plugins.cpp
+AmplitudeFollower.cpp
+PercussionOnsetDetector.cpp
+SpectralCentroid.cpp
+ZeroCrossing.cpp
+""")
+
+aubio_files = Split ("""
+Onset.cpp
+""")
Import('env install_prefix libraries')
-vampplugs = env.Copy()
+vampplugs = env.Clone()
vampplugs.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk")
vampplugs.Merge ([libraries['vamp'],
libraries['vamphost']
])
-libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', plugin_files)
+sources = plugin_files
+
+if vampplugs['AUBIO']:
+ sources += aubio_files
+ vampplugs.Merge ([libraries['aubio']])
+
+libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', sources)
Default(libvampplugins)
@@ -22,5 +38,5 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript' ] +
- plugin_files +
+ plugin_files + aubio_files +
glob.glob('*.h')))
diff --git a/libs/vamp-plugins/plugins.cpp b/libs/vamp-plugins/plugins.cpp
index 25c6e6c0d4..c45912be9b 100644
--- a/libs/vamp-plugins/plugins.cpp
+++ b/libs/vamp-plugins/plugins.cpp
@@ -41,11 +41,13 @@
#include "SpectralCentroid.h"
#include "PercussionOnsetDetector.h"
#include "AmplitudeFollower.h"
+#include "Onset.h"
static Vamp::PluginAdapter<ZeroCrossing> zeroCrossingAdapter;
static Vamp::PluginAdapter<SpectralCentroid> spectralCentroidAdapter;
static Vamp::PluginAdapter<PercussionOnsetDetector> percussionOnsetAdapter;
static Vamp::PluginAdapter<AmplitudeFollower> amplitudeAdapter;
+static Vamp::PluginAdapter<Onset> onsetAdapter;
const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
unsigned int index)
@@ -57,6 +59,7 @@ const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
case 1: return spectralCentroidAdapter.getDescriptor();
case 2: return percussionOnsetAdapter.getDescriptor();
case 3: return amplitudeAdapter.getDescriptor();
+ case 4: return onsetAdapter.getDescriptor();
default: return 0;
}
}
diff --git a/libs/vamp-sdk/SConscript b/libs/vamp-sdk/SConscript
index 79046e2fc0..be1834896b 100644
--- a/libs/vamp-sdk/SConscript
+++ b/libs/vamp-sdk/SConscript
@@ -20,7 +20,7 @@ vamp-sdk/RealTime.cpp
""")
Import('env install_prefix libraries')
-vampsdk = env.Copy()
+vampsdk = env.Clone()
vampsdk.Merge ([libraries['fftw3'], libraries['fftw3f']])
diff --git a/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
index 24f91e5f50..334c11103c 100644
--- a/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
+++ b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
@@ -34,7 +34,7 @@
authorization.
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "PluginHostAdapter.h"
namespace Vamp
diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp b/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
index 9d627a75cf..e9d75ee181 100644
--- a/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
+++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
@@ -40,6 +40,8 @@
#include "PluginChannelAdapter.h"
#include "PluginBufferingAdapter.h"
+#include <string>
+#include <cstring>
#include <fstream>
#include <cctype> // tolower
#include <cstring>