mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-04 04:39:33 +01:00
various minor MIDI fixes: prevent duplicate note entry with mouse, show note info more often with verbose cursor, fix some crashes from click+move on notes ... lots more where this comes from
git-svn-id: svn://localhost/ardour2/branches/3.0@7128 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
e58f6752af
commit
a196405da9
9 changed files with 90 additions and 21 deletions
|
|
@ -151,8 +151,9 @@ public:
|
|||
void apply_command(Session& session, Command* cmd);
|
||||
void apply_command_as_subcommand(Session& session, Command* cmd);
|
||||
|
||||
bool write_to(boost::shared_ptr<MidiSource> source, Evoral::MusicalTime begin = Evoral::MinMusicalTime,
|
||||
Evoral::MusicalTime end = Evoral::MaxMusicalTime);
|
||||
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);
|
||||
|
||||
// MidiModel doesn't use the normal AutomationList serialisation code
|
||||
// since controller data is stored in the .mid
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class MidiSource : virtual public Source
|
|||
|
||||
boost::shared_ptr<MidiModel> model() { return _model; }
|
||||
void set_model(boost::shared_ptr<MidiModel> m) { _model = m; }
|
||||
void drop_model() { _model.reset(); }
|
||||
void drop_model();
|
||||
|
||||
protected:
|
||||
virtual void flush_midi() = 0;
|
||||
|
|
|
|||
|
|
@ -676,6 +676,36 @@ MidiModel::DiffCommand::get_state ()
|
|||
return *diff_command;
|
||||
}
|
||||
|
||||
/** Write all of the model to a MidiSource (i.e. save the model).
|
||||
* This is different from manually using read to write to a source in that
|
||||
* note off events are written regardless of the track mode. This is so the
|
||||
* user can switch a recorded track (with note durations from some instrument)
|
||||
* to percussive, save, reload, then switch it back to sustained without
|
||||
* destroying the original note durations.
|
||||
*/
|
||||
bool
|
||||
MidiModel::write_to (boost::shared_ptr<MidiSource> source)
|
||||
{
|
||||
ReadLock lock(read_lock());
|
||||
|
||||
const bool old_percussive = percussive();
|
||||
set_percussive(false);
|
||||
|
||||
source->drop_model();
|
||||
source->mark_streaming_midi_write_started(note_mode(), _midi_source->timeline_position());
|
||||
|
||||
for (Evoral::Sequence<TimeType>::const_iterator i = begin(); i != end(); ++i) {
|
||||
source->append_event_unlocked_beats(*i);
|
||||
}
|
||||
|
||||
set_percussive(old_percussive);
|
||||
source->mark_streaming_write_completed();
|
||||
|
||||
set_edited(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Write part or all of the model to a MidiSource (i.e. save the model).
|
||||
* This is different from manually using read to write to a source in that
|
||||
* note off events are written regardless of the track mode. This is so the
|
||||
|
|
@ -684,7 +714,7 @@ MidiModel::DiffCommand::get_state ()
|
|||
* destroying the original note durations.
|
||||
*/
|
||||
bool
|
||||
MidiModel::write_to (boost::shared_ptr<MidiSource> source, Evoral::MusicalTime begin_time, Evoral::MusicalTime end_time)
|
||||
MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::MusicalTime begin_time, Evoral::MusicalTime end_time)
|
||||
{
|
||||
ReadLock lock(read_lock());
|
||||
MidiStateTracker mst;
|
||||
|
|
|
|||
|
|
@ -250,7 +250,11 @@ MidiSource::clone (Evoral::MusicalTime begin, Evoral::MusicalTime end)
|
|||
newsrc->set_timeline_position(_timeline_position);
|
||||
|
||||
if (_model) {
|
||||
_model->write_to (newsrc, begin, end);
|
||||
if (begin == Evoral::MinMusicalTime && end == Evoral::MaxMusicalTime) {
|
||||
_model->write_to (newsrc);
|
||||
} else {
|
||||
_model->write_section_to (newsrc, begin, end);
|
||||
}
|
||||
} else {
|
||||
error << string_compose (_("programming error: %1"), X_("no model for MidiSource during ::clone()"));
|
||||
return boost::shared_ptr<MidiSource>();
|
||||
|
|
@ -290,3 +294,9 @@ MidiSource::set_note_mode(NoteMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiSource::drop_model ()
|
||||
{
|
||||
cerr << name() << " drop model\n";
|
||||
_model.reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,8 @@ public:
|
|||
bool edited() const { return _edited; }
|
||||
void set_edited(bool yn) { _edited = yn; }
|
||||
|
||||
void add_note_unlocked(const boost::shared_ptr< Note<Time> > note);
|
||||
bool contains (const boost::shared_ptr< Note<Time> > ev) const;
|
||||
bool add_note_unlocked(const boost::shared_ptr< Note<Time> > note);
|
||||
void remove_note_unlocked(const boost::shared_ptr< const Note<Time> > note);
|
||||
|
||||
uint8_t lowest_note() const { return _lowest_note; }
|
||||
|
|
|
|||
|
|
@ -730,12 +730,38 @@ Sequence<Time>::append_sysex_unlocked(const MIDIEvent<Time>& ev)
|
|||
}
|
||||
|
||||
template<typename Time>
|
||||
void
|
||||
bool
|
||||
Sequence<Time>::contains(const boost::shared_ptr< Note<Time> > note) const
|
||||
{
|
||||
ReadLock lock (read_lock());
|
||||
|
||||
for (typename Sequence<Time>::Notes::const_iterator i = note_lower_bound(note->time());
|
||||
i != _notes.end() && (*i)->time() == note->time(); ++i) {
|
||||
if (*i == note) {
|
||||
cerr << "Existing note matches: " << *i << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
cerr << "No matching note for " << note << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Time>
|
||||
bool
|
||||
Sequence<Time>::add_note_unlocked(const boost::shared_ptr< Note<Time> > note)
|
||||
{
|
||||
DUMP(format("%1% add note %2% @ %3%\n") % this % (int)note->note() % note->time());
|
||||
|
||||
for (typename Sequence<Time>::Notes::iterator i = note_lower_bound(note->time());
|
||||
i != _notes.end() && (*i)->time() == note->time(); ++i) {
|
||||
if (*i == note) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_edited = true;
|
||||
_notes.insert(note);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Time>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue