mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-24 06:07:29 +01:00
* Renamed CanvasMidiEvent into CanvasNoteEvent
* changed MidiModel::write_to to include note off handling *and* time sorting git-svn-id: svn://localhost/ardour2/branches/3.0@3294 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
6d319e2132
commit
58e569c9e1
8 changed files with 45 additions and 64 deletions
|
|
@ -35,7 +35,7 @@ public:
|
|||
double size,
|
||||
const boost::shared_ptr<ARDOUR::Note> note = boost::shared_ptr<ARDOUR::Note>())
|
||||
|
||||
: Diamond(group, size), CanvasMidiEvent(region, this, note)
|
||||
: Diamond(group, size), CanvasNoteEvent(region, this, note)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Gnome {
|
|||
namespace Canvas {
|
||||
|
||||
|
||||
CanvasNoteEvent::CanvasMidiEvent(MidiRegionView& region, Item* item,
|
||||
CanvasNoteEvent::CanvasNoteEvent(MidiRegionView& region, Item* item,
|
||||
const boost::shared_ptr<ARDOUR::Note> note)
|
||||
: _region(region)
|
||||
, _item(item)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace Canvas {
|
|||
*/
|
||||
class CanvasNoteEvent : public sigc::trackable {
|
||||
public:
|
||||
CanvasMidiEvent(
|
||||
CanvasNoteEvent(
|
||||
MidiRegionView& region,
|
||||
Item* item,
|
||||
const boost::shared_ptr<ARDOUR::Note> note = boost::shared_ptr<ARDOUR::Note>());
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public:
|
|||
Group& group,
|
||||
const boost::shared_ptr<ARDOUR::Note> note = boost::shared_ptr<ARDOUR::Note>())
|
||||
|
||||
: SimpleRect(group), CanvasMidiEvent(region, this, note)
|
||||
: SimpleRect(group), CanvasNoteEvent(region, this, note)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
|
|||
double wx, wy;
|
||||
nframes_t xdelta;
|
||||
int direction = ev->direction;
|
||||
CanvasMidiEvent *midi_event = dynamic_cast<CanvasMidiEvent *>(track_canvas->get_item_at(ev->x, ev->y));
|
||||
CanvasNoteEvent *midi_event = dynamic_cast<CanvasNoteEvent *>(track_canvas->get_item_at(ev->x, ev->y));
|
||||
|
||||
retry:
|
||||
switch (direction) {
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ MidiRegionView::clear_events()
|
|||
}
|
||||
}
|
||||
|
||||
for (std::vector<CanvasMidiEvent*>::iterator i = _events.begin(); i != _events.end(); ++i)
|
||||
for (std::vector<CanvasNoteEvent*>::iterator i = _events.begin(); i != _events.end(); ++i)
|
||||
delete *i;
|
||||
|
||||
_events.clear();
|
||||
|
|
@ -570,8 +570,8 @@ MidiRegionView::set_y_position_and_height (double y, double h)
|
|||
|
||||
_model->read_lock();
|
||||
|
||||
for (std::vector<CanvasMidiEvent*>::const_iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
CanvasMidiEvent* event = *i;
|
||||
for (std::vector<CanvasNoteEvent*>::const_iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
CanvasNoteEvent* event = *i;
|
||||
Item* item = dynamic_cast<Item*>(event);
|
||||
assert(item);
|
||||
if (event && event->note()) {
|
||||
|
|
@ -646,7 +646,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
|
|||
ghost->set_duration (_region->length() / samples_per_unit);
|
||||
ghosts.push_back (ghost);
|
||||
|
||||
for (std::vector<CanvasMidiEvent*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
for (std::vector<CanvasNoteEvent*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
if ((note = dynamic_cast<CanvasNote*>(*i)) != 0) {
|
||||
ghost->add_note(note);
|
||||
}
|
||||
|
|
@ -735,7 +735,7 @@ MidiRegionView::add_note(const boost::shared_ptr<Note> note)
|
|||
|
||||
ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
|
||||
|
||||
CanvasMidiEvent *event = 0;
|
||||
CanvasNoteEvent *event = 0;
|
||||
|
||||
const double x = trackview.editor.frame_to_pixel((nframes_t)note->time() - _region->start());
|
||||
|
||||
|
|
@ -837,7 +837,7 @@ MidiRegionView::delete_selection()
|
|||
}
|
||||
|
||||
void
|
||||
MidiRegionView::clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev)
|
||||
MidiRegionView::clear_selection_except(ArdourCanvas::CanvasNoteEvent* ev)
|
||||
{
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i)
|
||||
if ((*i)->selected() && (*i) != ev)
|
||||
|
|
@ -847,7 +847,7 @@ MidiRegionView::clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev)
|
|||
}
|
||||
|
||||
void
|
||||
MidiRegionView::unique_select(ArdourCanvas::CanvasMidiEvent* ev)
|
||||
MidiRegionView::unique_select(ArdourCanvas::CanvasNoteEvent* ev)
|
||||
{
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i)
|
||||
if ((*i) != ev)
|
||||
|
|
@ -861,7 +861,7 @@ MidiRegionView::unique_select(ArdourCanvas::CanvasMidiEvent* ev)
|
|||
}
|
||||
|
||||
void
|
||||
MidiRegionView::note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add)
|
||||
MidiRegionView::note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add)
|
||||
{
|
||||
if ( ! add)
|
||||
clear_selection_except(ev);
|
||||
|
|
@ -874,7 +874,7 @@ MidiRegionView::note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add)
|
|||
|
||||
|
||||
void
|
||||
MidiRegionView::note_deselected(ArdourCanvas::CanvasMidiEvent* ev, bool add)
|
||||
MidiRegionView::note_deselected(ArdourCanvas::CanvasNoteEvent* ev, bool add)
|
||||
{
|
||||
if ( ! add)
|
||||
clear_selection_except(ev);
|
||||
|
|
@ -895,7 +895,7 @@ MidiRegionView::update_drag_selection(double x1, double x2, double y1, double y2
|
|||
// FIXME: so, so, so much slower than this should be
|
||||
|
||||
if (x1 < x2) {
|
||||
for (std::vector<CanvasMidiEvent*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
for (std::vector<CanvasNoteEvent*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
if ((*i)->x1() >= x1 && (*i)->x1() <= x2 && (*i)->y1() >= last_y && (*i)->y1() <= y) {
|
||||
(*i)->selected(true);
|
||||
_selection.insert(*i);
|
||||
|
|
@ -905,7 +905,7 @@ MidiRegionView::update_drag_selection(double x1, double x2, double y1, double y2
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for (std::vector<CanvasMidiEvent*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
for (std::vector<CanvasNoteEvent*>::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
if ((*i)->x2() <= x1 && (*i)->x2() >= x2 && (*i)->y1() >= last_y && (*i)->y1() <= y) {
|
||||
(*i)->selected(true);
|
||||
_selection.insert(*i);
|
||||
|
|
@ -927,7 +927,7 @@ MidiRegionView::move_selection(double dx, double dy)
|
|||
|
||||
|
||||
void
|
||||
MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote)
|
||||
MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
|
||||
{
|
||||
// TODO: This would be faster/nicer with a MoveCommand that doesn't need to copy...
|
||||
if (_selection.find(ev) != _selection.end()) {
|
||||
|
|
@ -1196,7 +1196,7 @@ MidiRegionView::change_velocity(uint8_t velocity, bool relative)
|
|||
Selection::iterator next = i;
|
||||
++next;
|
||||
|
||||
CanvasMidiEvent *event = *i;
|
||||
CanvasNoteEvent *event = *i;
|
||||
const boost::shared_ptr<Note> copy(new Note(*(event->note().get())));
|
||||
|
||||
if(relative) {
|
||||
|
|
@ -1231,7 +1231,7 @@ MidiRegionView::change_channel(uint8_t channel)
|
|||
Selection::iterator next = i;
|
||||
++next;
|
||||
|
||||
CanvasMidiEvent *event = *i;
|
||||
CanvasNoteEvent *event = *i;
|
||||
const boost::shared_ptr<Note> copy(new Note(*(event->note().get())));
|
||||
|
||||
copy->set_channel(channel);
|
||||
|
|
@ -1253,7 +1253,7 @@ MidiRegionView::change_channel(uint8_t channel)
|
|||
|
||||
|
||||
void
|
||||
MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev)
|
||||
MidiRegionView::note_entered(ArdourCanvas::CanvasNoteEvent* ev)
|
||||
{
|
||||
if (ev->note() && _mouse_state == EraseTouchDragging) {
|
||||
start_delta_command(_("note entered"));
|
||||
|
|
@ -1298,7 +1298,7 @@ MidiRegionView::midi_channel_selection_changed(uint16_t selection)
|
|||
selection = 0xFFFF;
|
||||
}
|
||||
|
||||
for(std::vector<ArdourCanvas::CanvasMidiEvent*>::iterator i = _events.begin();
|
||||
for(std::vector<ArdourCanvas::CanvasNoteEvent*>::iterator i = _events.begin();
|
||||
i != _events.end();
|
||||
++i) {
|
||||
(*i)->on_channel_selection_change(selection);
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ class MidiRegionView : public RegionView
|
|||
MouseState _mouse_state;
|
||||
int _pressed_button;
|
||||
|
||||
/// currently selected CanvasMidiEvents
|
||||
/// currently selected CanvasNoteEvents
|
||||
typedef std::set<ArdourCanvas::CanvasNoteEvent*> Selection;
|
||||
Selection _selection;
|
||||
|
||||
|
|
|
|||
|
|
@ -884,47 +884,23 @@ MidiModel::write_to(boost::shared_ptr<MidiSource> source)
|
|||
* note durations.
|
||||
*/
|
||||
|
||||
/* Percussive
|
||||
for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
||||
const MIDI::Event& ev = n->on_event();
|
||||
source->append_event_unlocked(ev);
|
||||
}*/
|
||||
|
||||
read_lock();
|
||||
|
||||
//LaterNoteEndComparator cmp;
|
||||
//ActiveNotes active_notes(cmp);
|
||||
LaterNoteEndComparator cmp;
|
||||
ActiveNotes active_notes(cmp);
|
||||
|
||||
EventTimeComparator comp;
|
||||
typedef std::priority_queue<
|
||||
MIDI::Event*,
|
||||
std::deque<MIDI::Event*>,
|
||||
const MIDI::Event*,
|
||||
std::deque<const MIDI::Event*>,
|
||||
EventTimeComparator> MidiEvents;
|
||||
|
||||
MidiEvents events(comp);
|
||||
|
||||
|
||||
for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
||||
events.push(&(*n)->on_event());
|
||||
events.push(&(*n)->off_event());
|
||||
}
|
||||
|
||||
for (PgmChanges::const_iterator p = _pgm_changes.begin(); p != _pgm_changes.end(); ++p) {
|
||||
events.push((*p).get());
|
||||
}
|
||||
|
||||
while(!events.empty()) {
|
||||
source->append_event_unlocked(Frames, *events.top());
|
||||
cerr << "MidiModel::write_to appending event with time:" << dec << int(events.top()->time()) << hex
|
||||
<< " buffer: 0x" << int(events.top()->buffer()[0]) << " 0x" << int(events.top()->buffer()[1])
|
||||
<< " 0x" << int(events.top()->buffer()[2]) << endl;
|
||||
events.pop();
|
||||
}
|
||||
|
||||
|
||||
/* Why sort manyally, when a priority queue does the job for us,
|
||||
* or am I missing something???
|
||||
*
|
||||
* (I am probably wrong here, but I needed that to test program
|
||||
* change code quickly) ???
|
||||
* */
|
||||
// Foreach note
|
||||
for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
||||
|
||||
|
|
@ -933,32 +909,37 @@ MidiModel::write_to(boost::shared_ptr<MidiSource> source)
|
|||
const boost::shared_ptr<const Note> earliest_off = active_notes.top();
|
||||
const MIDI::Event& off_ev = earliest_off->off_event();
|
||||
if (off_ev.time() <= (*n)->time()) {
|
||||
source->append_event_unlocked(Frames, off_ev);
|
||||
events.push(&off_ev);
|
||||
active_notes.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Write program changes preceding this note on
|
||||
if(p != _pgm_changes.end() && ((*p)->time() <= (*n)->time())) {
|
||||
const MIDI::Event& pgm_change_event = *(*p);
|
||||
source->append_event_unlocked(Frames, pgm_change_event);
|
||||
++p;
|
||||
}
|
||||
|
||||
// Write this note on
|
||||
source->append_event_unlocked(Frames, (*n)->on_event());
|
||||
events.push(&(*n)->on_event());
|
||||
if ((*n)->duration() > 0)
|
||||
active_notes.push(*n);
|
||||
}
|
||||
|
||||
// Write any trailing note offs
|
||||
while ( ! active_notes.empty() ) {
|
||||
source->append_event_unlocked(Frames, active_notes.top()->off_event());
|
||||
events.push(&active_notes.top()->off_event());
|
||||
active_notes.pop();
|
||||
}
|
||||
*/
|
||||
|
||||
//write program changes
|
||||
for (PgmChanges::const_iterator p = _pgm_changes.begin(); p != _pgm_changes.end(); ++p) {
|
||||
events.push((*p).get());
|
||||
}
|
||||
|
||||
while(!events.empty()) {
|
||||
source->append_event_unlocked(Frames, *events.top());
|
||||
cerr << "MidiModel::write_to appending event with time:" << dec << int(events.top()->time()) << hex
|
||||
<< " buffer: 0x" << int(events.top()->buffer()[0]) << " 0x" << int(events.top()->buffer()[1])
|
||||
<< " 0x" << int(events.top()->buffer()[2]) << endl;
|
||||
events.pop();
|
||||
}
|
||||
|
||||
_edited = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue