summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-01-23 13:41:20 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2014-01-23 13:41:20 -0500
commit7000afdc66c9e0ae8dcf9ec080517dabba1e7f34 (patch)
tree19574ed8a1fbafa6bed222d8cf817ee1c8098314 /libs/ardour
parent065e1e63342633f72725a5309926f71c87804293 (diff)
parent40d8c5ae01f25e02457c554170a53d537246a7d4 (diff)
fix merge conflict with master
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h4
-rw-r--r--libs/ardour/ardour/auditioner.h61
-rw-r--r--libs/ardour/ardour/internal_send.h2
-rw-r--r--libs/ardour/ardour/midi_diskstream.h5
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h1
-rw-r--r--libs/ardour/ardour/send.h4
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/audio_track.cc8
-rw-r--r--libs/ardour/auditioner.cc360
-rw-r--r--libs/ardour/internal_send.cc4
-rw-r--r--libs/ardour/lv2_plugin.cc1
-rw-r--r--libs/ardour/midi_track.cc8
-rw-r--r--libs/ardour/po/ru.po228
-rw-r--r--libs/ardour/route.cc4
-rw-r--r--libs/ardour/send.cc8
-rw-r--r--libs/ardour/session.cc15
-rw-r--r--libs/ardour/smf_source.cc101
-rw-r--r--libs/ardour/source_factory.cc7
18 files changed, 580 insertions, 244 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 6741ba0ed4..c0b78bad13 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -146,10 +146,8 @@ class LIBARDOUR_API AudioDiskstream : public Diskstream
protected:
friend class Auditioner;
- int seek (framepos_t which_sample, bool complete_refill = false);
-
- protected:
friend class AudioTrack;
+ int seek (framepos_t which_sample, bool complete_refill = false);
int process (BufferSet&, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_disk_signal);
frameoffset_t calculate_playback_distance (pframes_t nframes);
diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h
index 26e395f93e..94d4eab479 100644
--- a/libs/ardour/ardour/auditioner.h
+++ b/libs/ardour/ardour/auditioner.h
@@ -26,6 +26,10 @@
#include "ardour/ardour.h"
#include "ardour/audio_track.h"
+#include "ardour/midi_region.h"
+
+#include "ardour/audio_diskstream.h"
+#include "ardour/midi_diskstream.h"
namespace ARDOUR {
@@ -33,14 +37,14 @@ class Session;
class AudioRegion;
class AudioPlaylist;
-class LIBARDOUR_API Auditioner : public AudioTrack
+class LIBARDOUR_API Auditioner : public Track
{
public:
Auditioner (Session&);
~Auditioner ();
int init ();
- int connect ();
+ int connect ();
void audition_region (boost::shared_ptr<Region>);
@@ -63,11 +67,52 @@ class LIBARDOUR_API Auditioner : public AudioTrack
virtual ChanCount input_streams () const;
frameoffset_t seek_frame() const { return _seeking ? _seek_frame : -1;}
- void seek_response(frameoffset_t pos) { _seek_complete = true; if (_seeking) { current_frame = pos; _seek_complete = true;} }
+ void seek_response(frameoffset_t pos) {
+ _seek_complete = true;
+ if (_seeking) { current_frame = pos; _seek_complete = true;}
+ }
+
PBD::Signal2<void, ARDOUR::framecnt_t, ARDOUR::framecnt_t> AuditionProgress;
+ /* Track */
+ int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
+ DataType data_type () const;
+
+ int roll_audio (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
+ int roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
+
+ boost::shared_ptr<Diskstream> create_diskstream ();
+ void set_diskstream (boost::shared_ptr<Diskstream> ds);
+
+ /* fake track */
+ void set_state_part_two () {}
+ int set_state (const XMLNode&, int) { return 0; }
+ bool bounceable (boost::shared_ptr<Processor>, bool) const { return false; }
+ void freeze_me (InterThreadInfo&) {}
+ void unfreeze () {}
+
+ boost::shared_ptr<Region> bounce (InterThreadInfo&)
+ { return boost::shared_ptr<Region> (); }
+
+ boost::shared_ptr<Region> bounce_range (framepos_t, framepos_t, InterThreadInfo&, boost::shared_ptr<Processor>, bool)
+ { return boost::shared_ptr<Region> (); }
+
+ int export_stuff (BufferSet&, framepos_t, framecnt_t, boost::shared_ptr<Processor>, bool, bool)
+ { return -1; }
+
+ boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &)
+ { return boost::shared_ptr<Diskstream> (); }
+
+ boost::shared_ptr<AudioDiskstream> audio_diskstream() const
+ { return boost::dynamic_pointer_cast<AudioDiskstream> (_diskstream); }
+
+ boost::shared_ptr<MidiDiskstream> midi_diskstream() const
+ { return boost::dynamic_pointer_cast<MidiDiskstream> (_diskstream); }
+
+
private:
boost::shared_ptr<AudioRegion> the_region;
+ boost::shared_ptr<MidiRegion> midi_region;
framepos_t current_frame;
mutable gint _auditioning;
Glib::Threads::Mutex lock;
@@ -76,8 +121,18 @@ class LIBARDOUR_API Auditioner : public AudioTrack
bool _seeking;
bool _seek_complete;
bool via_monitor;
+ bool _midi_audition;
+ bool _synth_added;
+ bool _synth_changed;
+ bool _queue_panic;
+
+ boost::shared_ptr<Diskstream> _diskstream_audio;
+ boost::shared_ptr<Diskstream> _diskstream_midi;
+ boost::shared_ptr<Processor> asynth;
void drop_ports ();
+ void lookup_synth ();
+ void config_changed (std::string);
static void *_drop_ports (void *);
void actually_drop_ports ();
void output_changed (IOChange, void*);
diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h
index 9bfbc4c659..a06bf39906 100644
--- a/libs/ardour/ardour/internal_send.h
+++ b/libs/ardour/ardour/internal_send.h
@@ -28,7 +28,7 @@ namespace ARDOUR {
class LIBARDOUR_API InternalSend : public Send
{
public:
- InternalSend (Session&, boost::shared_ptr<Pannable>, boost::shared_ptr<MuteMaster>, boost::shared_ptr<Route> send_to, Delivery::Role role);
+ InternalSend (Session&, boost::shared_ptr<Pannable>, boost::shared_ptr<MuteMaster>, boost::shared_ptr<Route> send_to, Delivery::Role role = Delivery::Aux, bool ignore_bitslot = false);
virtual ~InternalSend ();
std::string display_name() const;
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index e3f2673871..01e8904736 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -119,10 +119,9 @@ class LIBARDOUR_API MidiDiskstream : public Diskstream
static void set_readahead_frames (framecnt_t frames_ahead) { midi_readahead = frames_ahead; }
protected:
- int seek (framepos_t which_sample, bool complete_refill = false);
-
- protected:
friend class MidiTrack;
+ friend class Auditioner;
+ int seek (framepos_t which_sample, bool complete_refill = false);
int process (BufferSet&, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_diskstream);
frameoffset_t calculate_playback_distance (pframes_t nframes);
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index adae854ca7..19500ccf74 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -114,6 +114,7 @@ CONFIG_VARIABLE (std::string, monitor_bus_preferred_bundle, "monitor-bus-preferr
CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true)
CONFIG_VARIABLE (bool, link_send_and_route_panner, "link-send-and-route-panner", true)
+CONFIG_VARIABLE (std::string, midi_audition_synth_uri, "midi-audition-synth-uri", "https://community.ardour.org/node/7596")
/* click */
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
index 9b30dcf792..a9d2c5dacd 100644
--- a/libs/ardour/ardour/send.h
+++ b/libs/ardour/ardour/send.h
@@ -35,7 +35,7 @@ class Amp;
class LIBARDOUR_API Send : public Delivery
{
public:
- Send (Session&, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster>, Delivery::Role r = Delivery::Send);
+ Send (Session&, boost::shared_ptr<Pannable> pannable, boost::shared_ptr<MuteMaster>, Delivery::Role r = Delivery::Send, bool ignore_bitslot = false);
virtual ~Send ();
uint32_t bit_slot() const { return _bitslot; }
@@ -67,7 +67,7 @@ class LIBARDOUR_API Send : public Delivery
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
static uint32_t how_many_sends();
- static std::string name_and_id_new_send (Session&, Delivery::Role r, uint32_t&);
+ static std::string name_and_id_new_send (Session&, Delivery::Role r, uint32_t&, bool);
protected:
bool _metering;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 7295828d2f..f77e09736f 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1356,9 +1356,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
private:
SourceMap sources;
- public:
- SourceMap get_sources() { return sources; }
-
private:
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index a82c109cba..8e14fff402 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -60,13 +60,7 @@ AudioTrack::~AudioTrack ()
boost::shared_ptr<Diskstream>
AudioTrack::create_diskstream ()
{
- AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
-
- if (_flags & Auditioner) {
- dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
- } else {
- dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
- }
+ AudioDiskstream::Flag dflags = AudioDiskstream::Flag (AudioDiskstream::Recordable);
if (_mode == Destructive) {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 75a40f142d..d682dc3617 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -21,17 +21,18 @@
#include "pbd/error.h"
-#include "ardour/audio_diskstream.h"
+#include "ardour/amp.h"
#include "ardour/audioregion.h"
#include "ardour/audioengine.h"
-#include "ardour/delivery.h"
-#include "ardour/route.h"
-#include "ardour/session.h"
-#include "ardour/auditioner.h"
#include "ardour/audioplaylist.h"
+#include "ardour/auditioner.h"
#include "ardour/audio_port.h"
#include "ardour/data_type.h"
+#include "ardour/delivery.h"
+#include "ardour/plugin.h"
#include "ardour/region_factory.h"
+#include "ardour/route.h"
+#include "ardour/session.h"
using namespace std;
using namespace ARDOUR;
@@ -40,37 +41,76 @@ using namespace PBD;
#include "i18n.h"
Auditioner::Auditioner (Session& s)
- : AudioTrack (s, "auditioner", Route::Auditioner)
- , current_frame (0)
- , _auditioning (0)
- , length (0)
- , _seek_frame (-1)
- , _seeking (false)
- , _seek_complete (false)
- , via_monitor (false)
+ : Track (s, "auditioner", Route::Auditioner)
+ , current_frame (0)
+ , _auditioning (0)
+ , length (0)
+ , _seek_frame (-1)
+ , _seeking (false)
+ , _seek_complete (false)
+ , via_monitor (false)
+ , _midi_audition (false)
+ , _synth_added (false)
+ , _synth_changed (false)
+ , _queue_panic (false)
{
}
int
Auditioner::init ()
{
- if (Track::init ()) {
- return -1;
- }
-
+ if (Track::init ()) {
+ return -1;
+ }
+
if (connect ()) {
return -1;
}
+ _output->add_port ("Midiaudition", this, DataType::MIDI);
+
+ lookup_synth();
+
_output->changed.connect_same_thread (*this, boost::bind (&Auditioner::output_changed, this, _1, _2));
+ Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Auditioner::config_changed, this, _1));
- return 0;
+ return 0;
}
Auditioner::~Auditioner ()
{
}
+void
+Auditioner::lookup_synth ()
+{
+ string plugin_id = Config->get_midi_audition_synth_uri();
+ asynth = boost::shared_ptr<Processor>();
+ if (!plugin_id.empty()) {
+ boost::shared_ptr<Plugin> p;
+ p = find_plugin (_session, plugin_id, ARDOUR::LV2);
+ if (!p) {
+ p = find_plugin (_session, "https://community.ardour.org/node/7596", ARDOUR::LV2);
+ if (p) {
+ warning << _("Falling back to Reasonable Synth for Midi Audition") << endmsg;
+ } else {
+ warning << _("No synth for midi-audition found.") << endmsg;
+ }
+ }
+ if (p) {
+ asynth = boost::shared_ptr<Processor> (new PluginInsert (_session, p));
+ }
+ }
+}
+
+void
+Auditioner::config_changed (std::string p)
+{
+ if (p == "midi-audition-synth-uri") {
+ _synth_changed = true;
+ }
+}
+
int
Auditioner::connect ()
{
@@ -149,9 +189,158 @@ Auditioner::connect ()
return 0;
}
+
+DataType
+Auditioner::data_type () const {
+ if (_midi_audition) {
+ return DataType::MIDI;
+ } else {
+ return DataType::AUDIO;
+ }
+}
+
+boost::shared_ptr<Diskstream>
+Auditioner::create_diskstream () {
+
+ {
+ AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
+ dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
+ _diskstream_audio = boost::shared_ptr<AudioDiskstream> (new AudioDiskstream (_session, name(), dflags));
+ }
+
+ {
+ MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
+ dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
+ _diskstream_midi = boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
+ _diskstream_midi->do_refill_with_alloc ();
+ _diskstream_midi->playlist()->set_orig_track_id (id());
+ }
+
+ return _diskstream_audio;
+}
+
+int
+Auditioner::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) {
+ if (_midi_audition) {
+ return roll_midi(nframes, start_frame, end_frame, declick, need_butler);
+ } else {
+ return roll_audio(nframes, start_frame, end_frame, declick, need_butler);
+ }
+}
+
+int
+Auditioner::roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
+{
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
+ if (!lm.locked()) {
+ return 0;
+ }
+
+ assert(_active);
+
+ framecnt_t playback_distance = nframes;
+ boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
+ MidiBuffer& mbuf (bufs.get_midi (0));
+ _silent = false;
+
+ ChanCount cnt (DataType::MIDI, 1);
+ cnt.set (DataType::AUDIO, bufs.count().n_audio());
+ bufs.set_count (cnt);
+
+ if (_queue_panic) {
+ _queue_panic = false;
+ for (uint8_t chn = 0; chn < 0xf; ++chn) {
+ uint8_t buf[3] = { ((uint8_t) (MIDI_CMD_CONTROL | chn)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
+ mbuf.push_back(0, 3, buf);
+ buf[1] = MIDI_CTL_ALL_NOTES_OFF;
+ mbuf.push_back(0, 3, buf);
+ buf[1] = MIDI_CTL_RESET_CONTROLLERS;
+ mbuf.push_back(0, 3, buf);
+ }
+ process_output_buffers (bufs, start_frame, start_frame+1, 1, false, false);
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
+ if (d) {
+ d->flush_buffers (nframes);
+ }
+ }
+ }
+
+ diskstream->get_playback (mbuf, nframes);
+
+ process_output_buffers (bufs, start_frame, end_frame, nframes,
+ declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
+ if (d) {
+ d->flush_buffers (nframes);
+ }
+ }
+
+ need_butler = diskstream->commit (playback_distance);
+ return 0;
+}
+
+
+int
+Auditioner::roll_audio (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) {
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
+ if (!lm.locked()) {
+ return 0;
+ }
+
+ assert(n_outputs().n_total() > 0);
+ assert(_active);
+
+ int dret;
+ framecnt_t playback_distance;
+ framepos_t transport_frame = _session.transport_frame();
+ boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
+ BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
+
+ _silent = false;
+ _amp->apply_gain_automation(false);
+
+ if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
+ need_butler = diskstream->commit (playback_distance);
+ silence (nframes);
+ return dret;
+ }
+
+ process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && _session.transport_rolling()));
+ need_butler = diskstream->commit (playback_distance);
+ return 0;
+}
+
+void
+Auditioner::set_diskstream (boost::shared_ptr<Diskstream> ds)
+{
+ Track::set_diskstream (ds);
+
+ _diskstream->set_track (this);
+ _diskstream->set_destructive (_mode == Destructive);
+ _diskstream->set_non_layered (_mode == NonLayered);
+ _diskstream->set_record_enabled (false);
+ _diskstream->request_input_monitoring (false);
+
+ DiskstreamChanged (); /* EMIT SIGNAL */
+}
+
AudioPlaylist&
Auditioner::prepare_playlist ()
{
+ // used by CrossfadeEditor::audition()
+
+ _midi_audition = false;
+ set_diskstream(_diskstream_audio);
+ if (_synth_added) {
+ remove_processor(asynth);
+ _synth_added = false;
+ }
+
// FIXME auditioner is still audio-only
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist());
assert(apl);
@@ -170,48 +359,109 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
cancel_audition ();
}
- if (boost::dynamic_pointer_cast<AudioRegion>(region) == 0) {
- error << _("Auditioning of non-audio regions not yet supported") << endmsg;
- return;
- }
-
Glib::Threads::Mutex::Lock lm (lock);
- /* copy it */
+ if (boost::dynamic_pointer_cast<AudioRegion>(region) != 0) {
- boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
- the_region->set_position (0);
+ _midi_audition = false;
+ set_diskstream(_diskstream_audio);
+ if (_synth_added) {
+ remove_processor(asynth);
+ _synth_added = false;
+ }
+ midi_region.reset();
- _diskstream->playlist()->drop_regions ();
- _diskstream->playlist()->add_region (the_region, 0, 1);
+ /* copy it */
+ the_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region));
+ the_region->set_position (0);
- if (_diskstream->n_channels().n_audio() < the_region->n_channels()) {
- audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels().n_audio());
- } else if (_diskstream->n_channels().n_audio() > the_region->n_channels()) {
- audio_diskstream()->remove_channel (_diskstream->n_channels().n_audio() - the_region->n_channels());
- }
+ _diskstream->playlist()->drop_regions ();
+ _diskstream->playlist()->add_region (the_region, 0, 1);
- ProcessorStreams ps;
- {
- Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ if (_diskstream->n_channels().n_audio() < the_region->n_channels()) {
+ audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels().n_audio());
+ } else if (_diskstream->n_channels().n_audio() > the_region->n_channels()) {
+ audio_diskstream()->remove_channel (_diskstream->n_channels().n_audio() - the_region->n_channels());
+ }
+
+ ProcessorStreams ps;
+ {
+ Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+
+ if (configure_processors (&ps)) {
+ error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
+ _diskstream->n_channels()) << endmsg;
+ return;
+ }
+ }
+
+ } else if (boost::dynamic_pointer_cast<MidiRegion>(region)) {
+ _midi_audition = true;
+ set_diskstream(_diskstream_midi);
+ the_region.reset();
+
+ /* copy it */
+ midi_region = (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (region)));
+ midi_region->set_position (0);
- if (configure_processors (&ps)) {
- error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
- _diskstream->n_channels()) << endmsg;
- return;
+ _diskstream->playlist()->drop_regions ();
+ _diskstream->playlist()->add_region (midi_region, 0, 1);
+ midi_diskstream()->reset_tracker();
+
+ ProcessorStreams ps;
+
+ if (_synth_changed && _synth_added) {
+ remove_processor(asynth);
+ _synth_added = false;
}
+ if (_synth_changed && !_synth_added) {
+ _synth_added = false;
+ lookup_synth();
+ }
+
+
+ if (!_synth_added && asynth) {
+ int rv = add_processor_by_index(asynth, PreFader, &ps, true);
+ if (rv) {
+ error << _("Failed to load synth for MIDI-Audition.") << endmsg;
+ } else {
+ _synth_added = true;
+ }
+ } else {
+ _queue_panic = true;
+ }
+
+ {
+ Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+
+ if (configure_processors (&ps)) {
+ error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
+ _diskstream->n_channels()) << endmsg;
+ return;
+ }
+ }
+
+ } else {
+ error << _("Auditioning of regions other than Audio or Midi is not supported.") << endmsg;
+ return;
}
/* force a panner reset now that we have all channels */
-
_main_outs->reset_panner();
_seek_frame = -1;
_seeking = false;
- length = the_region->length();
int dir;
- framecnt_t offset = the_region->sync_offset (dir);
+ framecnt_t offset;
+
+ if (_midi_audition) {
+ length = midi_region->length();
+ offset = midi_region->sync_offset (dir);
+ } else {
+ length = the_region->length();
+ offset = the_region->sync_offset (dir);
+ }
/* can't audition from a negative sync point */
@@ -249,6 +499,9 @@ Auditioner::play_audition (framecnt_t nframes)
_seek_complete = false;
_seeking = false;
_seek_frame = -1;
+ if (_midi_audition && midi_diskstream()) {
+ midi_diskstream()->reset_tracker();
+ }
}
if(!_seeking) {
@@ -267,6 +520,7 @@ Auditioner::play_audition (framecnt_t nframes)
}
if (_seek_frame >= 0 && _seek_frame < length && !_seeking) {
+ _queue_panic = true;
_seek_complete = false;
_seeking = true;
need_butler = true;
@@ -325,18 +579,22 @@ Auditioner::output_changed (IOChange change, void* /*src*/)
ChanCount
Auditioner::input_streams () const
{
- /* auditioner never has any inputs - its channel configuration
- depends solely on the region we are auditioning.
- */
+ /* auditioner never has any inputs - its channel configuration
+ depends solely on the region we are auditioning.
+ */
- if (audio_diskstream()) {
- return audio_diskstream()->n_channels();
- }
+ if (!_midi_audition && audio_diskstream()) {
+ return audio_diskstream()->n_channels();
+ }
+ if (_midi_audition && midi_diskstream()) {
+ ChanCount cnt (DataType::MIDI, 1);
+ return cnt;
+ }
- return ChanCount ();
+ return ChanCount ();
}
-MonitorState
+MonitorState
Auditioner::monitoring_state () const
{
return MonitoringDisk;
diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc
index dac1839a5e..1d4e18d06e 100644
--- a/libs/ardour/internal_send.cc
+++ b/libs/ardour/internal_send.cc
@@ -40,8 +40,8 @@ using namespace std;
PBD::Signal1<void, pframes_t> InternalSend::CycleStart;
-InternalSend::InternalSend (Session& s, boost::shared_ptr<Pannable> p, boost::shared_ptr<MuteMaster> mm, boost::shared_ptr<Route> sendto, Delivery::Role role)
- : Send (s, p, mm, role)
+InternalSend::InternalSend (Session& s, boost::shared_ptr<Pannable> p, boost::shared_ptr<MuteMaster> mm, boost::shared_ptr<Route> sendto, Delivery::Role role, bool ignore_bitslot)
+ : Send (s, p, mm, role, ignore_bitslot)
{
if (sendto) {
if (use_target (sendto)) {
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index f24aa653bb..b79e067798 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -1027,6 +1027,7 @@ LV2Plugin::load_preset(PresetRecord r)
if (state) {
lilv_state_restore(state, _impl->instance, set_port_value, this, 0, NULL);
lilv_state_free(state);
+ Plugin::load_preset(r);
}
lilv_node_free(pset);
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 6a998de90e..b820c001e1 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -80,13 +80,7 @@ MidiTrack::init ()
boost::shared_ptr<Diskstream>
MidiTrack::create_diskstream ()
{
- MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
-
- if (_flags & Auditioner) {
- dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
- } else {
- dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
- }
+ MidiDiskstream::Flag dflags = MidiDiskstream::Flag (MidiDiskstream::Recordable);
assert(_mode != Destructive);
diff --git a/libs/ardour/po/ru.po b/libs/ardour/po/ru.po
index 3748bfc18c..fca85fb393 100644
--- a/libs/ardour/po/ru.po
+++ b/libs/ardour/po/ru.po
@@ -7,11 +7,11 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-11-05 11:11-0500\n"
-"PO-Revision-Date: 2013-10-15 21:40+0300\n"
+"POT-Creation-Date: 2014-01-19 22:43+0400\n"
+"PO-Revision-Date: 2014-01-19 22:42+0300\n"
"Last-Translator: Александр Прокудин <alexandre.prokoudine@gmail.com>\n"
-"Language-Team: русский <>\n"
-"Language: \n"
+"Language-Team: \n"
+"Language: Russian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -123,8 +123,8 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
-#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
-#: rb_effect.cc:333 session.cc:2619 session.cc:2652 session.cc:3797
+#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:642
+#: rb_effect.cc:333 session.cc:2633 session.cc:2666 session.cc:3811
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
msgstr "programming error: %1"
@@ -266,15 +266,15 @@ msgstr "%1: could not write peak file data (%2)"
msgid "could not truncate peakfile %1 to %2 (error: %3)"
msgstr "could not truncate peakfile %1 to %2 (error: %3)"
-#: auditioner.cc:87
+#: auditioner.cc:112
msgid "no outputs available for auditioner - manual connection required"
msgstr ""
-#: auditioner.cc:135
+#: auditioner.cc:174
msgid "Auditioning of non-audio regions not yet supported"
msgstr ""
-#: auditioner.cc:160
+#: auditioner.cc:199
msgid "Cannot setup auditioner processing flow for %1 channels"
msgstr ""
@@ -335,43 +335,43 @@ msgstr ""
msgid "Error reading from butler request pipe"
msgstr ""
-#: butler.cc:248
+#: butler.cc:256
msgid "Butler read ahead failure on dstream %1"
msgstr ""
-#: butler.cc:285
+#: butler.cc:293
msgid "Butler write-behind failure on dstream %1"
msgstr ""
-#: control_protocol_manager.cc:134
+#: control_protocol_manager.cc:162
msgid "control protocol name \"%1\" has no descriptor"
msgstr ""
-#: control_protocol_manager.cc:141
+#: control_protocol_manager.cc:169
msgid "control protocol name \"%1\" could not be initialized"
msgstr ""
-#: control_protocol_manager.cc:201
+#: control_protocol_manager.cc:233
msgid "Instantiating mandatory control protocol %1"
msgstr ""
-#: control_protocol_manager.cc:222
+#: control_protocol_manager.cc:254
msgid "looking for control protocols in %1\n"
msgstr ""
-#: control_protocol_manager.cc:247
+#: control_protocol_manager.cc:279
msgid "Control protocol %1 not usable"
msgstr ""
-#: control_protocol_manager.cc:264
+#: control_protocol_manager.cc:296
msgid "Control surface protocol discovered: \"%1\"\n"
msgstr ""
-#: control_protocol_manager.cc:282
+#: control_protocol_manager.cc:314
msgid "ControlProtocolManager: cannot load module \"%1\" (%2)"
msgstr "ControlProtocolManager: cannot load module \"%1\" (%2)"
-#: control_protocol_manager.cc:290
+#: control_protocol_manager.cc:322
msgid "ControlProtocolManager: module \"%1\" has no descriptor function."
msgstr ""
@@ -391,7 +391,7 @@ msgstr ""
msgid "audio"
msgstr ""
-#: data_type.cc:28 session.cc:1791 session.cc:1794
+#: data_type.cc:28 session.cc:1805 session.cc:1808
msgid "MIDI"
msgstr ""
@@ -399,11 +399,11 @@ msgstr ""
msgid "unknown"
msgstr ""
-#: delivery.cc:114
+#: delivery.cc:118
msgid "main outs"
msgstr ""
-#: delivery.cc:117 send.cc:61
+#: delivery.cc:121 send.cc:62
msgid "listen"
msgstr ""
@@ -473,7 +473,7 @@ msgstr "Сжатие без потерь"
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
-msgstr "Частота сеанса"
+msgstr "Частота сессии"
#: export_format_specification.cc:537
msgid "normalize"
@@ -503,7 +503,7 @@ msgstr "Треугольное"
msgid "Rectangular"
msgstr "Прямоугольное"
-#: export_formats.cc:52 session.cc:5014 session.cc:5030
+#: export_formats.cc:52 session.cc:5028 session.cc:5044
msgid "None"
msgstr "Нет"
@@ -543,15 +543,15 @@ msgstr "Формат сэмплов Vorbis"
msgid "No sample format"
msgstr "Без формата сэмплов"
-#: export_handler.cc:335
+#: export_handler.cc:342
msgid "Editor: cannot open \"%1\" as export file for CD marker file"
msgstr ""
-#: export_handler.cc:417 export_handler.cc:420
+#: export_handler.cc:424 export_handler.cc:427
msgid "an error occured while writing a TOC/CUE file: %1"
msgstr ""
-#: export_handler.cc:642 export_handler.cc:700
+#: export_handler.cc:649 export_handler.cc:707
msgid "Cannot convert %1 to Latin-1 text"
msgstr ""
@@ -776,7 +776,7 @@ msgstr ""
msgid "preset %1 (bank %2)"
msgstr ""
-#: internal_send.cc:278 internal_send.cc:279
+#: internal_send.cc:300 internal_send.cc:301
msgid "%1 - cannot find any track/bus with the ID %2 to connect to"
msgstr ""
@@ -962,7 +962,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
-#: location.cc:842 session.cc:4516 session_state.cc:1031
+#: location.cc:842 session.cc:4530 session_state.cc:1031
msgid "session"
msgstr ""
@@ -1204,31 +1204,35 @@ msgstr ""
msgid "Pannable given XML data for %1 - ignored"
msgstr ""
-#: panner_manager.cc:76
-msgid "looking for panners in %1"
+#: panner_manager.cc:79
+msgid "looking for panners in %1\n"
msgstr ""
-#: panner_manager.cc:100
-msgid "Panner discovered: \"%1\" in %2"
+#: panner_manager.cc:106
+msgid "Panner discovered: \"%1\" in %2\n"
msgstr ""
-#: panner_manager.cc:117
+#: panner_manager.cc:123
msgid "PannerManager: cannot load module \"%1\" (%2)"
msgstr "PannerManager: cannot load module \"%1\" (%2)"
-#: panner_manager.cc:124
+#: panner_manager.cc:130
msgid "PannerManager: module \"%1\" has no descriptor function."
msgstr ""
-#: panner_manager.cc:187
+#: panner_manager.cc:215
msgid "no panner discovered for in/out = %1/%2"
msgstr ""
-#: panner_shell.cc:179
+#: panner_shell.cc:126
+msgid "select panner: %1\n"
+msgstr ""
+
+#: panner_shell.cc:245
msgid "Unknown panner plugin \"%1\" found in pan state - ignored"
msgstr ""
-#: panner_shell.cc:185
+#: panner_shell.cc:251
msgid "panner plugin node has no type information!"
msgstr ""
@@ -1260,37 +1264,37 @@ msgid ""
"for the full version"
msgstr ""
-#: plugin_insert.cc:598
+#: plugin_insert.cc:597
msgid "programming error: "
msgstr "ошибка программы: "
-#: plugin_insert.cc:926
+#: plugin_insert.cc:934
msgid "XML node describing plugin is missing the `type' field"
msgstr ""
-#: plugin_insert.cc:941
+#: plugin_insert.cc:949
msgid "unknown plugin type %1 in plugin insert state"
msgstr ""
-#: plugin_insert.cc:969
+#: plugin_insert.cc:977
msgid "Plugin has no unique ID field"
msgstr ""
-#: plugin_insert.cc:978
+#: plugin_insert.cc:986
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
msgstr ""
-#: plugin_insert.cc:1094
+#: plugin_insert.cc:1102
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
-#: plugin_insert.cc:1101
+#: plugin_insert.cc:1109
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
-#: plugin_insert.cc:1137
+#: plugin_insert.cc:1145
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1338,11 +1342,11 @@ msgstr ""
msgid "insert %1"
msgstr ""
-#: port_insert.cc:198
+#: port_insert.cc:197
msgid "XML node describing port insert is missing the `type' field"
msgstr ""
-#: port_insert.cc:203
+#: port_insert.cc:202
msgid "non-port insert XML used for port plugin insert"
msgstr ""
@@ -1374,11 +1378,11 @@ msgstr ""
msgid "Re-establising port %1 failed"
msgstr ""
-#: processor.cc:207
+#: processor.cc:208
msgid "No %1 property flag in element %2"
msgstr ""
-#: processor.cc:216
+#: processor.cc:217
msgid "No child node with active property"
msgstr ""
@@ -1446,7 +1450,7 @@ msgstr ""
msgid "Import: %1"
msgstr "Импорт: %1"
-#: resampled_source.cc:128
+#: resampled_source.cc:128 srcfilesource.cc:76
msgid "Import: src_new() failed : %1"
msgstr ""
@@ -1454,27 +1458,27 @@ msgstr ""
msgid "return %1"
msgstr ""
-#: route.cc:1075 route.cc:2528
+#: route.cc:1077 route.cc:2518
msgid "unknown Processor type \"%1\"; ignored"
msgstr ""
-#: route.cc:1087
+#: route.cc:1089
msgid "processor could not be created. Ignored."
msgstr ""
-#: route.cc:1962 route.cc:2187
+#: route.cc:1952 route.cc:2177
msgid "Bad node sent to Route::set_state() [%1]"
msgstr ""
-#: route.cc:2022
+#: route.cc:2012
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
-#: route.cc:2096 route.cc:2100 route.cc:2301 route.cc:2305
+#: route.cc:2086 route.cc:2090 route.cc:2291 route.cc:2295
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
-#: route.cc:2311
+#: route.cc:2301
msgid "Converting deprecated order key for %1 using Editor order %2"
msgstr ""
@@ -1490,15 +1494,15 @@ msgstr ""
msgid "error writing tempo-adjusted data to %1"
msgstr ""
-#: send.cc:59
+#: send.cc:60
msgid "aux %1"
msgstr ""
-#: send.cc:63
+#: send.cc:64
msgid "send %1"
msgstr ""
-#: send.cc:65
+#: send.cc:66
msgid "programming error: send created using role %1"
msgstr "programming error: send created using role %1"
@@ -1508,7 +1512,7 @@ msgstr "Соединение со звуковым движком"
#: session.cc:349
msgid "Session loading complete"
-msgstr "Загрузка сеанса завершена"
+msgstr "Загрузка сессии завершена"
#: session.cc:421
msgid "Set up LTC"
@@ -1550,119 +1554,119 @@ msgstr ""
msgid "cannot connect master output %1 to %2"
msgstr ""
-#: session.cc:849
+#: session.cc:859
msgid "monitor"
msgstr ""
-#: session.cc:894
+#: session.cc:904
msgid "cannot connect control input %1 to %2"
msgstr ""
-#: session.cc:914
+#: session.cc:924
msgid "The preferred I/O for the monitor bus (%1) cannot be found"
msgstr ""
-#: session.cc:945
+#: session.cc:955
msgid "cannot connect control output %1 to %2"
msgstr ""
-#: session.cc:1009
+#: session.cc:1023
msgid "cannot create Auditioner: no auditioning of regions possible"
msgstr ""
-#: session.cc:1193
+#: session.cc:1207
msgid "Session: you can't use that location for auto punch (start <= end)"
msgstr ""
-#: session.cc:1233
+#: session.cc:1247
msgid ""
"You cannot use this location for auto-loop because it has zero or negative "
"length"
msgstr ""
-#: session.cc:1547
+#: session.cc:1561
msgid "feedback loop setup between %1 and %2"
msgstr ""
-#: session.cc:1843
+#: session.cc:1857
msgid "Session: could not create new midi track."
msgstr ""
-#: session.cc:1849
+#: session.cc:1863
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
-#: session.cc:2026 session.cc:2029
+#: session.cc:2040 session.cc:2043
msgid "Audio"
msgstr ""
-#: session.cc:2053 session.cc:2061 session.cc:2138 session.cc:2146
+#: session.cc:2067 session.cc:2075 session.cc:2152 session.cc:2160
msgid "cannot configure %1 in/%2 out configuration for new audio track"
msgstr ""
-#: session.cc:2084
+#: session.cc:2098
msgid "Session: could not create new audio track."
msgstr ""
-#: session.cc:2116 session.cc:2119
+#: session.cc:2130 session.cc:2133
msgid "Bus"
msgstr ""
-#: session.cc:2169
+#: session.cc:2183
msgid "Session: could not create new audio route."
msgstr ""
-#: session.cc:2228 session.cc:2238
+#: session.cc:2242 session.cc:2252
msgid "Session: UINT_MAX routes? impossible!"
msgstr ""
-#: session.cc:2260
+#: session.cc:2274
msgid "Session: cannot create track/bus from template description"
msgstr ""
-#: session.cc:2286
+#: session.cc:2300
msgid "Session: could not create new route from template"
msgstr ""
-#: session.cc:2315
+#: session.cc:2329
msgid "Adding new tracks/busses failed"
msgstr "Не удалось добавить новые дорожки/шины"
-#: session.cc:3419
+#: session.cc:3433
msgid "FATAL ERROR! Could not find a suitable version of %1 for a rename"
msgstr ""
-#: session.cc:3539 session.cc:3597
+#: session.cc:3553 session.cc:3611
msgid "There are already %1 recordings for %2, which I consider too many."
msgstr ""
-#: session.cc:3987
+#: session.cc:4001
msgid "send ID %1 appears to be in use already"
msgstr ""
-#: session.cc:3999
+#: session.cc:4013
msgid "aux send ID %1 appears to be in use already"
msgstr ""
-#: session.cc:4011
+#: session.cc:4025
msgid "return ID %1 appears to be in use already"
msgstr ""
-#: session.cc:4023
+#: session.cc:4037
msgid "insert ID %1 appears to be in use already"
msgstr ""
-#: session.cc:4150
+#: session.cc:4164
msgid "Cannot write a range where end <= start (e.g. %1 <= %2)"
msgstr ""
-#: session.cc:4179
+#: session.cc:4193
msgid "too many bounced versions of playlist \"%1\""
msgstr ""
-#: session.cc:4189
+#: session.cc:4203
msgid "cannot create new audio file \"%1\" for %2"
msgstr ""
@@ -1727,7 +1731,7 @@ msgstr ""
msgid "Session: error in no roll for %1"
msgstr ""
-#: session_process.cc:1157
+#: session_process.cc:1159
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -1789,7 +1793,7 @@ msgstr "Session: cannot create session folder \"%1\" (%2)"
#: session_state.cc:514
msgid "Could not open %1 for writing session template"
-msgstr "Не удалось открыть %1 для записи шаблона сеанса"
+msgstr "Не удалось открыть %1 для записи шаблона сессии"
#: session_state.cc:520
msgid "Could not open session template %1 for reading"
@@ -1831,7 +1835,7 @@ msgstr ""
#: session_state.cc:798
msgid "%1: session file \"%2\" doesn't exist!"
-msgstr "%1: файл сеанса «%2» не существует!"
+msgstr "%1: файл сессии «%2» не существует!"
#: session_state.cc:810
msgid "Could not understand session file %1"
@@ -1839,7 +1843,7 @@ msgstr ""
#: session_state.cc:819
msgid "Session file %1 is not a session"
-msgstr "Файл сеанса %1 не является сеансом"
+msgstr "Файл сессии %1 не является сессией"
#: session_state.cc:1125
msgid "programming error: Session: incorrect XML node sent to set_state()"
@@ -2231,7 +2235,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
-#: sndfilesource.cc:396 utils.cc:510 utils.cc:534 utils.cc:548 utils.cc:567
+#: sndfilesource.cc:396 utils.cc:545 utils.cc:569 utils.cc:583 utils.cc:602
msgid "programming error: %1 %2"
msgstr "programming error: %1 %2"
@@ -2274,18 +2278,22 @@ msgid ""
"start time."
msgstr ""
-#: speakers.cc:239
+#: speakers.cc:280
msgid "Speaker information is missing azimuth - speaker ignored"
msgstr ""
-#: speakers.cc:245
+#: speakers.cc:286
msgid "Speaker information is missing elevation - speaker ignored"
msgstr ""
-#: speakers.cc:251
+#: speakers.cc:292
msgid "Speaker information is missing distance - speaker ignored"
msgstr ""
+#: srcfilesource.cc:135
+msgid "SrcFileSource: %1"
+msgstr ""
+
#: tape_file_matcher.cc:46
msgid "Cannot compile tape track regexp for use (%1)"
msgstr ""
@@ -2433,54 +2441,54 @@ msgstr ""
msgid "Node for Port has no \"name\" property"
msgstr "Node for Port has no \"name\" property"
-#: utils.cc:358 utils.cc:382
+#: utils.cc:393 utils.cc:417
msgid "Splice"
msgstr ""
-#: utils.cc:360 utils.cc:375
+#: utils.cc:395 utils.cc:410
msgid "Slide"
msgstr ""
-#: utils.cc:362 utils.cc:378
+#: utils.cc:397 utils.cc:413
msgid "Lock"
msgstr ""
-#: utils.cc:365
+#: utils.cc:400
msgid "programming error: unknown edit mode string \"%1\""
msgstr "programming error: unknown edit mode string \"%1\""
-#: utils.cc:389 utils.cc:421
+#: utils.cc:424 utils.cc:456
msgid "MIDI Timecode"
msgstr ""
-#: utils.cc:389 utils.cc:419
+#: utils.cc:424 utils.cc:454
msgid "MTC"
msgstr "MTC"
-#: utils.cc:393 utils.cc:428
+#: utils.cc:428 utils.cc:463
msgid "MIDI Clock"
msgstr ""
-#: utils.cc:397 utils.cc:415 utils.cc:435
+#: utils.cc:432 utils.cc:450 utils.cc:470
msgid "JACK"
msgstr "JACK"
-#: utils.cc:401
+#: utils.cc:436
msgid "programming error: unknown sync source string \"%1\""
msgstr "programming error: unknown sync source string \"%1\""
-#: utils.cc:426
+#: utils.cc:461
msgid "M-Clock"
msgstr ""
-#: utils.cc:432
+#: utils.cc:467
msgid "LTC"
msgstr "LTC"
-#: utils.cc:602
+#: utils.cc:637
msgid "programming error: unknown native header format: %1"
msgstr "programming error: unknown native header format: %1"
-#: utils.cc:617
+#: utils.cc:652
msgid "cannot open directory %1 (%2)"
msgstr "cannot open directory %1 (%2)"
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 66a8ea706d..ddef560e9b 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2502,7 +2502,7 @@ Route::set_processor_state (const XMLNode& node)
if (prop->value() == "intsend") {
- processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Aux));
+ processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Aux, true));
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
@@ -2518,7 +2518,7 @@ Route::set_processor_state (const XMLNode& node)
} else if (prop->value() == "send") {
- processor.reset (new Send (_session, _pannable, _mute_master));
+ processor.reset (new Send (_session, _pannable, _mute_master, Delivery::Send, true));
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 1664f42b35..71cab46879 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -44,9 +44,9 @@ using namespace PBD;
using namespace std;
string
-Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot)
+Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot, bool ignore_bitslot)
{
- if (r == Role (0)) {
+ if (ignore_bitslot) {
/* this happens during initial construction of sends from XML,
before they get ::set_state() called. lets not worry about
it.
@@ -70,8 +70,8 @@ Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot)
}
-Send::Send (Session& s, boost::shared_ptr<Pannable> p, boost::shared_ptr<MuteMaster> mm, Role r)
- : Delivery (s, p, mm, name_and_id_new_send (s, r, _bitslot), r)
+Send::Send (Session& s, boost::shared_ptr<Pannable> p, boost::shared_ptr<MuteMaster> mm, Role r, bool ignore_bitslot)
+ : Delivery (s, p, mm, name_and_id_new_send (s, r, _bitslot, ignore_bitslot), r)
, _metering (false)
{
if (_role == Listen) {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index d93d689459..be2d4c5441 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -526,13 +526,16 @@ Session::destroy ()
}
routes.flush ();
- DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
- for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
- DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
- i->second->drop_references ();
- }
+ {
+ DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
+ Glib::Threads::Mutex::Lock lm (source_lock);
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
+ DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
+ i->second->drop_references ();
+ }
- sources.clear ();
+ sources.clear ();
+ }
DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index d915bba845..dfaa51481d 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -67,6 +67,15 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
}
/* file is not opened until write */
+
+ if (flags & Writable) {
+ return;
+ }
+
+ if (open(_path)) {
+ throw failed_constructor ();
+ }
+ _open = true;
}
/** Constructor used for existing internal-to-session files. */
@@ -468,6 +477,12 @@ SMFSource::safe_midi_file_extension (const string& file)
return true;
}
+static bool compare_eventlist (
+ const std::pair< Evoral::Event<double>*, gint >& a,
+ const std::pair< Evoral::Event<double>*, gint >& b) {
+ return ( a.first->time() < b.first->time() );
+}
+
void
SMFSource::load_model (bool lock, bool force_reload)
{
@@ -506,60 +521,74 @@ SMFSource::load_model (bool lock, bool force_reload)
uint8_t* buf = NULL;
int ret;
gint event_id;
- bool have_event_id = false;
+ bool have_event_id;
- while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
+ // TODO simplify event allocation
+ std::list< std::pair< Evoral::Event<double>*, gint > > eventlist;
- time += delta_t;
+ for (unsigned i = 1; i <= num_tracks(); ++i) {
+ if (seek_to_track(i)) continue;
- if (ret == 0) {
-
- /* meta-event : did we get an event ID ?
- */
-
- if (event_id >= 0) {
- have_event_id = true;
- }
+ time = 0;
+ have_event_id = false;
- continue;
- }
+ while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
- if (ret > 0) {
+ time += delta_t;
- /* not a meta-event */
+ if (ret == 0) {
+ /* meta-event : did we get an event ID ? */
+ if (event_id >= 0) {
+ have_event_id = true;
+ }
+ continue;
+ }
- ev.set (buf, size, time / (double)ppqn());
- ev.set_event_type(EventTypeMap::instance().midi_event_type(buf[0]));
+ if (ret > 0) {
+ /* not a meta-event */
- if (!have_event_id) {
- event_id = Evoral::next_event_id();
- }
+ if (!have_event_id) {
+ event_id = Evoral::next_event_id();
+ }
+ uint32_t event_type = EventTypeMap::instance().midi_event_type(buf[0]);
+ double event_time = time / (double) ppqn();
#ifndef NDEBUG
- std::string ss;
+ std::string ss;
- for (uint32_t xx = 0; xx < size; ++xx) {
- char b[8];
- snprintf (b, sizeof (b), "0x%x ", buf[xx]);
- ss += b;
- }
+ for (uint32_t xx = 0; xx < size; ++xx) {
+ char b[8];
+ snprintf (b, sizeof (b), "0x%x ", buf[xx]);
+ ss += b;
+ }
- DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
- delta_t, time, size, ss , ev.event_type(), name()));
+ DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
+ delta_t, time, size, ss , event_type, name()));
#endif
- _model->append (ev, event_id);
+ eventlist.push_back(make_pair (
+ new Evoral::Event<double> (
+ event_type, event_time,
+ size, buf, true)
+ , event_id));
+
+ // Set size to max capacity to minimize allocs in read_event
+ scratch_size = std::max(size, scratch_size);
+ size = scratch_size;
- // Set size to max capacity to minimize allocs in read_event
- scratch_size = std::max(size, scratch_size);
- size = scratch_size;
+ _length_beats = max(_length_beats, event_time);
+ }
- _length_beats = max(_length_beats, ev.time());
+ /* event ID's must immediately precede the event they are for */
+ have_event_id = false;
}
+ }
- /* event ID's must immediately precede the event they are for
- */
+ eventlist.sort(compare_eventlist);
- have_event_id = false;
+ std::list< std::pair< Evoral::Event<double>*, gint > >::iterator it;
+ for (it=eventlist.begin(); it!=eventlist.end(); ++it) {
+ _model->append (*it->first, it->second);
+ delete it->first;
}
_model->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 5e1a7d40d9..0729f21592 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -272,18 +272,17 @@ SourceFactory::createExternal (DataType type, Session& s, const string& path,
} else if (type == DataType::MIDI) {
- SMFSource* src = new SMFSource (s, path, SMFSource::Flag(0));
+ boost::shared_ptr<SMFSource> src (new SMFSource (s, path, SMFSource::Flag(0)));
src->load_model (true, true);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// boost_debug_shared_ptr_mark_interesting (src, "Source");
#endif
- boost::shared_ptr<Source> ret (src);
if (announce) {
- SourceCreated (ret);
+ SourceCreated (src);
}
- return ret;
+ return src;
}