#include <ardour/midi_region.h>
#include <ardour/midi_source.h>
#include <ardour/midi_diskstream.h>
+#include <ardour/midi_events.h>
#include "streamview.h"
#include "midi_region_view.h"
#include "simplerect.h"
#include "simpleline.h"
#include "public_editor.h"
-//#include "midi_region_editor.h"
#include "ghostregion.h"
#include "midi_time_axis.h"
#include "utils.h"
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu,
Gdk::Color& basic_color)
: RegionView (parent, tv, r, spu, basic_color)
+ , _active_notes(0)
{
}
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu,
Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
: RegionView (parent, tv, r, spu, basic_color, visibility)
+ , _active_notes(0)
{
}
reset_width_dependent_items ((double) _region->length() / samples_per_unit);
- set_height (trackview.height);
+ set_y_position_and_height (0, trackview.height);
region_muted ();
region_resized (BoundsChanged);
_region->StateChanged.connect (mem_fun(*this, &MidiRegionView::region_changed));
set_colors ();
+
+ if (wfd) {
+ midi_region()->midi_source(0)->load_model();
+ display_events();
+ }
}
+
+void
+MidiRegionView::display_events()
+{
+ for (std::vector<ArdourCanvas::Item*>::iterator i = _events.begin(); i != _events.end(); ++i)
+ delete *i;
+
+ _events.clear();
+ begin_write();
+
+ for (size_t i=0; i < midi_region()->midi_source(0)->model()->n_events(); ++i)
+ add_event(midi_region()->midi_source(0)->model()->event_at(i));
+
+ end_write();
+}
+
+
MidiRegionView::~MidiRegionView ()
{
in_destructor = true;
+ end_write();
RegionViewGoingAway (this); /* EMIT_SIGNAL */
}
return boost::dynamic_pointer_cast<MidiRegion>(_region);
}
+void
+MidiRegionView::region_resized (Change what_changed)
+{
+ RegionView::region_resized(what_changed);
+
+ if (what_changed & ARDOUR::PositionChanged) {
+
+ display_events();
+
+ } else if (what_changed & Change (StartChanged)) {
+
+ //cerr << "MIDI RV START CHANGED" << endl;
+
+ } else if (what_changed & Change (LengthChanged)) {
+
+ //cerr << "MIDI RV LENGTH CHANGED" << endl;
+
+ }
+}
+
+void
+MidiRegionView::reset_width_dependent_items (double pixel_width)
+{
+ RegionView::reset_width_dependent_items(pixel_width);
+ assert(_pixel_width == pixel_width);
+
+ display_events();
+}
+
+void
+MidiRegionView::set_y_position_and_height (double y, double h)
+{
+ RegionView::set_y_position_and_height(y, h - 1);
+
+ display_events();
+
+ if (name_text) {
+ name_text->raise_to_top();
+ }
+}
+
void
MidiRegionView::show_region_editor ()
{
return NULL;
}
+
+/** Begin tracking note state for successive calls to add_event
+ */
+void
+MidiRegionView::begin_write()
+{
+ _active_notes = new ArdourCanvas::SimpleRect*[128];
+ for (unsigned i=0; i < 128; ++i)
+ _active_notes[i] = NULL;
+}
+
+
+/** Destroy note state for add_event
+ */
+void
+MidiRegionView::end_write()
+{
+ delete[] _active_notes;
+ _active_notes = NULL;
+}
+
+
+void
+MidiRegionView::add_event (const MidiEvent& ev)
+{
+ /*printf("Event, time = %f, size = %zu, data = ", ev.time, ev.size);
+ for (size_t i=0; i < ev.size; ++i) {
+ printf("%X ", ev.buffer[i]);
+ }
+ printf("\n\n");*/
+
+ double y1 = trackview.height / 2.0;
+ if ((ev.buffer[0] & 0xF0) == MIDI_CMD_NOTE_ON) {
+ const Byte& note = ev.buffer[1];
+ y1 = trackview.height - ((trackview.height / 127.0) * note);
+
+ ArdourCanvas::SimpleRect * ev_rect = new Gnome::Canvas::SimpleRect(
+ *(ArdourCanvas::Group*)get_canvas_group());
+ ev_rect->property_x1() = trackview.editor.frame_to_pixel (
+ (nframes_t)ev.time);
+ ev_rect->property_y1() = y1;
+ ev_rect->property_x2() = trackview.editor.frame_to_pixel (
+ _region->length());
+ ev_rect->property_y2() = y1 + ceil(trackview.height / 127.0);
+ ev_rect->property_outline_color_rgba() = 0xFFFFFFAA;
+ /* outline all but right edge */
+ ev_rect->property_outline_what() = (guint32) (0x1 & 0x4 & 0x8);
+ ev_rect->property_fill_color_rgba() = 0xFFFFFF66;
+
+ _events.push_back(ev_rect);
+ if (_active_notes)
+ _active_notes[note] = ev_rect;
+
+ } else if ((ev.buffer[0] & 0xF0) == MIDI_CMD_NOTE_OFF) {
+ const Byte& note = ev.buffer[1];
+ if (_active_notes && _active_notes[note]) {
+ _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes_t)ev.time);
+ _active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges
+ _active_notes[note] = NULL;
+ }
+ }
+
+}
+
+
+/** Extend active notes to rightmost edge of region (if length is changed)
+ */
+void
+MidiRegionView::extend_active_notes()
+{
+ if (!_active_notes)
+ return;
+
+ for (unsigned i=0; i < 128; ++i)
+ if (_active_notes[i])
+ _active_notes[i]->property_x2() = trackview.editor.frame_to_pixel(_region->length());
+}
+
+
+