mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
libardour APIs for Sequence::shift (timepos_t const &)
A way to move all MIDI data in a Sequence later in time. This is likely not finished, and may need a new signal for notifications
This commit is contained in:
parent
9c0c3309e6
commit
4ee709af7b
7 changed files with 110 additions and 1 deletions
|
|
@ -83,10 +83,25 @@ public:
|
|||
|
||||
protected:
|
||||
std::shared_ptr<MidiModel> _model;
|
||||
const std::string _name;
|
||||
const std::string _name;
|
||||
|
||||
};
|
||||
|
||||
class LIBARDOUR_API ShiftCommand : public DiffCommand {
|
||||
public:
|
||||
ShiftCommand (std::shared_ptr<MidiModel> m, std::string const & name, TimeType distance);
|
||||
ShiftCommand (std::shared_ptr<MidiModel> m, const XMLNode& node);
|
||||
|
||||
void operator() ();
|
||||
void undo ();
|
||||
|
||||
int set_state (const XMLNode&, int version);
|
||||
XMLNode & get_state () const;
|
||||
|
||||
private:
|
||||
TimeType _distance;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API NoteDiffCommand : public DiffCommand {
|
||||
public:
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ MidiModel::apply_diff_command_only (Command* cmd)
|
|||
|
||||
/* ************* DIFF COMMAND ********************/
|
||||
|
||||
#define SHIFT_COMMAND_ELEMENT "ShiftCommand"
|
||||
#define NOTE_DIFF_COMMAND_ELEMENT "NoteDiffCommand"
|
||||
#define DIFF_NOTES_ELEMENT "ChangedNotes"
|
||||
#define ADDED_NOTES_ELEMENT "AddedNotes"
|
||||
|
|
@ -146,6 +147,55 @@ MidiModel::DiffCommand::DiffCommand(std::shared_ptr<MidiModel> m, const std::str
|
|||
assert(_model);
|
||||
}
|
||||
|
||||
MidiModel::ShiftCommand::ShiftCommand (std::shared_ptr<MidiModel> m, std::string const & name, MidiModel::TimeType distance)
|
||||
: DiffCommand (m, name)
|
||||
, _distance (distance)
|
||||
{
|
||||
assert (_model);
|
||||
}
|
||||
|
||||
MidiModel::ShiftCommand::ShiftCommand (std::shared_ptr<MidiModel> m, const XMLNode& node)
|
||||
: DiffCommand (m, "")
|
||||
{
|
||||
assert (_model);
|
||||
set_state (node, Stateful::loading_state_version);
|
||||
// _name = string_compose (_("Shift MIDI by %1"), _distance.str());
|
||||
}
|
||||
|
||||
void
|
||||
MidiModel::ShiftCommand::operator() ()
|
||||
{
|
||||
_model->shift (_distance);
|
||||
_model->ContentsChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
MidiModel::ShiftCommand::undo ()
|
||||
{
|
||||
_model->shift (-_distance);
|
||||
_model->ContentsChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
int
|
||||
MidiModel::ShiftCommand::set_state (XMLNode const & diff_command, int /* version */)
|
||||
{
|
||||
if (diff_command.name() != string (SHIFT_COMMAND_ELEMENT)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff_command.get_property (X_("distance"), _distance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
MidiModel::ShiftCommand::get_state () const
|
||||
{
|
||||
XMLNode* node = new XMLNode (SHIFT_COMMAND_ELEMENT);
|
||||
node->set_property (X_("distance"), _distance);
|
||||
return *node;
|
||||
}
|
||||
|
||||
MidiModel::NoteDiffCommand::NoteDiffCommand (std::shared_ptr<MidiModel> m, const XMLNode& node)
|
||||
: DiffCommand (m, "")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1041,6 +1041,8 @@ Region::modify_front_unchecked (timepos_t const & npos, bool reset_fade)
|
|||
source_zero = timepos_t (source_position().time_domain()); // its actually negative, but this will work for us
|
||||
}
|
||||
|
||||
std::cerr << "source zero " << source_zero << std::endl;
|
||||
|
||||
if (new_position >= last) { /* can't trim it zero or negative length */
|
||||
return;
|
||||
}
|
||||
|
|
@ -1059,6 +1061,8 @@ Region::modify_front_unchecked (timepos_t const & npos, bool reset_fade)
|
|||
newlen = length() + (np.distance (position()));
|
||||
}
|
||||
|
||||
std::cerr << "tti " << np << ", " << newlen << std::endl;
|
||||
|
||||
trim_to_internal (np, newlen);
|
||||
|
||||
if (reset_fade) {
|
||||
|
|
|
|||
|
|
@ -1213,6 +1213,23 @@ ControlList::shift (timepos_t const& time, timecnt_t const& distance)
|
|||
maybe_signal_changed ();
|
||||
}
|
||||
|
||||
/* Note: timepos_t is used here instead of timecnt_t because there's an
|
||||
* implicit origin for the magnitude of the distance.
|
||||
*/
|
||||
void
|
||||
ControlList::simple_shift (timepos_t const & distance)
|
||||
{
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (_lock);
|
||||
for (auto & e : _events) {
|
||||
e->when = e->when + distance;
|
||||
}
|
||||
|
||||
mark_dirty ();
|
||||
}
|
||||
maybe_signal_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
ControlList::modify (iterator iter, timepos_t const& time, double val)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1448,6 +1448,26 @@ Sequence<Time>::control_list_marked_dirty ()
|
|||
set_edited (true);
|
||||
}
|
||||
|
||||
template<typename Time>
|
||||
void
|
||||
Sequence<Time>::shift (Time const & d)
|
||||
{
|
||||
WriteLock rl (write_lock());
|
||||
|
||||
for (auto & n : _notes) {
|
||||
n->set_time (n->time() + d);
|
||||
}
|
||||
for (auto & s : _sysexes) {
|
||||
s->set_time (s->time() + d);
|
||||
}
|
||||
for (auto & p : _patch_changes) {
|
||||
p->set_time (p->time() + d);
|
||||
}
|
||||
for (auto & [param,ctl] : _controls) {
|
||||
ctl->list()->simple_shift (Temporal::timepos_t (d));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Time>
|
||||
void
|
||||
Sequence<Time>::dump (ostream& str, typename Sequence<Time>::const_iterator x, uint32_t limit) const
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ public:
|
|||
bool extend_to (Temporal::timepos_t const & );
|
||||
void slide (iterator before, Temporal::timecnt_t const & distance);
|
||||
void shift (Temporal::timepos_t const & before, Temporal::timecnt_t const & distance);
|
||||
void simple_shift (Temporal::timepos_t const & distance);
|
||||
|
||||
void y_transform (std::function<double(double)> callback);
|
||||
void list_merge (ControlList const& other, std::function<double(double, double)> callback);
|
||||
|
|
|
|||
|
|
@ -319,6 +319,8 @@ public:
|
|||
Time duration() const { return _duration; }
|
||||
void set_duration (Time const &);
|
||||
|
||||
void shift (Time const &);
|
||||
|
||||
protected:
|
||||
bool _edited;
|
||||
bool _overlapping_pitches_accepted;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue