summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-10-07 07:20:09 +0000
committerDavid Robillard <d@drobilla.net>2007-10-07 07:20:09 +0000
commit49763a55c9bcbff2cb7844f36df777bbfadab172 (patch)
tree6751da6e2c8c24207fd197ef4fca7c5bb8f467d1 /libs
parent7d2efe25ac9ab876c91684591a7bbf02337f9476 (diff)
Fix several MIDI timestamp related problems:
Fix recording MIDI regions that start at t != 0. Fix display of MIDI events in regions that start at t != 0. Fix recording after relocating an already rec-armed MIDI track. git-svn-id: svn://localhost/ardour2/trunk@2528 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/diskstream.h1
-rw-r--r--libs/ardour/ardour/midi_diskstream.h2
-rw-r--r--libs/ardour/ardour/midi_model.h3
-rw-r--r--libs/ardour/ardour/midi_source.h5
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/ardour/smf_source.h1
-rw-r--r--libs/ardour/midi_diskstream.cc10
-rw-r--r--libs/ardour/midi_model.cc24
-rw-r--r--libs/ardour/midi_source.cc4
-rw-r--r--libs/ardour/session_transport.cc18
-rw-r--r--libs/ardour/smf_source.cc17
11 files changed, 48 insertions, 38 deletions
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index 9842ea0060..2a5c94dd68 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -101,6 +101,7 @@ class Diskstream : public SessionObject
void set_speed (double);
void non_realtime_set_speed ();
+ virtual void non_realtime_locate (nframes_t location) {};
virtual void playlist_modified ();
boost::shared_ptr<Playlist> playlist () { return _playlist; }
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index 53c7a7e22c..d08f00b72f 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -79,7 +79,6 @@ class MidiDiskstream : public Diskstream
int use_copy_playlist ();
/* stateful */
-
XMLNode& get_state(void);
int set_state(const XMLNode& node);
@@ -107,6 +106,7 @@ class MidiDiskstream : public Diskstream
int rename_write_sources ();
void reset_write_sources (bool, bool force = false);
void non_realtime_input_change ();
+ void non_realtime_locate (nframes_t location);
protected:
int seek (nframes_t which_sample, bool complete_refill = false);
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
index 6337ca8e65..28a747683c 100644
--- a/libs/ardour/ardour/midi_model.h
+++ b/libs/ardour/ardour/midi_model.h
@@ -70,9 +70,6 @@ public:
size_t read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset) const;
/** Resizes vector if necessary (NOT realtime safe) */
- void append(const MidiBuffer& data);
-
- /** Resizes vector if necessary (NOT realtime safe) */
void append(const MidiEvent& ev);
inline const Note& note_at(unsigned i) const { return _notes[i]; }
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
index 95d2a38c4e..433e7ceee9 100644
--- a/libs/ardour/ardour/midi_source.h
+++ b/libs/ardour/ardour/midi_source.h
@@ -54,11 +54,12 @@ class MidiSource : public Source
virtual void append_event_unlocked(const MidiEvent& ev) = 0;
virtual void mark_for_remove() = 0;
- virtual void mark_streaming_midi_write_started (NoteMode mode);
+ virtual void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time);
virtual void mark_streaming_write_started ();
virtual void mark_streaming_write_completed ();
- void set_timeline_position (nframes_t when) { _timeline_position = when; }
+ uint64_t timeline_position () { return _timeline_position; }
+ void set_timeline_position (nframes_t when) { _timeline_position = when; }
virtual void session_saved();
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 8709fff148..540ad08011 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1385,6 +1385,7 @@ class Session : public PBD::StatefulDestructible
void realtime_stop (bool abort);
void non_realtime_start_scrub ();
void non_realtime_set_speed ();
+ void non_realtime_locate ();
void non_realtime_stop (bool abort, int entry_request_count, bool& finished);
void non_realtime_overwrite (int entry_request_count, bool& finished);
void butler_transport_work ();
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
index 302fb15838..bb3950f2ee 100644
--- a/libs/ardour/ardour/smf_source.h
+++ b/libs/ardour/ardour/smf_source.h
@@ -77,6 +77,7 @@ class SMFSource : public MidiSource {
int move_to_trash (const string trash_dir_name);
bool is_empty () const;
+ void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time);
void mark_streaming_write_completed ();
void mark_take (string);
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 54f4c10698..2b8f70a307 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -137,6 +137,14 @@ MidiDiskstream::~MidiDiskstream ()
Glib::Mutex::Lock lm (state_lock);
}
+
+void
+MidiDiskstream::non_realtime_locate (nframes_t position)
+{
+ _write_source->set_timeline_position (position);
+}
+
+
void
MidiDiskstream::non_realtime_input_change ()
{
@@ -1195,7 +1203,7 @@ MidiDiskstream::engage_record_enable ()
_source_port->request_monitor_input (!(Config->get_auto_input() && rolling));
}
- _write_source->mark_streaming_midi_write_started (_note_mode);
+ _write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
RecordEnableChanged (); /* EMIT SIGNAL */
}
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index 7c02f5095f..d7167ed2ec 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -450,30 +450,6 @@ MidiModel::end_write(bool delete_stuck)
}
-/** Append contents of \a buf to model. NOT realtime safe.
- *
- * Timestamps of events in \a buf are expected to be relative to
- * the start of this model (t=0) and MUST be monotonically increasing
- * and MUST be >= the latest event currently in the model.
- *
- * Events in buf are deep copied.
- */
-void
-MidiModel::append(const MidiBuffer& buf)
-{
- write_lock();
-
- assert(_writing);
-
- for (MidiBuffer::const_iterator i = buf.begin(); i != buf.end(); ++i) {
- assert(_notes.empty() || (*i).time() >= _notes.back().time());
- append(*i);
- }
-
- write_unlock();
-}
-
-
/** Append \a in_event to model. NOT realtime safe.
*
* Timestamps of events in \a buf are expected to be relative to
diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc
index 4c97bb4e6d..f072c2a7ef 100644
--- a/libs/ardour/midi_source.cc
+++ b/libs/ardour/midi_source.cc
@@ -131,8 +131,10 @@ MidiSource::file_changed (string path)
}
void
-MidiSource::mark_streaming_midi_write_started (NoteMode mode)
+MidiSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame)
{
+ set_timeline_position(start_frame); // why do I have a feeling this can break somehow...
+
if (_model) {
_model->set_note_mode(mode);
_model->start_write();
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index c122989b68..2776fbf41d 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -238,8 +238,12 @@ Session::butler_transport_work ()
}
}
}
+
+ if (post_transport_work & PostTransportLocate) {
+ non_realtime_locate ();
+ }
- if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
+ if (post_transport_work & PostTransportStop) {
non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
if (!finished) {
g_atomic_int_dec_and_test (&butler_should_do_transport_work);
@@ -288,6 +292,18 @@ Session::non_realtime_overwrite (int on_entry, bool& finished)
}
}
+
+void
+Session::non_realtime_locate ()
+{
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ (*i)->non_realtime_locate (_transport_frame);
+ }
+}
+
+
void
Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
{
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 4ad8f80b4b..3bc53cb538 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -159,7 +159,6 @@ SMFSource::open()
_track_size = 4;
// Write a tentative header just to pad things out so writing happens in the right spot
- set_timeline_position(0);
flush_header();
write_footer();
seek_to_end();
@@ -403,7 +402,7 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
while (true) {
bool ret = src.full_peek(sizeof(double), (Byte*)&time);
- if (!ret || time > _length + cnt)
+ if (!ret || time - _timeline_position > _length + cnt)
break;
ret = src.read_prefix(&time, &size);
@@ -423,10 +422,9 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
assert(time >= _timeline_position);
time -= _timeline_position;
- assert(time >= _last_ev_time);
const MidiEvent ev(time, size, buf);
- append_event_unlocked(MidiEvent(ev));
+ append_event_unlocked(ev);
if (_model)
_model->append(ev);
@@ -438,7 +436,7 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
const nframes_t oldlen = _length;
update_length(oldlen, cnt);
- ViewDataRangeReady (oldlen, cnt); /* EMIT SIGNAL */
+ ViewDataRangeReady (_timeline_position + oldlen, cnt); /* EMIT SIGNAL */
return cnt;
}
@@ -453,6 +451,8 @@ SMFSource::append_event_unlocked(const MidiEvent& ev)
}
printf("\n");*/
+ assert(ev.time() >= 0);
+
assert(ev.time() >= _last_ev_time);
// FIXME: assumes tempo never changes after start
@@ -517,6 +517,13 @@ SMFSource::mark_for_remove ()
}
void
+SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame)
+{
+ MidiSource::mark_streaming_midi_write_started (mode, start_frame);
+ _last_ev_time = 0;
+}
+
+void
SMFSource::mark_streaming_write_completed ()
{
MidiSource::mark_streaming_write_completed();