* 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:
Hans Baier 2008-04-29 08:37:53 +00:00
parent 6d319e2132
commit 58e569c9e1
8 changed files with 45 additions and 64 deletions

View file

@ -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)
{
}

View file

@ -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)

View file

@ -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>());

View file

@ -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)
{
}

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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;