diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 0852108077..f99855d238 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -72,7 +72,7 @@ public: bool writing() const { return _writing; } void end_write(bool delete_stuck=false); - size_t read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset) const; + size_t read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset, nframes_t negative_stamp_offset) const; /** Resizes vector if necessary (NOT realtime safe) */ void append(const MIDI::Event& ev); diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h index d465506819..997f3f9d69 100644 --- a/libs/ardour/ardour/midi_source.h +++ b/libs/ardour/ardour/midi_source.h @@ -55,7 +55,7 @@ class MidiSource : public Source virtual uint32_t n_channels () const { return 1; } // FIXME: integrate this with the Readable::read interface somehow - virtual nframes_t midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const; + virtual nframes_t midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const; virtual nframes_t midi_write (MidiRingBuffer& src, nframes_t cnt); virtual void append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev) = 0; @@ -98,7 +98,7 @@ class MidiSource : public Source virtual int flush_header() = 0; virtual int flush_footer() = 0; - virtual nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const = 0; + virtual nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const = 0; virtual nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt) = 0; mutable Glib::Mutex _lock; diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h index 626aa64def..7c729b10f3 100644 --- a/libs/ardour/ardour/smf_source.h +++ b/libs/ardour/ardour/smf_source.h @@ -102,7 +102,7 @@ class SMFSource : public MidiSource { int init (string idstr, bool must_exist); - nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cn, nframes_t stamp_offset) const; + nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cn, nframes_t stamp_offset, nframes_t negative_stamp_offset) const; nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt); bool find (std::string path, bool must_exist, bool& is_new); diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 4aa229b450..43ac4b0f96 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -292,9 +292,9 @@ MidiModel::MidiModel(Session& s, size_t size) * \return number of events written to \a dst */ size_t -MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset) const +MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset, nframes_t negative_stamp_offset) const { - cerr << this << " MM::read @ " << start << " * " << nframes << " + " << stamp_offset << endl; + cerr << this << " MM::read @ " << start << " frames: " << nframes << " -> " << stamp_offset << endl; cerr << this << " MM # notes: " << n_notes() << endl; size_t read_events = 0; @@ -310,7 +310,7 @@ MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes while (_read_iter != end() && _read_iter->time() < start + nframes) { assert(_read_iter->size() > 0); - dst.write(_read_iter->time() + stamp_offset, _read_iter->size(), _read_iter->buffer()); + dst.write(_read_iter->time() + stamp_offset - negative_stamp_offset, _read_iter->size(), _read_iter->buffer()); cerr << this << " MM::read event @ " << _read_iter->time() << " type: " << hex << int(_read_iter->type()) << dec << " note: " << int(_read_iter->note()) diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 26eb0e5054..c3ce6db327 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -131,7 +131,8 @@ MidiRegion::master_read_at (MidiRingBuffer& out, nframes_t position, nframes_t d nframes_t MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const { - //cerr << _name << "._read_at(" << position << ") - " << _position << " duration: " << dur << endl; + cerr << "reading from region " << _name << " position: " << _position << " start: " << _start << endl; + cerr << _name << "._read_at(" << position << ") - " << position << " duration: " << dur << endl; nframes_t internal_offset = 0; nframes_t src_offset = 0; @@ -171,6 +172,17 @@ MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t pos boost::shared_ptr src = midi_source(chan_n); src->set_note_mode(mode); + nframes_t output_buffer_position = 0; + nframes_t negative_output_buffer_position = 0; + if(_position >= _start) { + // handle resizing of beginnings of regions correctly + output_buffer_position = _position - _start; + } else { + // when _start is greater than _position, we have to subtract + // _start from the note times in the midi source + negative_output_buffer_position = _start; + } + if (src->midi_read ( // the destination buffer dst, @@ -179,7 +191,9 @@ MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t pos // how many bytes to_read, // the offset in the output buffer - _position - _start + output_buffer_position, + // what to substract from note times written in the output buffer + negative_output_buffer_position ) != to_read) { return 0; /* "read nothing" */ } diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index eab87376eb..aeb898a31b 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -101,15 +101,15 @@ MidiSource::set_state (const XMLNode& node) } nframes_t -MidiSource::midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const +MidiSource::midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const { Glib::Mutex::Lock lm (_lock); if (_model) { - const size_t n_events = _model->read(dst, start, cnt, stamp_offset); + const size_t n_events = _model->read(dst, start, cnt, stamp_offset, negative_stamp_offset); cout << "Read " << n_events << " events from model." << endl; return cnt; } else { - return read_unlocked (dst, start, cnt, stamp_offset); + return read_unlocked (dst, start, cnt, stamp_offset, negative_stamp_offset); } } diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 6df78f3b29..18d7e87d88 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -331,7 +331,7 @@ SMFSource::read_event(uint32_t* delta_t, uint32_t* size, Byte** buf) const /** All stamps in audio frames */ nframes_t -SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const +SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const { cerr << "SMF read_unlocked " << name() << " read " << start << ", count=" << cnt << ", offset=" << stamp_offset << endl; @@ -377,7 +377,7 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n ((time / (double)_ppqn) * frames_per_beat)) + stamp_offset; if (ev_frame_time <= start + cnt) - dst.write(ev_frame_time, ev_size, ev_buffer); + dst.write(ev_frame_time - negative_stamp_offset, ev_size, ev_buffer); else break; }