summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/SConscript1
-rw-r--r--gtk2_ardour/canvas-hit.h4
-rw-r--r--gtk2_ardour/canvas-midi-event.cc24
-rw-r--r--gtk2_ardour/canvas-midi-event.h4
-rw-r--r--gtk2_ardour/canvas-note.cc4
-rw-r--r--gtk2_ardour/canvas-note.h2
-rw-r--r--gtk2_ardour/canvas-program-change.cc58
-rw-r--r--gtk2_ardour/canvas-program-change.h43
-rw-r--r--gtk2_ardour/canvas_vars.h2
-rw-r--r--gtk2_ardour/ghostregion.cc2
-rw-r--r--gtk2_ardour/ghostregion.h6
-rw-r--r--gtk2_ardour/midi_region_view.cc32
-rw-r--r--gtk2_ardour/midi_region_view.h21
-rw-r--r--libs/ardour/midi_model.cc17
14 files changed, 180 insertions, 40 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index 5b4fa141f9..aceb587998 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -131,6 +131,7 @@ automation_streamview.cc
automation_time_axis.cc
axis_view.cc
bundle_manager.cc
+canvas-program-change.cc
canvas-midi-event.cc
canvas-note.cc
canvas-simpleline.c
diff --git a/gtk2_ardour/canvas-hit.h b/gtk2_ardour/canvas-hit.h
index e9be381ef2..ffa1764003 100644
--- a/gtk2_ardour/canvas-hit.h
+++ b/gtk2_ardour/canvas-hit.h
@@ -27,7 +27,7 @@
namespace Gnome {
namespace Canvas {
-class CanvasHit : public Diamond, public CanvasMidiEvent {
+class CanvasHit : public Diamond, public CanvasNoteEvent {
public:
CanvasHit(
MidiRegionView& region,
@@ -47,7 +47,7 @@ public:
void set_outline_color(uint32_t c) { property_outline_color_rgba() = c; }
void set_fill_color(uint32_t c) { property_fill_color_rgba() = c; }
- bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
+ bool on_event(GdkEvent* ev) { return CanvasNoteEvent::on_event(ev); }
};
} // namespace Gnome
diff --git a/gtk2_ardour/canvas-midi-event.cc b/gtk2_ardour/canvas-midi-event.cc
index f87ae135cb..20804260b2 100644
--- a/gtk2_ardour/canvas-midi-event.cc
+++ b/gtk2_ardour/canvas-midi-event.cc
@@ -31,7 +31,7 @@ namespace Gnome {
namespace Canvas {
-CanvasMidiEvent::CanvasMidiEvent(MidiRegionView& region, Item* item,
+CanvasNoteEvent::CanvasMidiEvent(MidiRegionView& region, Item* item,
const boost::shared_ptr<ARDOUR::Note> note)
: _region(region)
, _item(item)
@@ -44,21 +44,21 @@ CanvasMidiEvent::CanvasMidiEvent(MidiRegionView& region, Item* item,
_text = new Text(*(item->property_parent()));
}
-CanvasMidiEvent::~CanvasMidiEvent()
+CanvasNoteEvent::~CanvasNoteEvent()
{
if(_text) delete _text;
if(_channel_selector_widget) delete _channel_selector_widget;
}
void
-CanvasMidiEvent::move_event(double dx, double dy)
+CanvasNoteEvent::move_event(double dx, double dy)
{
_item->move(dx, dy);
_text->move(dx, dy);
}
void
-CanvasMidiEvent::show_velocity(void)
+CanvasNoteEvent::show_velocity(void)
{
_text->property_x() = (x1() + x2()) /2;
_text->property_y() = (y1() + y2()) /2;
@@ -73,13 +73,13 @@ CanvasMidiEvent::show_velocity(void)
}
void
-CanvasMidiEvent::hide_velocity(void)
+CanvasNoteEvent::hide_velocity(void)
{
_text->hide();
}
void
-CanvasMidiEvent::on_channel_selection_change(uint16_t selection)
+CanvasNoteEvent::on_channel_selection_change(uint16_t selection)
{
// make note change its color if its channel is not marked active
if( (selection & (1 << _note->channel())) == 0 ) {
@@ -95,7 +95,7 @@ CanvasMidiEvent::on_channel_selection_change(uint16_t selection)
}
void
-CanvasMidiEvent::on_channel_change(uint8_t channel)
+CanvasNoteEvent::on_channel_change(uint8_t channel)
{
_region.note_selected(this, true);
hide_channel_selector();
@@ -103,14 +103,14 @@ CanvasMidiEvent::on_channel_change(uint8_t channel)
}
void
-CanvasMidiEvent::show_channel_selector(void)
+CanvasNoteEvent::show_channel_selector(void)
{
if(_channel_selector_widget == 0) {
cerr << "Note has channel: " << int(_note->channel()) << endl;
SingleMidiChannelSelector* _channel_selector = new SingleMidiChannelSelector(_note->channel());
_channel_selector->show_all();
_channel_selector->channel_selected.connect(
- sigc::mem_fun(this, &CanvasMidiEvent::on_channel_change));
+ sigc::mem_fun(this, &CanvasNoteEvent::on_channel_change));
_channel_selector_widget =
new Widget(*(_item->property_parent()),
@@ -129,7 +129,7 @@ CanvasMidiEvent::show_channel_selector(void)
}
void
-CanvasMidiEvent::hide_channel_selector(void)
+CanvasNoteEvent::hide_channel_selector(void)
{
if(_channel_selector_widget) {
_channel_selector_widget->hide();
@@ -139,7 +139,7 @@ CanvasMidiEvent::hide_channel_selector(void)
}
void
-CanvasMidiEvent::selected(bool yn)
+CanvasNoteEvent::selected(bool yn)
{
if (!_note) {
return;
@@ -159,7 +159,7 @@ CanvasMidiEvent::selected(bool yn)
bool
-CanvasMidiEvent::on_event(GdkEvent* ev)
+CanvasNoteEvent::on_event(GdkEvent* ev)
{
MidiStreamView *streamview = _region.midi_stream_view();
static uint8_t drag_delta_note = 0;
diff --git a/gtk2_ardour/canvas-midi-event.h b/gtk2_ardour/canvas-midi-event.h
index acb49b8984..bb076eea23 100644
--- a/gtk2_ardour/canvas-midi-event.h
+++ b/gtk2_ardour/canvas-midi-event.h
@@ -44,14 +44,14 @@ namespace Canvas {
*
* A newer, better canvas should remove the need for all the ugly here.
*/
-class CanvasMidiEvent : public sigc::trackable {
+class CanvasNoteEvent : public sigc::trackable {
public:
CanvasMidiEvent(
MidiRegionView& region,
Item* item,
const boost::shared_ptr<ARDOUR::Note> note = boost::shared_ptr<ARDOUR::Note>());
- virtual ~CanvasMidiEvent();
+ virtual ~CanvasNoteEvent();
bool on_event(GdkEvent* ev);
diff --git a/gtk2_ardour/canvas-note.cc b/gtk2_ardour/canvas-note.cc
index bc15c3468d..30b1e3807b 100644
--- a/gtk2_ardour/canvas-note.cc
+++ b/gtk2_ardour/canvas-note.cc
@@ -80,11 +80,11 @@ CanvasNote::on_event(GdkEvent* ev)
return true;
default:
- return CanvasMidiEvent::on_event(ev);
+ return CanvasNoteEvent::on_event(ev);
}
default:
- return CanvasMidiEvent::on_event(ev);
+ return CanvasNoteEvent::on_event(ev);
}
}
diff --git a/gtk2_ardour/canvas-note.h b/gtk2_ardour/canvas-note.h
index 0a1aed8021..f404794b78 100644
--- a/gtk2_ardour/canvas-note.h
+++ b/gtk2_ardour/canvas-note.h
@@ -29,7 +29,7 @@
namespace Gnome {
namespace Canvas {
-class CanvasNote : public SimpleRect, public CanvasMidiEvent {
+class CanvasNote : public SimpleRect, public CanvasNoteEvent {
public:
CanvasNote(
MidiRegionView& region,
diff --git a/gtk2_ardour/canvas-program-change.cc b/gtk2_ardour/canvas-program-change.cc
new file mode 100644
index 0000000000..5883dd5b86
--- /dev/null
+++ b/gtk2_ardour/canvas-program-change.cc
@@ -0,0 +1,58 @@
+#include "canvas-program-change.h"
+#include <iostream>
+
+using namespace ArdourCanvas;
+using namespace std;
+
+CanvasProgramChange::CanvasProgramChange(
+ MidiRegionView& region,
+ Group& parent,
+ boost::shared_ptr<MIDI::Event> event,
+ double height,
+ double x,
+ double y)
+ : Group(parent, x, y),
+ _region(region),
+ _event(event),
+ _text(0),
+ _line(0),
+ _rect(0),
+ _widget(0)
+{
+ _text = new Text(*this);
+ ostringstream pgm(ios::ate);
+ pgm << int(event->pgm_number());
+ _text->property_text() = pgm.str();
+ _text->property_justification() = Gtk::JUSTIFY_CENTER;
+ _text->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get();
+ double flagwidth = _text->property_text_width() + 10.0;
+ double flagheight = _text->property_text_height() + 3.0;
+ _text->property_x() = flagwidth / 2.0;
+ _text->property_y() = flagheight / 2.0;
+ _text->show();
+ _line = new SimpleLine(*this, 0.0, 0.0, 0.0, height);
+ _line->property_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get();
+ _rect = new SimpleRect(*this, 0.0, 0.0, flagwidth, flagheight);
+ _rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeOutline.get();
+ _rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiProgramChangeFill.get();
+ _text->lower_to_bottom();
+ _text->raise(2);
+ assert(_widget == 0);
+ assert(_text != 0);
+ assert(_line != 0);
+ assert(_rect != 0);
+}
+
+CanvasProgramChange::~CanvasProgramChange()
+{
+ if(_line)
+ delete _line;
+ if(_rect)
+ delete _rect;
+ if(_text)
+ delete _text;
+ if(_widget)
+ delete _widget;
+}
+
+
diff --git a/gtk2_ardour/canvas-program-change.h b/gtk2_ardour/canvas-program-change.h
new file mode 100644
index 0000000000..cf99ca0715
--- /dev/null
+++ b/gtk2_ardour/canvas-program-change.h
@@ -0,0 +1,43 @@
+#ifndef CANVASPROGRAMCHANGE_H_
+#define CANVASPROGRAMCHANGE_H_
+
+#include <libgnomecanvasmm/group.h>
+#include "simplerect.h"
+#include "simpleline.h"
+#include "midi_region_view.h"
+#include <libgnomecanvasmm/text.h>
+#include <libgnomecanvasmm/widget.h>
+#include <ardour/midi_model.h>
+
+namespace Gnome
+{
+namespace Canvas
+{
+
+class CanvasProgramChange : public Group
+{
+public:
+ CanvasProgramChange(
+ MidiRegionView& region,
+ Group& parent,
+ boost::shared_ptr<MIDI::Event> event,
+ double height,
+ double x = 0.0,
+ double y = 0.0
+ );
+
+ virtual ~CanvasProgramChange();
+
+private:
+ MidiRegionView& _region;
+ boost::shared_ptr<MIDI::Event> _event;
+ Text* _text;
+ SimpleLine* _line;
+ SimpleRect* _rect;
+ Widget* _widget;
+};
+
+} // namespace Canvas
+} // namespace Gnome
+
+#endif /*CANVASPROGRAMCHANGE_H_*/
diff --git a/gtk2_ardour/canvas_vars.h b/gtk2_ardour/canvas_vars.h
index 5a29309e67..44a710703b 100644
--- a/gtk2_ardour/canvas_vars.h
+++ b/gtk2_ardour/canvas_vars.h
@@ -65,6 +65,8 @@ CANVAS_VARIABLE(canvasvar_MidiNoteOutlineMid, "midi note outline mid")
CANVAS_VARIABLE(canvasvar_MidiNoteOutlineMin, "midi note outline min")
CANVAS_VARIABLE(canvasvar_MidiNoteOutlineInactiveChannel, "midi note outline inactive channel")
CANVAS_VARIABLE(canvasvar_MidiNoteSelectedOutline, "midi note selected outline")
+CANVAS_VARIABLE(canvasvar_MidiProgramChangeFill, "midi program change fill")
+CANVAS_VARIABLE(canvasvar_MidiProgramChangeOutline, "midi program change outline")
CANVAS_VARIABLE(canvasvar_MidiSelectRectFill, "midi select rect fill")
CANVAS_VARIABLE(canvasvar_MidiSelectRectOutline, "midi select rect outline")
CANVAS_VARIABLE(canvasvar_MidiTrackBase, "midi track base")
diff --git a/gtk2_ardour/ghostregion.cc b/gtk2_ardour/ghostregion.cc
index 6384baffa0..4e06ece82f 100644
--- a/gtk2_ardour/ghostregion.cc
+++ b/gtk2_ardour/ghostregion.cc
@@ -174,7 +174,7 @@ MidiGhostRegion::~MidiGhostRegion()
//clear_events();
}
-MidiGhostRegion::Event::Event(ArdourCanvas::CanvasMidiEvent* e)
+MidiGhostRegion::Event::Event(ArdourCanvas::CanvasNoteEvent* e)
: event(e)
{
}
diff --git a/gtk2_ardour/ghostregion.h b/gtk2_ardour/ghostregion.h
index 72658f2d53..885edfde59 100644
--- a/gtk2_ardour/ghostregion.h
+++ b/gtk2_ardour/ghostregion.h
@@ -28,7 +28,7 @@
namespace Gnome {
namespace Canvas {
- class CanvasMidiEvent;
+ class CanvasNoteEvent;
class CanvasNote;
class CanvasHit;
class Diamond;
@@ -76,11 +76,11 @@ class MidiGhostRegion : public GhostRegion {
public:
class Event : public sigc::trackable {
public:
- Event(ArdourCanvas::CanvasMidiEvent*);
+ Event(ArdourCanvas::CanvasNoteEvent*);
virtual ~Event() {}
virtual void x_changed() = 0;
- ArdourCanvas::CanvasMidiEvent* event;
+ ArdourCanvas::CanvasNoteEvent* event;
};
class Note : public Event {
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 858f59af69..0d8d7984a2 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -41,6 +41,7 @@
#include "simpleline.h"
#include "canvas-hit.h"
#include "canvas-note.h"
+#include "canvas-program-change.h"
#include "public_editor.h"
#include "ghostregion.h"
#include "midi_time_axis.h"
@@ -474,6 +475,16 @@ MidiRegionView::redisplay_model()
add_note(_model->note_at(i));
}
+ MidiModel::PgmChanges& pgm_changes = _model->pgm_changes();
+ /*
+ for (MidiModel::PgmChanges::const_iterator i = pgm_changes.begin();
+ i != pgm_changes.end();
+ ++i) {
+ add_pgm_change()
+ }
+ */
+ for_each(pgm_changes.begin(), pgm_changes.end(), sigc::mem_fun(this, &MidiRegionView::add_pgm_change));
+
end_write();
/*for (Automatable::Controls::const_iterator i = _model->controls().begin();
@@ -793,6 +804,27 @@ MidiRegionView::add_note(const boost::shared_ptr<Note> note)
}
void
+MidiRegionView::add_pgm_change(boost::shared_ptr<MIDI::Event> event)
+{
+ assert(event->time() >= 0);
+
+ // dont display notes beyond the region bounds
+ if(
+ event->time() - _region->start() >= _region->length() ||
+ event->time() < _region->start()
+ ) {
+ return;
+ }
+
+ ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
+ const double x = trackview.editor.frame_to_pixel((nframes_t)event->time() - _region->start());
+
+ double height = midi_stream_view()->contents_height();
+ new CanvasProgramChange(*this, *group, event, height, x, 1.0);
+ //TODO : keep track of pgm changes
+}
+
+void
MidiRegionView::delete_selection()
{
assert(_delta_command);
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index bc5639476f..f380704d33 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -37,6 +37,7 @@
#include "canvas.h"
#include "canvas-note.h"
#include "canvas-midi-event.h"
+#include "canvas-program-change.h"
namespace ARDOUR {
class MidiRegion;
@@ -80,6 +81,8 @@ class MidiRegionView : public RegionView
void add_note(const boost::shared_ptr<ARDOUR::Note> note);
void resolve_note(uint8_t note_num, double end_time);
+
+ void add_pgm_change(boost::shared_ptr<MIDI::Event> event);
void begin_write();
void end_write();
@@ -101,7 +104,7 @@ class MidiRegionView : public RegionView
_delta_command->add(note);
}
- void command_remove_note(ArdourCanvas::CanvasMidiEvent* ev) {
+ void command_remove_note(ArdourCanvas::CanvasNoteEvent* ev) {
if (_delta_command && ev->note()) {
_selection.erase(ev);
_delta_command->remove(ev->note());
@@ -123,15 +126,15 @@ class MidiRegionView : public RegionView
midi_view()->midi_track()->diskstream()->playlist_modified();
}
- void note_entered(ArdourCanvas::CanvasMidiEvent* ev);
- void unique_select(ArdourCanvas::CanvasMidiEvent* ev);
- void note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add);
- void note_deselected(ArdourCanvas::CanvasMidiEvent* ev, bool add);
+ void note_entered(ArdourCanvas::CanvasNoteEvent* ev);
+ void unique_select(ArdourCanvas::CanvasNoteEvent* ev);
+ void note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add);
+ void note_deselected(ArdourCanvas::CanvasNoteEvent* ev, bool add);
void delete_selection();
size_t selection_size() { return _selection.size(); }
void move_selection(double dx, double dy);
- void note_dropped(ArdourCanvas::CanvasMidiEvent* ev, double dt, uint8_t dnote);
+ void note_dropped(ArdourCanvas::CanvasNoteEvent* ev, double dt, uint8_t dnote);
/**
* This function is needed to subtract the region start in pixels
@@ -243,14 +246,14 @@ class MidiRegionView : public RegionView
uint16_t last_channel_selection;
void midi_channel_selection_changed(uint16_t selection);
- void clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev);
+ void clear_selection_except(ArdourCanvas::CanvasNoteEvent* ev);
void clear_selection() { clear_selection_except(NULL); }
void update_drag_selection(double last_x, double x, double last_y, double y);
double _default_note_length;
boost::shared_ptr<ARDOUR::MidiModel> _model;
- std::vector<ArdourCanvas::CanvasMidiEvent*> _events;
+ std::vector<ArdourCanvas::CanvasNoteEvent*> _events;
ArdourCanvas::CanvasNote** _active_notes;
ArdourCanvas::Group* _note_group;
ARDOUR::MidiModel::DeltaCommand* _delta_command;
@@ -259,7 +262,7 @@ class MidiRegionView : public RegionView
int _pressed_button;
/// currently selected CanvasMidiEvents
- typedef std::set<ArdourCanvas::CanvasMidiEvent*> Selection;
+ typedef std::set<ArdourCanvas::CanvasNoteEvent*> Selection;
Selection _selection;
/**
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index 4c811604ee..d2e24bafb7 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -87,6 +87,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
}
}
+ /* TODO: Disabled for stablility reasons
MidiControlIterator earliest_control(boost::shared_ptr<AutomationList>(), DBL_MAX, 0.0);
_control_iters.reserve(model.controls().size());
@@ -98,8 +99,8 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
double x, y;
bool ret = i->second->list()->rt_safe_earliest_event_unlocked(t, DBL_MAX, x, y);
if (!ret) {
- /*cerr << "MIDI Iterator: CC " << i->first.id() << " (size " << i->second->list()->size()
- << ") has no events past " << t << endl;*/
+ //cerr << "MIDI Iterator: CC " << i->first.id() << " (size " << i->second->list()->size()
+ // << ") has no events past " << t << endl;
continue;
}
@@ -118,6 +119,8 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
--_control_iter;
}
}
+ */
+
if (_note_iter != model.notes().end()) {
_event = MIDI::Event((*_note_iter)->on_event(), false);
@@ -126,10 +129,12 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
++_note_iter;
}
+ /** TODO: Disabled for stability reasons
if (earliest_control.automation_list && earliest_control.x < _event.time())
model.control_to_midi_event(_event, earliest_control);
else
_control_iter = _control_iters.end();
+ */
_pgm_change_iter = model.pgm_changes().end();
// find first program change which begins after t
@@ -556,12 +561,13 @@ MidiModel::append_cc_unlocked(uint8_t chan, double time, uint8_t number, uint8_t
assert(chan < 16);
assert(_writing);
+ /** TODO: disabled for now until debugged....
_edited = true;
Parameter param(MidiCCAutomation, number, chan);
-
boost::shared_ptr<AutomationControl> control = Automatable::control(param, true);
control->list()->fast_simple_add(time, (double)value);
+ */
}
void
@@ -577,11 +583,6 @@ MidiModel::append_pgm_change_unlocked(uint8_t chan, double time, uint8_t number)
event_ptr->set_channel(chan);
event_ptr->set_pgm_number(number);
_pgm_changes.push_back(event_ptr);
- cerr << "MidiModel::append_pgm_change_unlocked: appended pgm change" << endl;
- for(PgmChanges::iterator i = _pgm_changes.begin(); i != _pgm_changes.end(); ++i) {
- cerr << "_pgm_changes contents: channel " << int((*i)->channel()) << dec << " time: " << int((*i)->time()) << hex << " program number: " << int(int((*i)->pgm_number())) <<endl;
- }
- //<< int(_pgm_changes.) << " time: " << time << " program number: " << int(number) <<endl;
}
void