diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2014-01-23 13:41:20 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2014-01-23 13:41:20 -0500 |
commit | 7000afdc66c9e0ae8dcf9ec080517dabba1e7f34 (patch) | |
tree | 19574ed8a1fbafa6bed222d8cf817ee1c8098314 /libs/ardour | |
parent | 065e1e63342633f72725a5309926f71c87804293 (diff) | |
parent | 40d8c5ae01f25e02457c554170a53d537246a7d4 (diff) |
fix merge conflict with master
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/audio_diskstream.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/auditioner.h | 61 | ||||
-rw-r--r-- | libs/ardour/ardour/internal_send.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_diskstream.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/send.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 3 | ||||
-rw-r--r-- | libs/ardour/audio_track.cc | 8 | ||||
-rw-r--r-- | libs/ardour/auditioner.cc | 360 | ||||
-rw-r--r-- | libs/ardour/internal_send.cc | 4 | ||||
-rw-r--r-- | libs/ardour/lv2_plugin.cc | 1 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 8 | ||||
-rw-r--r-- | libs/ardour/po/ru.po | 228 | ||||
-rw-r--r-- | libs/ardour/route.cc | 4 | ||||
-rw-r--r-- | libs/ardour/send.cc | 8 | ||||
-rw-r--r-- | libs/ardour/session.cc | 15 | ||||
-rw-r--r-- | libs/ardour/smf_source.cc | 101 | ||||
-rw-r--r-- | libs/ardour/source_factory.cc | 7 |
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; } |