summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/automation_streamview.cc3
-rw-r--r--gtk2_ardour/midi_region_view.cc3
-rw-r--r--gtk2_ardour/midi_streamview.cc6
-rw-r--r--libs/ardour/ardour/audiofilesource.h2
-rw-r--r--libs/ardour/ardour/audiosource.h2
-rw-r--r--libs/ardour/ardour/midi_model.h13
-rw-r--r--libs/ardour/ardour/midi_playlist_source.h16
-rw-r--r--libs/ardour/ardour/midi_source.h56
-rw-r--r--libs/ardour/ardour/midi_state_tracker.h4
-rw-r--r--libs/ardour/ardour/smf_source.h29
-rw-r--r--libs/ardour/ardour/source.h6
-rw-r--r--libs/ardour/audio_diskstream.cc9
-rw-r--r--libs/ardour/audiofilesource.cc4
-rw-r--r--libs/ardour/audiosource.cc2
-rw-r--r--libs/ardour/import.cc11
-rw-r--r--libs/ardour/midi_diskstream.cc10
-rw-r--r--libs/ardour/midi_model.cc54
-rw-r--r--libs/ardour/midi_playlist_source.cc20
-rw-r--r--libs/ardour/midi_region.cc15
-rw-r--r--libs/ardour/midi_source.cc61
-rw-r--r--libs/ardour/midi_state_tracker.cc4
-rw-r--r--libs/ardour/midi_stretch.cc4
-rw-r--r--libs/ardour/smf_source.cc62
-rw-r--r--libs/ardour/source_factory.cc6
24 files changed, 228 insertions, 174 deletions
diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc
index 89ae7fa079..e504d13931 100644
--- a/gtk2_ardour/automation_streamview.cc
+++ b/gtk2_ardour/automation_streamview.cc
@@ -76,7 +76,8 @@ AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region
if (wait_for_data) {
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
if (mr) {
- mr->midi_source()->load_model();
+ Source::Lock lock(mr->midi_source()->mutex());
+ mr->midi_source()->load_model(lock);
}
}
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 0b14ca6a7a..e072d7c7ce 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -270,7 +270,8 @@ MidiRegionView::init (bool wfd)
gui_context());
if (wfd) {
- midi_region()->midi_source(0)->load_model();
+ Glib::Threads::Mutex::Lock lm(midi_region()->midi_source(0)->mutex());
+ midi_region()->midi_source(0)->load_model(lm);
}
_model = midi_region()->midi_source(0)->model();
diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc
index d124426cc9..8a5fd53150 100644
--- a/gtk2_ardour/midi_streamview.cc
+++ b/gtk2_ardour/midi_streamview.cc
@@ -193,7 +193,8 @@ MidiStreamView::display_region(MidiRegionView* region_view, bool load_model)
}
if (load_model) {
- source->load_model();
+ Glib::Threads::Mutex::Lock lm(source->mutex());
+ source->load_model(lm);
}
if (!source->model()) {
@@ -225,7 +226,8 @@ MidiStreamView::update_contents_metrics(boost::shared_ptr<Region> r)
{
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(r);
if (mr) {
- mr->midi_source(0)->load_model();
+ Glib::Threads::Mutex::Lock lm(mr->midi_source(0)->mutex());
+ mr->midi_source(0)->load_model(lm);
_range_dirty = update_data_note_range(
mr->model()->lowest_note(),
mr->model()->highest_note());
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index 4831eb2081..9e63f4c81d 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -64,7 +64,7 @@ public:
virtual int update_header (framepos_t when, struct tm&, time_t) = 0;
virtual int flush_header () = 0;
- void mark_streaming_write_completed ();
+ void mark_streaming_write_completed (const Lock& lock);
int setup_peakfile ();
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 7d1878f286..622bc6052a 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -60,7 +60,7 @@ class LIBARDOUR_API AudioSource : virtual public Source,
virtual float sample_rate () const = 0;
- virtual void mark_streaming_write_completed ();
+ virtual void mark_streaming_write_completed (const Lock& lock);
virtual bool can_truncate_peaks() const { return true; }
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
index 4d12839625..1988c1a2d1 100644
--- a/libs/ardour/ardour/midi_model.h
+++ b/libs/ardour/ardour/midi_model.h
@@ -238,10 +238,15 @@ public:
void apply_command (Session& session, Command* cmd);
void apply_command_as_subcommand (Session& session, Command* cmd);
- bool sync_to_source ();
- bool write_to(boost::shared_ptr<MidiSource> source);
- bool write_section_to (boost::shared_ptr<MidiSource> source, Evoral::MusicalTime begin = Evoral::MinMusicalTime,
- Evoral::MusicalTime end = Evoral::MaxMusicalTime);
+ bool sync_to_source (const Glib::Threads::Mutex::Lock& source_lock);
+
+ bool write_to(boost::shared_ptr<MidiSource> source,
+ const Glib::Threads::Mutex::Lock& source_lock);
+
+ bool write_section_to(boost::shared_ptr<MidiSource> source,
+ const Glib::Threads::Mutex::Lock& source_lock,
+ Evoral::MusicalTime begin = Evoral::MinMusicalTime,
+ Evoral::MusicalTime end = Evoral::MaxMusicalTime);
// MidiModel doesn't use the normal AutomationList serialisation code
// since controller data is stored in the .mid
diff --git a/libs/ardour/ardour/midi_playlist_source.h b/libs/ardour/ardour/midi_playlist_source.h
index 7a61f5aa02..f064553342 100644
--- a/libs/ardour/ardour/midi_playlist_source.h
+++ b/libs/ardour/ardour/midi_playlist_source.h
@@ -45,10 +45,10 @@ public:
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
- void append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& ev);
- void append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev, framepos_t source_start);
- void load_model(bool lock=true, bool force_reload=false);
- void destroy_model();
+ void append_event_beats(const Glib::Threads::Mutex::Lock& lock, const Evoral::Event<Evoral::MusicalTime>& ev);
+ void append_event_frames(const Glib::Threads::Mutex::Lock& lock, const Evoral::Event<framepos_t>& ev, framepos_t source_start);
+ void load_model(const Glib::Threads::Mutex::Lock& lock, bool force_reload=false);
+ void destroy_model(const Glib::Threads::Mutex::Lock& lock);
protected:
friend class SourceFactory;
@@ -58,15 +58,17 @@ protected:
MidiPlaylistSource (Session&, const XMLNode&);
- void flush_midi();
+ void flush_midi(const Lock& lock);
- framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
+ framecnt_t read_unlocked (const Lock& lock,
+ Evoral::EventSink<framepos_t>& dst,
framepos_t position,
framepos_t start,
framecnt_t cnt,
MidiStateTracker* tracker) const;
- framecnt_t write_unlocked (MidiRingBuffer<framepos_t>& dst,
+ framecnt_t write_unlocked (const Lock& lock,
+ MidiRingBuffer<framepos_t>& dst,
framepos_t position,
framecnt_t cnt);
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
index 2ce92ba3cf..2b78230a00 100644
--- a/libs/ardour/ardour/midi_source.h
+++ b/libs/ardour/ardour/midi_source.h
@@ -57,7 +57,8 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
* \param end time of latest event that can be written.
* \return zero on success, non-zero if the write failed for any reason.
*/
- int write_to (boost::shared_ptr<MidiSource> newsrc,
+ int write_to (const Lock& lock,
+ boost::shared_ptr<MidiSource> newsrc,
Evoral::MusicalTime begin = Evoral::MinMusicalTime,
Evoral::MusicalTime end = Evoral::MaxMusicalTime);
@@ -70,7 +71,8 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
* \param tracker an optional pointer to MidiStateTracker object, for note on/off tracking.
* \param filtered Parameters whose MIDI messages will not be returned.
*/
- virtual framecnt_t midi_read (Evoral::EventSink<framepos_t>& dst,
+ virtual framecnt_t midi_read (const Lock& lock,
+ Evoral::EventSink<framepos_t>& dst,
framepos_t source_start,
framepos_t start,
framecnt_t cnt,
@@ -82,22 +84,33 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
* @param source_start This source's start position in session frames.
* @param cnt The length of time to write.
*/
- virtual framecnt_t midi_write (MidiRingBuffer<framepos_t>& src,
+ virtual framecnt_t midi_write (const Lock& lock,
+ MidiRingBuffer<framepos_t>& src,
framepos_t source_start,
framecnt_t cnt);
- virtual void append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& ev) = 0;
+ /** Append a single event with a timestamp in beats.
+ *
+ * Caller must ensure that the event is later than the last written event.
+ */
+ virtual void append_event_beats(const Lock& lock,
+ const Evoral::Event<Evoral::MusicalTime>& ev) = 0;
- virtual void append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev,
- framepos_t source_start) = 0;
+ /** Append a single event with a timestamp in frames.
+ *
+ * Caller must ensure that the event is later than the last written event.
+ */
+ virtual void append_event_frames(const Lock& lock,
+ const Evoral::Event<framepos_t>& ev,
+ framepos_t source_start) = 0;
virtual bool empty () const;
virtual framecnt_t length (framepos_t pos) const;
virtual void update_length (framecnt_t);
- virtual void mark_streaming_midi_write_started (NoteMode mode);
- virtual void mark_streaming_write_started ();
- virtual void mark_streaming_write_completed ();
+ virtual void mark_streaming_midi_write_started (const Lock& lock, NoteMode mode);
+ virtual void mark_streaming_write_started (const Lock& lock);
+ virtual void mark_streaming_write_completed (const Lock& lock);
/** Mark write starting with the given time parameters.
*
@@ -119,6 +132,7 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
* etc.
*/
virtual void mark_midi_streaming_write_completed (
+ const Lock& lock,
Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption stuck_option,
Evoral::MusicalTime when = Evoral::MusicalTime());
@@ -137,19 +151,17 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
void set_length_beats(TimeType l) { _length_beats = l; }
TimeType length_beats() const { return _length_beats; }
- virtual void load_model(bool lock=true, bool force_reload=false) = 0;
- virtual void destroy_model() = 0;
+ virtual void load_model(const Glib::Threads::Mutex::Lock& lock, bool force_reload=false) = 0;
+ virtual void destroy_model(const Glib::Threads::Mutex::Lock& lock) = 0;
- /** This must be called with the source lock held whenever the
- * source/model contents have been changed (reset iterators/cache/etc).
- */
- void invalidate();
+ /** Reset cached information (like iterators) when things have changed. */
+ void invalidate(const Glib::Threads::Mutex::Lock& lock);
- void set_note_mode(NoteMode mode);
+ void set_note_mode(const Glib::Threads::Mutex::Lock& lock, NoteMode mode);
boost::shared_ptr<MidiModel> model() { return _model; }
- void set_model (boost::shared_ptr<MidiModel>);
- void drop_model();
+ void set_model(const Glib::Threads::Mutex::Lock& lock, boost::shared_ptr<MidiModel>);
+ void drop_model(const Glib::Threads::Mutex::Lock& lock);
Evoral::ControlList::InterpolationStyle interpolation_of (Evoral::Parameter) const;
void set_interpolation_of (Evoral::Parameter, Evoral::ControlList::InterpolationStyle);
@@ -169,9 +181,10 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
PBD::Signal2<void, Evoral::Parameter, AutoState> AutomationStateChanged;
protected:
- virtual void flush_midi() = 0;
+ virtual void flush_midi(const Lock& lock) = 0;
- virtual framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
+ virtual framecnt_t read_unlocked (const Lock& lock,
+ Evoral::EventSink<framepos_t>& dst,
framepos_t position,
framepos_t start,
framecnt_t cnt,
@@ -182,7 +195,8 @@ class LIBARDOUR_API MidiSource : virtual public Source, public boost::enable_sha
* @param position This source's start position in session frames.
* @param cnt The duration of this block to write for.
*/
- virtual framecnt_t write_unlocked (MidiRingBuffer<framepos_t>& source,
+ virtual framecnt_t write_unlocked (const Lock& lock,
+ MidiRingBuffer<framepos_t>& source,
framepos_t position,
framecnt_t cnt) = 0;
diff --git a/libs/ardour/ardour/midi_state_tracker.h b/libs/ardour/ardour/midi_state_tracker.h
index d8a31c10aa..98611bc722 100644
--- a/libs/ardour/ardour/midi_state_tracker.h
+++ b/libs/ardour/ardour/midi_state_tracker.h
@@ -20,6 +20,8 @@
#ifndef __ardour_midi_state_tracker_h__
#define __ardour_midi_state_tracker_h__
+#include <glibmm/threads.h>
+
#include "ardour/midi_buffer.h"
namespace Evoral {
@@ -44,7 +46,7 @@ public:
void remove (uint8_t note, uint8_t chn);
void resolve_notes (MidiBuffer& buffer, framepos_t time);
void resolve_notes (Evoral::EventSink<framepos_t>& buffer, framepos_t time);
- void resolve_notes (MidiSource& src, Evoral::MusicalTime time);
+ void resolve_notes (MidiSource& src, const Glib::Threads::Mutex::Lock& lock, Evoral::MusicalTime time);
void dump (std::ostream&);
void reset ();
bool empty() const { return _on == 0; }
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
index 56b70b15bd..d93fdb8506 100644
--- a/libs/ardour/ardour/smf_source.h
+++ b/libs/ardour/ardour/smf_source.h
@@ -47,26 +47,24 @@ public:
virtual ~SMFSource ();
- bool safe_file_extension (const std::string& path) const {
+ bool safe_file_extension (const std::string& path) const {
return safe_midi_file_extension(path);
}
- void append_event_unlocked_beats (const Evoral::Event<Evoral::MusicalTime>& ev);
- void append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t source_start);
+ void append_event_beats (const Lock& lock, const Evoral::Event<Evoral::MusicalTime>& ev);
+ void append_event_frames (const Lock& lock, const Evoral::Event<framepos_t>& ev, framepos_t source_start);
- void mark_streaming_midi_write_started (NoteMode mode);
- void mark_streaming_write_completed ();
- void mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption,
+ void mark_streaming_midi_write_started (const Lock& lock, NoteMode mode);
+ void mark_streaming_write_completed (const Lock& lock);
+ void mark_midi_streaming_write_completed (const Lock& lock,
+ Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption,
Evoral::MusicalTime when = Evoral::MusicalTime());
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
- void load_model (bool lock=true, bool force_reload=false);
- void destroy_model ();
-
- void flush_midi ();
- void ensure_disk_file ();
+ void load_model (const Glib::Threads::Mutex::Lock& lock, bool force_reload=false);
+ void destroy_model (const Glib::Threads::Mutex::Lock& lock);
static bool safe_midi_file_extension (const std::string& path);
static bool valid_midi_file (const std::string& path);
@@ -75,6 +73,7 @@ public:
protected:
void set_path (const std::string& newpath);
+ void flush_midi (const Lock& lock);
private:
bool _open;
@@ -87,13 +86,17 @@ public:
int open_for_write ();
- framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
+ void ensure_disk_file (const Lock& lock);
+
+ framecnt_t read_unlocked (const Lock& lock,
+ Evoral::EventSink<framepos_t>& dst,
framepos_t position,
framepos_t start,
framecnt_t cnt,
MidiStateTracker* tracker) const;
- framecnt_t write_unlocked (MidiRingBuffer<framepos_t>& src,
+ framecnt_t write_unlocked (const Lock& lock,
+ MidiRingBuffer<framepos_t>& src,
framepos_t position,
framecnt_t cnt);
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index e009e0ef51..18de40771c 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -51,6 +51,8 @@ class LIBARDOUR_API Source : public SessionObject
Empty = 0x100, /* used for MIDI only */
};
+ typedef Glib::Threads::Mutex::Lock Lock;
+
Source (Session&, DataType type, const std::string& name, Flag flags=Flag(0));
Source (Session&, const XMLNode&);
@@ -69,8 +71,8 @@ class LIBARDOUR_API Source : public SessionObject
void mark_for_remove();
- virtual void mark_streaming_write_started () {}
- virtual void mark_streaming_write_completed () = 0;
+ virtual void mark_streaming_write_started (const Lock& lock) {}
+ virtual void mark_streaming_write_completed (const Lock& lock) = 0;
virtual void session_saved() {}
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 4c3f7e6437..eb85538811 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1771,13 +1771,15 @@ AudioDiskstream::prep_record_enable ()
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
(*chan)->source.request_input_monitoring (!(_session.config.get_auto_input() && rolling));
capturing_sources.push_back ((*chan)->write_source);
- (*chan)->write_source->mark_streaming_write_started ();
+ (*chan)->write_source->mark_streaming_write_started (
+ Source::Lock((*chan)->write_source->mutex()));
}
} else {
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
capturing_sources.push_back ((*chan)->write_source);
- (*chan)->write_source->mark_streaming_write_started ();
+ (*chan)->write_source->mark_streaming_write_started (
+ Source::Lock((*chan)->write_source->mutex()));
}
}
@@ -1963,7 +1965,8 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
if ((*chan)->write_source) {
if (mark_write_complete) {
- (*chan)->write_source->mark_streaming_write_completed ();
+ (*chan)->write_source->mark_streaming_write_completed (
+ Source::Lock((*chan)->write_source->mutex()));
(*chan)->write_source->done_with_peakfile_writes ();
}
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 40c3d2f012..6d9414a5cb 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -302,13 +302,13 @@ AudioFileSource::set_state (const XMLNode& node, int version)
}
void
-AudioFileSource::mark_streaming_write_completed ()
+AudioFileSource::mark_streaming_write_completed (const Lock& lock)
{
if (!writable()) {
return;
}
- AudioSource::mark_streaming_write_completed ();
+ AudioSource::mark_streaming_write_completed (lock);
}
int
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index b0b229a57a..93a0ca4fee 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -923,7 +923,7 @@ AudioSource::available_peaks (double zoom_factor) const
}
void
-AudioSource::mark_streaming_write_completed ()
+AudioSource::mark_streaming_write_completed (const Lock& lock)
{
Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 38a3da2fdc..2b3f105879 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -354,7 +354,9 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
- smfs->drop_model ();
+ Glib::Threads::Mutex::Lock source_lock(smfs->mutex());
+
+ smfs->drop_model (source_lock);
source->seek_to_track (i);
uint64_t t = 0;
@@ -384,11 +386,12 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
}
if (first) {
- smfs->mark_streaming_write_started ();
+ smfs->mark_streaming_write_started (source_lock);
first = false;
}
- smfs->append_event_unlocked_beats(
+ smfs->append_event_beats(
+ source_lock,
Evoral::Event<Evoral::MusicalTime>(
0,
Evoral::MusicalTime::ticks_at_rate(t, source->ppqn()),
@@ -408,7 +411,7 @@ write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
const Evoral::MusicalTime length_beats = Evoral::MusicalTime::ticks_at_rate(t, source->ppqn());
BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
smfs->update_length(pos + converter.to(length_beats.round_up_to_beat()));
- smfs->mark_streaming_write_completed ();
+ smfs->mark_streaming_write_completed (source_lock);
if (status.cancel) {
break;
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 27ec409b15..e2fd6d1681 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -851,7 +851,8 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
}
if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
- if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
+ Source::Lock lm(_write_source->mutex());
+ if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
return -1;
}
@@ -919,6 +920,8 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
/* phew, we have data */
+ Source::Lock source_lock(_write_source->mutex());
+
/* figure out the name for this take */
srcs.push_back (_write_source);
@@ -936,7 +939,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
where all the data is already on disk.
*/
- _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
+ _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
/* we will want to be able to keep (over)writing the source
but we don't want it to be removable. this also differs
@@ -1280,7 +1283,8 @@ MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
}
if (_write_source && mark_write_complete) {
- _write_source->mark_streaming_write_completed ();
+ Source::Lock lm(_write_source->mutex());
+ _write_source->mark_streaming_write_completed (lm);
}
use_new_write_source (0);
}
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index 6c2132562a..f64a5f6d0c 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -1426,25 +1426,23 @@ MidiModel::PatchChangeDiffCommand::get_state ()
* `Discrete' mode).
*/
bool
-MidiModel::write_to (boost::shared_ptr<MidiSource> source)
+MidiModel::write_to (boost::shared_ptr<MidiSource> source,
+ const Glib::Threads::Mutex::Lock& source_lock)
{
ReadLock lock(read_lock());
const bool old_percussive = percussive();
set_percussive(false);
- boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
- assert (ms);
-
- source->drop_model();
- source->mark_streaming_midi_write_started (note_mode());
+ source->drop_model(source_lock);
+ source->mark_streaming_midi_write_started (source_lock, note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(TimeType(), true); i != end(); ++i) {
- source->append_event_unlocked_beats(*i);
+ source->append_event_beats(source_lock, *i);
}
set_percussive(old_percussive);
- source->mark_streaming_write_completed();
+ source->mark_streaming_write_completed(source_lock);
set_edited(false);
@@ -1457,7 +1455,7 @@ MidiModel::write_to (boost::shared_ptr<MidiSource> source)
of the model.
*/
bool
-MidiModel::sync_to_source ()
+MidiModel::sync_to_source (const Glib::Threads::Mutex::Lock& source_lock)
{
ReadLock lock(read_lock());
@@ -1465,16 +1463,19 @@ MidiModel::sync_to_source ()
set_percussive(false);
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
- assert (ms);
+ if (!ms) {
+ error << "MIDI model has no source to sync to" << endmsg;
+ return false;
+ }
- ms->mark_streaming_midi_write_started (note_mode());
+ ms->mark_streaming_midi_write_started (source_lock, note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(TimeType(), true); i != end(); ++i) {
- ms->append_event_unlocked_beats(*i);
+ ms->append_event_beats(source_lock, *i);
}
set_percussive (old_percussive);
- ms->mark_streaming_write_completed ();
+ ms->mark_streaming_write_completed (source_lock);
set_edited (false);
@@ -1489,7 +1490,10 @@ MidiModel::sync_to_source ()
* destroying the original note durations.
*/
bool
-MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::MusicalTime begin_time, Evoral::MusicalTime end_time)
+MidiModel::write_section_to (boost::shared_ptr<MidiSource> source,
+ const Glib::Threads::Mutex::Lock& source_lock,
+ Evoral::MusicalTime begin_time,
+ Evoral::MusicalTime end_time)
{
ReadLock lock(read_lock());
MidiStateTracker mst;
@@ -1497,11 +1501,8 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::Music
const bool old_percussive = percussive();
set_percussive(false);
- boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
- assert (ms);
-
- source->drop_model();
- source->mark_streaming_midi_write_started (note_mode());
+ source->drop_model(source_lock);
+ source->mark_streaming_midi_write_started (source_lock, note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(TimeType(), true); i != end(); ++i) {
const Evoral::Event<Evoral::MusicalTime>& ev (*i);
@@ -1526,22 +1527,22 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::Music
continue;
}
- source->append_event_unlocked_beats (*i);
+ source->append_event_beats (source_lock, *i);
mst.remove (mev->note(), mev->channel());
} else if (mev->is_note_on()) {
mst.add (mev->note(), mev->channel());
- source->append_event_unlocked_beats(*i);
+ source->append_event_beats(source_lock, *i);
} else {
- source->append_event_unlocked_beats(*i);
+ source->append_event_beats(source_lock, *i);
}
}
}
- mst.resolve_notes (*source, end_time);
+ mst.resolve_notes (*source, source_lock, end_time);
set_percussive(old_percussive);
- source->mark_streaming_write_completed();
+ source->mark_streaming_write_completed(source_lock);
set_edited(false);
@@ -1630,7 +1631,7 @@ MidiModel::edit_lock()
assert (ms);
Glib::Threads::Mutex::Lock* source_lock = new Glib::Threads::Mutex::Lock (ms->mutex());
- ms->invalidate(); // Release cached iterator's read lock on model
+ ms->invalidate(*source_lock); // Release cached iterator's read lock on model
return WriteLock(new WriteLockImpl(source_lock, _lock, _control_lock));
}
@@ -1855,7 +1856,8 @@ MidiModel::set_midi_source (boost::shared_ptr<MidiSource> s)
boost::shared_ptr<MidiSource> old = _midi_source.lock ();
if (old) {
- old->invalidate ();
+ Source::Lock lm(old->mutex());
+ old->invalidate (lm);
}
_midi_source_connections.drop_connections ();
diff --git a/libs/ardour/midi_playlist_source.cc b/libs/ardour/midi_playlist_source.cc
index cd5362c3da..587bc7b12f 100644
--- a/libs/ardour/midi_playlist_source.cc
+++ b/libs/ardour/midi_playlist_source.cc
@@ -122,7 +122,8 @@ MidiPlaylistSource::length (framepos_t) const
}
framecnt_t
-MidiPlaylistSource::read_unlocked (Evoral::EventSink<framepos_t>& dst,
+MidiPlaylistSource::read_unlocked (const Lock& lock,
+ Evoral::EventSink<framepos_t>& dst,
framepos_t /*position*/,
framepos_t start, framecnt_t cnt,
MidiStateTracker*) const
@@ -137,7 +138,8 @@ MidiPlaylistSource::read_unlocked (Evoral::EventSink<framepos_t>& dst,
}
framecnt_t
-MidiPlaylistSource::write_unlocked (MidiRingBuffer<framepos_t>&,
+MidiPlaylistSource::write_unlocked (const Lock&,
+ MidiRingBuffer<framepos_t>&,
framepos_t,
framecnt_t)
{
@@ -147,33 +149,33 @@ MidiPlaylistSource::write_unlocked (MidiRingBuffer<framepos_t>&,
}
void
-MidiPlaylistSource::append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& /*ev*/)
+MidiPlaylistSource::append_event_beats(const Glib::Threads::Mutex::Lock& /*lock*/, const Evoral::Event<Evoral::MusicalTime>& /*ev*/)
{
- fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_beats() called - should be impossible") << endmsg;
+ fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_beats() called - should be impossible") << endmsg;
abort(); /*NOTREACHED*/
}
void
-MidiPlaylistSource::append_event_unlocked_frames(const Evoral::Event<framepos_t>& /* ev */, framepos_t /*source_start*/)
+MidiPlaylistSource::append_event_frames(const Glib::Threads::Mutex::Lock& /*lock*/, const Evoral::Event<framepos_t>& /* ev */, framepos_t /*source_start*/)
{
- fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_frames() called - should be impossible") << endmsg;
+ fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_frames() called - should be impossible") << endmsg;
abort(); /*NOTREACHED*/
}
void
-MidiPlaylistSource::load_model (bool, bool)
+MidiPlaylistSource::load_model (const Glib::Threads::Mutex::Lock&, bool)
{
/* nothing to do */
}
void
-MidiPlaylistSource::destroy_model ()
+MidiPlaylistSource::destroy_model (const Glib::Threads::Mutex::Lock&)
{
/* nothing to do */
}
void
-MidiPlaylistSource::flush_midi ()
+MidiPlaylistSource::flush_midi (const Lock& lock)
{
}
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index f6631b9de5..f79e5ef203 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -150,8 +150,11 @@ MidiRegion::clone (boost::shared_ptr<MidiSource> newsrc) const
Evoral::MusicalTime const bbegin = bfc.from (_start);
Evoral::MusicalTime const bend = bfc.from (_start + _length);
- if (midi_source(0)->write_to (newsrc, bbegin, bend)) {
- return boost::shared_ptr<MidiRegion> ();
+ {
+ Source::Lock lm(newsrc->mutex());
+ if (midi_source(0)->write_to (lm, newsrc, bbegin, bend)) {
+ return boost::shared_ptr<MidiRegion> ();
+ }
}
PropertyList plist;
@@ -272,7 +275,10 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<framepos_t>&
}
boost::shared_ptr<MidiSource> src = midi_source(chan_n);
- src->set_note_mode(mode);
+
+ Glib::Threads::Mutex::Lock lm(src->mutex());
+
+ src->set_note_mode(lm, mode);
/*
cerr << "MR " << name () << " read @ " << position << " * " << to_read
@@ -285,6 +291,7 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<framepos_t>&
/* This call reads events from a source and writes them to `dst' timed in session frames */
if (src->midi_read (
+ lm, // source lock
dst, // destination buffer
_position - _start, // start position of the source in session frames
_start + internal_offset, // where to start reading in the source
@@ -429,7 +436,7 @@ MidiRegion::model_automation_state_changed (Evoral::Parameter const & p)
the iterator.
*/
Glib::Threads::Mutex::Lock lm (midi_source(0)->mutex());
- midi_source(0)->invalidate ();
+ midi_source(0)->invalidate (lm);
}
/** This is called when a trim drag has resulted in a -ve _start time for this region.
diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc
index adf28cff09..1b1cf20c68 100644
--- a/libs/ardour/midi_source.cc
+++ b/libs/ardour/midi_source.cc
@@ -177,22 +177,21 @@ MidiSource::update_length (framecnt_t)
}
void
-MidiSource::invalidate ()
+MidiSource::invalidate (const Lock& lock)
{
_model_iter_valid = false;
_model_iter.invalidate();
}
framecnt_t
-MidiSource::midi_read (Evoral::EventSink<framepos_t>& dst,
+MidiSource::midi_read (const Lock& lm,
+ Evoral::EventSink<framepos_t>& dst,
framepos_t source_start,
framepos_t start,
framecnt_t cnt,
MidiStateTracker* tracker,
const std::set<Evoral::Parameter>& filtered) const
{
- Glib::Threads::Mutex::Lock lm (_lock);
-
BeatsFramesConverter converter(_session.tempo_map(), source_start);
DEBUG_TRACE (DEBUG::MidiSourceIO,
@@ -233,22 +232,21 @@ MidiSource::midi_read (Evoral::EventSink<framepos_t>& dst,
}
return cnt;
} else {
- return read_unlocked (dst, source_start, start, cnt, tracker);
+ return read_unlocked (lm, dst, source_start, start, cnt, tracker);
}
}
framecnt_t
-MidiSource::midi_write (MidiRingBuffer<framepos_t>& source,
+MidiSource::midi_write (const Lock& lm,
+ MidiRingBuffer<framepos_t>& source,
framepos_t source_start,
framecnt_t cnt)
{
- Glib::Threads::Mutex::Lock lm (_lock);
-
- const framecnt_t ret = write_unlocked (source, source_start, cnt);
+ const framecnt_t ret = write_unlocked (lm, source, source_start, cnt);
if (cnt == max_framecnt) {
_last_read_end = 0;
- invalidate();
+ invalidate(lm);
} else {
_capture_length += cnt;
}
@@ -257,7 +255,7 @@ MidiSource::midi_write (MidiRingBuffer<framepos_t>& source,
}
void
-MidiSource::mark_streaming_midi_write_started (NoteMode mode)
+MidiSource::mark_streaming_midi_write_started (const Lock& lock, NoteMode mode)
{
if (_model) {
_model->set_note_mode (mode);
@@ -292,14 +290,15 @@ MidiSource::mark_write_starting_now (framecnt_t position,
}
void
-MidiSource::mark_streaming_write_started ()
+MidiSource::mark_streaming_write_started (const Lock& lock)
{
NoteMode note_mode = _model ? _model->note_mode() : Sustained;
- mark_streaming_midi_write_started (note_mode);
+ mark_streaming_midi_write_started (lock, note_mode);
}
void
-MidiSource::mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption option,
+MidiSource::mark_midi_streaming_write_completed (const Lock& lock,
+ Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption option,
Evoral::MusicalTime end)
{
if (_model) {
@@ -318,37 +317,39 @@ MidiSource::mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::Musica
}
void
-MidiSource::mark_streaming_write_completed ()
+MidiSource::mark_streaming_write_completed (const Lock& lock)
{
- mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::DeleteStuckNotes);
+ mark_midi_streaming_write_completed (lock, Evoral::Sequence<Evoral::MusicalTime>::DeleteStuckNotes);
}
int
-MidiSource::write_to (boost::shared_ptr<MidiSource> newsrc, Evoral::MusicalTime begin, Evoral::MusicalTime end)
+MidiSource::write_to (const Lock& lock, boost::shared_ptr<MidiSource> newsrc, Evoral::MusicalTime begin, Evoral::MusicalTime end)
{
+ Lock newsrc_lock (newsrc->mutex ());
+
newsrc->set_timeline_position (_timeline_position);
newsrc->copy_interpolation_from (this);
newsrc->copy_automation_state_from (this);
if (_model) {
if (begin == Evoral::MinMusicalTime && end == Evoral::MaxMusicalTime) {
- _model->write_to (newsrc);
+ _model->write_to (newsrc, newsrc_lock);
} else {
- _model->write_section_to (newsrc, begin, end);
+ _model->write_section_to (newsrc, newsrc_lock, begin, end);
}
} else {
error << string_compose (_("programming error: %1"), X_("no model for MidiSource during ::clone()"));
return -1;
}
- newsrc->flush_midi();
+ newsrc->flush_midi(newsrc_lock);
/* force a reload of the model if the range is partial */
if (begin != Evoral::MinMusicalTime || end != Evoral::MaxMusicalTime) {
- newsrc->load_model (true, true);
+ newsrc->load_model (newsrc_lock, true);
} else {
- newsrc->set_model (_model);
+ newsrc->set_model (newsrc_lock, _model);
}
/* this file is not removable (but since it is MIDI, it is mutable) */
@@ -361,6 +362,8 @@ MidiSource::write_to (boost::shared_ptr<MidiSource> newsrc, Evoral::MusicalTime
void
MidiSource::session_saved()
{
+ Lock lm (_lock);
+
/* this writes a copy of the data to disk.
XXX do we need to do this every time?
*/
@@ -375,18 +378,18 @@ MidiSource::session_saved()
_model.reset ();
/* Flush model contents to disk. */
- mm->sync_to_source ();
+ mm->sync_to_source (lm);
/* Reacquire model. */
_model = mm;
} else {
- flush_midi();
+ flush_midi(lm);
}
}
void
-MidiSource::set_note_mode(NoteMode mode)
+MidiSource::set_note_mode(const Lock& lock, NoteMode mode)
{
if (_model) {
_model->set_note_mode(mode);
@@ -394,18 +397,18 @@ MidiSource::set_note_mode(NoteMode mode)
}
void
-MidiSource::drop_model ()
+MidiSource::drop_model (const Lock& lock)
{
_model.reset();
- invalidate();
+ invalidate(lock);
ModelChanged (); /* EMIT SIGNAL */
}
void
-MidiSource::set_model (boost::shared_ptr<MidiModel> m)
+MidiSource::set_model (const Lock& lock, boost::shared_ptr<MidiModel> m)
{
_model = m;
- invalidate();
+ invalidate(lock);
ModelChanged (); /* EMIT SIGNAL */
}
diff --git a/libs/ardour/midi_state_tracker.cc b/libs/ardour/midi_state_tracker.cc
index afe6f07db7..f919a02f35 100644
--- a/libs/ardour/midi_state_tracker.cc
+++ b/libs/ardour/midi_state_tracker.cc
@@ -168,7 +168,7 @@ MidiStateTracker::resolve_notes (Evoral::EventSink<framepos_t> &dst, framepos_t
}
void
-MidiStateTracker::resolve_notes (MidiSource& src, Evoral::MusicalTime time)
+MidiStateTracker::resolve_notes (MidiSource& src, const MidiSource::Lock& lock, Evoral::MusicalTime time)
{
DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1 MS-resolve notes @ %2 on = %3\n", this, time, _on));
@@ -186,7 +186,7 @@ MidiStateTracker::resolve_notes (MidiSource& src, Evoral::MusicalTime time)
ev.set_channel (channel);
ev.set_note (note);
ev.set_velocity (0);
- src.append_event_unlocked_beats (ev);
+ src.append_event_beats (lock, ev);
DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1: MS-resolved note %2/%3 at %4\n",
this, (int) note, (int) channel, time));
_active_notes[note + 128 * channel]--;
diff --git a/libs/ardour/midi_stretch.cc b/libs/ardour/midi_stretch.cc
index f5b3a47b41..0e75cdca1d 100644
--- a/libs/ardour/midi_stretch.cc
+++ b/libs/ardour/midi_stretch.cc
@@ -76,7 +76,7 @@ MidiStretch::run (boost::shared_ptr<Region> r, Progress*)
return -1;
boost::shared_ptr<MidiSource> src = region->midi_source(0);
- src->load_model();
+ src->load_model(Glib::Threads::Mutex::Lock(src->mutex()));
boost::shared_ptr<MidiModel> old_model = src->model();
@@ -88,7 +88,7 @@ MidiStretch::run (boost::shared_ptr<Region> r, Progress*)
Glib::Threads::Mutex::Lock sl (new_src->mutex ());
- new_src->load_model(false, true);
+ new_src->load_model(sl, true);
boost::shared_ptr<MidiModel> new_model = new_src->model();
new_model->start_write();
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index b25977fe8d..519d8bbf10 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -203,7 +203,8 @@ SMFSource::open_for_write ()
/** All stamps in audio frames */
framecnt_t
-SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination,
+SMFSource::read_unlocked (const Lock& lock,
+ Evoral::EventSink<framepos_t>& destination,
framepos_t const source_start,
framepos_t start,
framecnt_t duration,
@@ -303,12 +304,13 @@ SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination,
}
framecnt_t
-SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source,
+SMFSource::write_unlocked (const Lock& lock,
+ MidiRingBuffer<framepos_t>& source,
framepos_t position,
framecnt_t cnt)
{
if (!_writing) {
- mark_streaming_write_started ();
+ mark_streaming_write_started (lock);
}
framepos_t time;
@@ -372,7 +374,7 @@ SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source,
continue;
}
- append_event_unlocked_frames(ev, position);
+ append_event_frames(lock, ev, position);
}
Evoral::SMF::flush ();
@@ -383,13 +385,14 @@ SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source,
/** Append an event with a timestamp in beats */
void
-SMFSource::append_event_unlocked_beats (const Evoral::Event<Evoral::MusicalTime>& ev)
+SMFSource::append_event_beats (const Glib::Threads::Mutex::Lock& lock,
+ const Evoral::Event<Evoral::MusicalTime>& ev)
{
if (!_writing || ev.size() == 0) {
return;
}
- /*printf("SMFSource: %s - append_event_unlocked_beats ID = %d time = %lf, size = %u, data = ",
+ /*printf("SMFSource: %s - append_event_beats ID = %d time = %lf, size = %u, data = ",
name().c_str(), ev.id(), ev.time(), ev.size());
for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
@@ -435,13 +438,15 @@ SMFSource::append_event_unlocked_beats (const Evoral::Event<Evoral::MusicalTime>
/** Append an event with a timestamp in frames (framepos_t) */
void
-SMFSource::append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t position)
+SMFSource::append_event_frames (const Glib::Threads::Mutex::Lock& lock,
+ const Evoral::Event<framepos_t>& ev,
+ framepos_t position)
{
if (!_writing || ev.size() == 0) {
return;
}
- // printf("SMFSource: %s - append_event_unlocked_frames ID = %d time = %u, size = %u, data = ",
+ // printf("SMFSource: %s - append_event_frames ID = %d time = %u, size = %u, data = ",
// name().c_str(), ev.id(), ev.time(), ev.size());
// for (size_t i=0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");
@@ -508,33 +513,30 @@ SMFSource::set_state (const XMLNode& node, int version)
}
void
-SMFSource::mark_streaming_midi_write_started (NoteMode mode)
+SMFSource::mark_streaming_midi_write_started (const Lock& lock, NoteMode mode)
{
- /* CALLER MUST HOLD LOCK */
-
if (!_open && open_for_write()) {
error << string_compose (_("cannot open MIDI file %1 for write"), _path) << endmsg;
/* XXX should probably throw or return something */
return;
}
- MidiSource::mark_streaming_midi_write_started (mode);
+ MidiSource::mark_streaming_midi_write_started (lock, mode);
Evoral::SMF::begin_write ();
_last_ev_time_beats = Evoral::MusicalTime();
_last_ev_time_frames = 0;
}
void
-SMFSource::mark_streaming_write_completed ()
+SMFSource::mark_streaming_write_completed (const Lock& lock)
{
- mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::DeleteStuckNotes);
+ mark_midi_streaming_write_completed (lock, Evoral::Sequence<Evoral::MusicalTime>::DeleteStuckNotes);
}
void
-SMFSource::mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption stuck_notes_option, Evoral::MusicalTime when)
+SMFSource::mark_midi_streaming_write_completed (const Lock& lm, Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption stuck_notes_option, Evoral::MusicalTime when)
{
- Glib::Threads::Mutex::Lock lm (_lock);
- MidiSource::mark_midi_streaming_write_completed (stuck_notes_option, when);
+ MidiSource::mark_midi_streaming_write_completed (lm, stuck_notes_option, when);
if (!writable()) {
warning << string_compose ("attempt to write to unwritable SMF file %1", _path) << endmsg;
@@ -596,16 +598,12 @@ static bool compare_eventlist (
}
void
-SMFSource::load_model (bool lock, bool force_reload)
+SMFSource::load_model (const Glib::Threads::Mutex::Lock& lock, bool force_reload)
{
if (_writing) {
return;
}
- boost::shared_ptr<Glib::Threads::Mutex::Lock> lm;
- if (lock)
- lm = boost::shared_ptr<Glib::Threads::Mutex::Lock>(new Glib::Threads::Mutex::Lock(_lock));
-
if (_model && !force_reload) {
return;
}
@@ -616,7 +614,7 @@ SMFSource::load_model (bool lock, bool force_reload)
_model->clear();
}
- invalidate();
+ invalidate(lock);
if (writable() && !_open) {
return;
@@ -707,33 +705,33 @@ SMFSource::load_model (bool lock, bool force_reload)
_model->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);
_model->set_edited (false);
- invalidate();
+ invalidate(lock);
free(buf);
}
void
-SMFSource::destroy_model ()
+SMFSource::destroy_model (const Glib::Threads::Mutex::Lock& lock)
{
//cerr << _name << " destroying model " << _model.get() << endl;
_model.reset();
- invalidate();
+ invalidate(lock);
}
void
-SMFSource::flush_midi ()
+SMFSource::flush_midi (const Lock& lock)
{
if (!writable() || _length_beats == 0.0) {
return;
}
- ensure_disk_file ();
+ ensure_disk_file (lock);
Evoral::SMF::end_write ();
/* data in the file means its no longer removable */
mark_nonremovable ();
- invalidate();
+ invalidate(lock);
}
void
@@ -745,7 +743,7 @@ SMFSource::set_path (const string& p)
/** Ensure that this source has some file on disk, even if it's just a SMF header */
void
-SMFSource::ensure_disk_file ()
+SMFSource::ensure_disk_file (const Lock& lock)
{
if (!writable()) {
return;
@@ -757,9 +755,9 @@ SMFSource::ensure_disk_file ()
*/
boost::shared_ptr<MidiModel> mm = _model;
_model.reset ();
- mm->sync_to_source ();
+ mm->sync_to_source (lock);
_model = mm;
- invalidate();
+ invalidate(lock);
} else {
/* No model; if it's not already open, it's an empty source, so create
and open it for writing.
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 6d2bb80b30..4005148564 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -205,7 +205,7 @@ SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks)
}
} else if (type == DataType::MIDI) {
boost::shared_ptr<SMFSource> src (new SMFSource (s, node));
- src->load_model (true, true);
+ src->load_model (Glib::Threads::Mutex::Lock(src->mutex()), true);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// boost_debug_shared_ptr_mark_interesting (src, "Source");
#endif
@@ -273,7 +273,7 @@ SourceFactory::createExternal (DataType type, Session& s, const string& path,
} else if (type == DataType::MIDI) {
boost::shared_ptr<SMFSource> src (new SMFSource (s, path));
- src->load_model (true, true);
+ src->load_model (Glib::Threads::Mutex::Lock(src->mutex()), true);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// boost_debug_shared_ptr_mark_interesting (src, "Source");
#endif
@@ -324,7 +324,7 @@ SourceFactory::createWritable (DataType type, Session& s, const std::string& pat
boost::shared_ptr<SMFSource> src (new SMFSource (s, path, SndFileSource::default_writable_flags));
assert (src->writable ());
- src->load_model (true, true);
+ src->load_model (Glib::Threads::Mutex::Lock(src->mutex()), true);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// boost_debug_shared_ptr_mark_interesting (src, "Source");
#endif