mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
Basic canvas note event handling framework.
Note dragging (non-functional). git-svn-id: svn://localhost/ardour2/trunk@2187 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
633d9131af
commit
2cbaa2751c
10 changed files with 398 additions and 89 deletions
|
|
@ -109,6 +109,7 @@ canvas-simplerect.c
|
||||||
simplerect.cc
|
simplerect.cc
|
||||||
canvas-waveview.c
|
canvas-waveview.c
|
||||||
diamond.cc
|
diamond.cc
|
||||||
|
canvas-midi-event.cc
|
||||||
crossfade_edit.cc
|
crossfade_edit.cc
|
||||||
crossfade_view.cc
|
crossfade_view.cc
|
||||||
curvetest.cc
|
curvetest.cc
|
||||||
|
|
|
||||||
41
gtk2_ardour/canvas-hit.h
Normal file
41
gtk2_ardour/canvas-hit.h
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2007 Paul Davis
|
||||||
|
Author: Dave Robillard
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __gtk_ardour_canvas_hit_h__
|
||||||
|
#define __gtk_ardour_canvas_hit_h__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "simplerect.h"
|
||||||
|
#include "diamond.h"
|
||||||
|
|
||||||
|
namespace Gnome {
|
||||||
|
namespace Canvas {
|
||||||
|
|
||||||
|
class CanvasHit : public Diamond, public CanvasMidiEvent {
|
||||||
|
public:
|
||||||
|
CanvasHit(MidiRegionView& region, Group& group, double size)
|
||||||
|
: Diamond(group, size), CanvasMidiEvent(region, this) {}
|
||||||
|
|
||||||
|
bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Gnome
|
||||||
|
} // namespace Canvas
|
||||||
|
|
||||||
|
#endif /* __gtk_ardour_canvas_hit_h__ */
|
||||||
122
gtk2_ardour/canvas-midi-event.cc
Normal file
122
gtk2_ardour/canvas-midi-event.cc
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2007 Paul Davis
|
||||||
|
Author: Dave Robillard
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "canvas-midi-event.h"
|
||||||
|
#include "midi_region_view.h"
|
||||||
|
#include "public_editor.h"
|
||||||
|
#include "editing_syms.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace Gnome {
|
||||||
|
namespace Canvas {
|
||||||
|
|
||||||
|
|
||||||
|
CanvasMidiEvent::CanvasMidiEvent(MidiRegionView& region, Item* item)
|
||||||
|
: _region(region)
|
||||||
|
, _item(item)
|
||||||
|
, _state(None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
|
{
|
||||||
|
static double last_x, last_y;
|
||||||
|
double event_x, event_y;
|
||||||
|
|
||||||
|
if (_region.get_time_axis_view().editor.current_mouse_mode() != Editing::MouseNote)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (ev->type) {
|
||||||
|
/*case GDK_ENTER_NOTIFY:
|
||||||
|
cerr << "ENTERED: " << ev->crossing.state << endl;
|
||||||
|
if ( (ev->crossing.state & GDK_BUTTON2_MASK) ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case GDK_KEY_PRESS:
|
||||||
|
cerr << "EVENT KEY PRESS\n"; // doesn't work :/
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_BUTTON_PRESS:
|
||||||
|
_state = Pressed;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case GDK_MOTION_NOTIFY:
|
||||||
|
event_x = ev->motion.x;
|
||||||
|
event_y = ev->motion.y;
|
||||||
|
_item->property_parent().get_value()->w2i(event_x, event_y);
|
||||||
|
|
||||||
|
switch (_state) {
|
||||||
|
case Pressed:
|
||||||
|
_item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
||||||
|
Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
|
||||||
|
_state = Dragging;
|
||||||
|
last_x = event_x;
|
||||||
|
last_y = event_y;
|
||||||
|
return true;
|
||||||
|
case Dragging:
|
||||||
|
if (ev->motion.is_hint) {
|
||||||
|
int t_x;
|
||||||
|
int t_y;
|
||||||
|
GdkModifierType state;
|
||||||
|
gdk_window_get_pointer(ev->motion.window, &t_x, &t_y, &state);
|
||||||
|
event_x = t_x;
|
||||||
|
event_y = t_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
_item->move(event_x - last_x, event_y - last_y);
|
||||||
|
|
||||||
|
last_x = event_x;
|
||||||
|
last_y = event_y;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_BUTTON_RELEASE:
|
||||||
|
switch (_state) {
|
||||||
|
case Pressed: // Clicked
|
||||||
|
_state = None;
|
||||||
|
return true;
|
||||||
|
case Dragging: // Dropped
|
||||||
|
_item->ungrab(ev->button.time);
|
||||||
|
_state = None;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Canvas
|
||||||
|
} // namespace Gnome
|
||||||
|
|
||||||
59
gtk2_ardour/canvas-midi-event.h
Normal file
59
gtk2_ardour/canvas-midi-event.h
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2007 Paul Davis
|
||||||
|
Author: Dave Robillard
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __gtk_ardour_canvas_midi_event_h__
|
||||||
|
#define __gtk_ardour_canvas_midi_event_h__
|
||||||
|
|
||||||
|
#include "simplerect.h"
|
||||||
|
|
||||||
|
class Editor;
|
||||||
|
class MidiRegionView;
|
||||||
|
|
||||||
|
namespace Gnome {
|
||||||
|
namespace Canvas {
|
||||||
|
|
||||||
|
|
||||||
|
/** This manages all the event handling for any MIDI event on the canvas.
|
||||||
|
*
|
||||||
|
* This is not actually a canvas item itself to avoid the dreaded diamond,
|
||||||
|
* since various types of canvas items (Note (rect), Hit (diamond), etc)
|
||||||
|
* need to share this functionality but can't share an ancestor.
|
||||||
|
*
|
||||||
|
* Note: Because of this, derived classes need to manually bounce events to
|
||||||
|
* on_event, it won't happen automatically.
|
||||||
|
*/
|
||||||
|
class CanvasMidiEvent {
|
||||||
|
public:
|
||||||
|
CanvasMidiEvent(MidiRegionView& region, Item* item);
|
||||||
|
virtual ~CanvasMidiEvent() {}
|
||||||
|
|
||||||
|
virtual bool on_event(GdkEvent* ev);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum State { None, Pressed, Dragging };
|
||||||
|
|
||||||
|
MidiRegionView& _region;
|
||||||
|
Item* const _item;
|
||||||
|
State _state;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Gnome
|
||||||
|
} // namespace Canvas
|
||||||
|
|
||||||
|
#endif /* __gtk_ardour_canvas_midi_event_h__ */
|
||||||
43
gtk2_ardour/canvas-note.h
Normal file
43
gtk2_ardour/canvas-note.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2007 Paul Davis
|
||||||
|
Author: Dave Robillard
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __gtk_ardour_canvas_note_h__
|
||||||
|
#define __gtk_ardour_canvas_note_h__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "simplerect.h"
|
||||||
|
#include "canvas-midi-event.h"
|
||||||
|
|
||||||
|
namespace Gnome {
|
||||||
|
namespace Canvas {
|
||||||
|
|
||||||
|
class CanvasNote : public SimpleRect, public CanvasMidiEvent {
|
||||||
|
public:
|
||||||
|
CanvasNote(MidiRegionView& region, Group& group)
|
||||||
|
: SimpleRect(group), CanvasMidiEvent(region, this)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Gnome
|
||||||
|
} // namespace Canvas
|
||||||
|
|
||||||
|
#endif /* __gtk_ardour_canvas_note_h__ */
|
||||||
|
|
@ -21,14 +21,15 @@
|
||||||
#define __ardour_diamond_h__
|
#define __ardour_diamond_h__
|
||||||
|
|
||||||
#include <libgnomecanvasmm/polygon.h>
|
#include <libgnomecanvasmm/polygon.h>
|
||||||
|
#include "canvas-midi-event.h"
|
||||||
|
|
||||||
namespace Gnome {
|
namespace Gnome {
|
||||||
namespace Canvas {
|
namespace Canvas {
|
||||||
|
|
||||||
|
|
||||||
class Diamond : public Gnome::Canvas::Polygon {
|
class Diamond : public Polygon {
|
||||||
public:
|
public:
|
||||||
Diamond(Gnome::Canvas::Group& group, double height);
|
Diamond(Group& group, double height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#include "midi_time_axis.h"
|
#include "midi_time_axis.h"
|
||||||
#include "simplerect.h"
|
#include "simplerect.h"
|
||||||
#include "simpleline.h"
|
#include "simpleline.h"
|
||||||
#include "diamond.h"
|
#include "canvas-hit.h"
|
||||||
#include "public_editor.h"
|
#include "public_editor.h"
|
||||||
#include "ghostregion.h"
|
#include "ghostregion.h"
|
||||||
#include "midi_time_axis.h"
|
#include "midi_time_axis.h"
|
||||||
|
|
@ -108,56 +108,124 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
|
||||||
bool
|
bool
|
||||||
MidiRegionView::canvas_event(GdkEvent* ev)
|
MidiRegionView::canvas_event(GdkEvent* ev)
|
||||||
{
|
{
|
||||||
if (trackview.editor.current_mouse_mode() == MouseNote) {
|
enum State { None, Pressed, Dragging };
|
||||||
if (ev->type == GDK_BUTTON_PRESS) {
|
static State _state;
|
||||||
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
|
|
||||||
MidiStreamView* const view = mtv->midi_view();
|
|
||||||
|
|
||||||
const uint8_t note_range = view->highest_note() - view->lowest_note() + 1;
|
|
||||||
const double footer_height = name_highlight->property_y2() - name_highlight->property_y1();
|
|
||||||
const double roll_height = trackview.height - footer_height;
|
|
||||||
|
|
||||||
double x = ev->button.x;
|
|
||||||
double y = ev->button.y;
|
|
||||||
get_canvas_group()->w2i(x, y);
|
|
||||||
|
|
||||||
double note = floor((roll_height - y) / roll_height * (double)note_range) + view->lowest_note();
|
static double last_x, last_y;
|
||||||
assert(note >= 0.0);
|
double event_x, event_y;
|
||||||
assert(note <= 127.0);
|
|
||||||
|
|
||||||
const nframes_t stamp = trackview.editor.pixel_to_frame (x);
|
|
||||||
assert(stamp >= 0);
|
|
||||||
//assert(stamp <= _region->length());
|
|
||||||
|
|
||||||
const Meter& m = trackview.session().tempo_map().meter_at(stamp);
|
|
||||||
const Tempo& t = trackview.session().tempo_map().tempo_at(stamp);
|
|
||||||
double dur = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar();
|
|
||||||
|
|
||||||
MidiModel* model = midi_region()->midi_source(0)->model();
|
|
||||||
|
|
||||||
// Add a 1 beat long note (for now)
|
|
||||||
const MidiModel::Note new_note(stamp, dur, (uint8_t)note, 0x40);
|
|
||||||
|
|
||||||
model->begin_command();
|
|
||||||
model->add_note(new_note);
|
|
||||||
model->finish_command();
|
|
||||||
|
|
||||||
view->update_bounds(new_note.note());
|
|
||||||
|
|
||||||
add_note(new_note);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (trackview.editor.current_mouse_mode() != MouseNote)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (ev->type) {
|
||||||
|
case GDK_BUTTON_PRESS:
|
||||||
|
//group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, ev->button.time);
|
||||||
|
// This should happen on release...
|
||||||
|
if (ev->button.button == 1)
|
||||||
|
create_note_at(ev->button.x, ev->button.y);
|
||||||
|
|
||||||
|
_state = Pressed;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case GDK_MOTION_NOTIFY:
|
||||||
|
cerr << "MOTION\n";
|
||||||
|
event_x = ev->motion.x;
|
||||||
|
event_y = ev->motion.y;
|
||||||
|
group->w2i(event_x, event_y);
|
||||||
|
|
||||||
|
switch (_state) {
|
||||||
|
case Pressed:
|
||||||
|
cerr << "SELECT DRAG START\n";
|
||||||
|
//group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
||||||
|
// Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
|
||||||
|
_state = Dragging;
|
||||||
|
last_x = event_x;
|
||||||
|
last_y = event_y;
|
||||||
|
return true;
|
||||||
|
case Dragging:
|
||||||
|
if (ev->motion.is_hint) {
|
||||||
|
int t_x;
|
||||||
|
int t_y;
|
||||||
|
GdkModifierType state;
|
||||||
|
gdk_window_get_pointer(ev->motion.window, &t_x, &t_y, &state);
|
||||||
|
event_x = t_x;
|
||||||
|
event_y = t_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "SELECT DRAG" << endl;
|
||||||
|
//move(event_x - last_x, event_y - last_y);
|
||||||
|
|
||||||
|
last_x = event_x;
|
||||||
|
last_y = event_y;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_BUTTON_RELEASE:
|
||||||
|
cerr << "RELEASE\n";
|
||||||
|
//group->ungrab(ev->button.time);
|
||||||
|
switch (_state) {
|
||||||
|
case Pressed:
|
||||||
|
cerr << "CLICK\n";
|
||||||
|
//create_note_at(ev->button.x, ev->button.y);
|
||||||
|
_state = None;
|
||||||
|
return true;
|
||||||
|
case Dragging:
|
||||||
|
cerr << "SELECT RECT DONE\n";
|
||||||
|
_state = None;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
/** Add a note to the model, and the view, at a canvas (click) coordinate */
|
||||||
MidiRegionView::note_canvas_event(GdkEvent* ev)
|
void
|
||||||
|
MidiRegionView::create_note_at(double x, double y)
|
||||||
{
|
{
|
||||||
cerr << "NOTE CANVAS EVENT" << endl;
|
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
|
||||||
|
MidiStreamView* const view = mtv->midi_view();
|
||||||
|
|
||||||
return true;
|
const uint8_t note_range = view->highest_note() - view->lowest_note() + 1;
|
||||||
|
const double footer_height = name_highlight->property_y2() - name_highlight->property_y1();
|
||||||
|
const double roll_height = trackview.height - footer_height;
|
||||||
|
|
||||||
|
get_canvas_group()->w2i(x, y);
|
||||||
|
|
||||||
|
double note = floor((roll_height - y) / roll_height * (double)note_range) + view->lowest_note();
|
||||||
|
assert(note >= 0.0);
|
||||||
|
assert(note <= 127.0);
|
||||||
|
|
||||||
|
const nframes_t stamp = trackview.editor.pixel_to_frame (x);
|
||||||
|
assert(stamp >= 0);
|
||||||
|
//assert(stamp <= _region->length());
|
||||||
|
|
||||||
|
const Meter& m = trackview.session().tempo_map().meter_at(stamp);
|
||||||
|
const Tempo& t = trackview.session().tempo_map().tempo_at(stamp);
|
||||||
|
double dur = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar();
|
||||||
|
|
||||||
|
MidiModel* model = midi_region()->midi_source(0)->model();
|
||||||
|
|
||||||
|
// Add a 1 beat long note (for now)
|
||||||
|
const MidiModel::Note new_note(stamp, dur, (uint8_t)note, 0x40);
|
||||||
|
|
||||||
|
model->begin_command();
|
||||||
|
model->add_note(new_note);
|
||||||
|
model->finish_command();
|
||||||
|
|
||||||
|
view->update_bounds(new_note.note());
|
||||||
|
|
||||||
|
add_note(new_note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -279,7 +347,7 @@ MidiRegionView::add_ghost (AutomationTimeAxisView& atv)
|
||||||
void
|
void
|
||||||
MidiRegionView::begin_write()
|
MidiRegionView::begin_write()
|
||||||
{
|
{
|
||||||
_active_notes = new ArdourCanvas::SimpleRect*[128];
|
_active_notes = new CanvasNote*[128];
|
||||||
for (unsigned i=0; i < 128; ++i)
|
for (unsigned i=0; i < 128; ++i)
|
||||||
_active_notes[i] = NULL;
|
_active_notes[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +391,7 @@ MidiRegionView::add_event (const MidiEvent& ev)
|
||||||
const double y1 = trackview.height - (pixel_range * (note - view->lowest_note() + 1))
|
const double y1 = trackview.height - (pixel_range * (note - view->lowest_note() + 1))
|
||||||
- footer_height - 3.0;
|
- footer_height - 3.0;
|
||||||
|
|
||||||
ArdourCanvas::SimpleRect * ev_rect = new Gnome::Canvas::SimpleRect(*group);
|
CanvasNote* ev_rect = new CanvasNote(*this, *group);
|
||||||
ev_rect->property_x1() = trackview.editor.frame_to_pixel (
|
ev_rect->property_x1() = trackview.editor.frame_to_pixel (
|
||||||
(nframes_t)ev.time);
|
(nframes_t)ev.time);
|
||||||
ev_rect->property_y1() = y1;
|
ev_rect->property_y1() = y1;
|
||||||
|
|
@ -335,8 +403,6 @@ MidiRegionView::add_event (const MidiEvent& ev)
|
||||||
ev_rect->property_outline_what() = (guint32) (0x1 & 0x4 & 0x8);
|
ev_rect->property_outline_what() = (guint32) (0x1 & 0x4 & 0x8);
|
||||||
ev_rect->property_fill_color_rgba() = 0xFFFFFF66;
|
ev_rect->property_fill_color_rgba() = 0xFFFFFF66;
|
||||||
|
|
||||||
ev_rect->signal_event().connect(sigc::mem_fun(this, &MidiRegionView::note_canvas_event));
|
|
||||||
|
|
||||||
ev_rect->raise_to_top();
|
ev_rect->raise_to_top();
|
||||||
|
|
||||||
_events.push_back(ev_rect);
|
_events.push_back(ev_rect);
|
||||||
|
|
@ -358,14 +424,12 @@ MidiRegionView::add_event (const MidiEvent& ev)
|
||||||
const double y = trackview.height - (pixel_range * (note - view->lowest_note() + 1))
|
const double y = trackview.height - (pixel_range * (note - view->lowest_note() + 1))
|
||||||
- footer_height - 3.0;
|
- footer_height - 3.0;
|
||||||
|
|
||||||
Diamond* ev_diamond = new Diamond(*group, std::min(pixel_range, 5.0));
|
CanvasHit* ev_diamond = new CanvasHit(*this, *group, std::min(pixel_range, 5.0));
|
||||||
ev_diamond->move(x, y);
|
ev_diamond->move(x, y);
|
||||||
ev_diamond->show();
|
ev_diamond->show();
|
||||||
ev_diamond->property_outline_color_rgba() = 0xFFFFFFDD;
|
ev_diamond->property_outline_color_rgba() = 0xFFFFFFDD;
|
||||||
ev_diamond->property_fill_color_rgba() = 0xFFFFFF66;
|
ev_diamond->property_fill_color_rgba() = 0xFFFFFF66;
|
||||||
|
|
||||||
ev_diamond->signal_event().connect(sigc::mem_fun(this, &MidiRegionView::note_canvas_event));
|
|
||||||
|
|
||||||
_events.push_back(ev_diamond);
|
_events.push_back(ev_diamond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -385,7 +449,7 @@ MidiRegionView::extend_active_notes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Add a MIDI note (with duration).
|
/** Add a MIDI note to the view (with duration).
|
||||||
*
|
*
|
||||||
* This does no 'realtime' note resolution, notes from a MidiModel have a
|
* This does no 'realtime' note resolution, notes from a MidiModel have a
|
||||||
* duration so they can be drawn in full immediately.
|
* duration so they can be drawn in full immediately.
|
||||||
|
|
@ -419,7 +483,7 @@ MidiRegionView::add_note (const MidiModel::Note& note)
|
||||||
const double y1 = trackview.height - (pixel_range * (note.note() - view->lowest_note() + 1))
|
const double y1 = trackview.height - (pixel_range * (note.note() - view->lowest_note() + 1))
|
||||||
- footer_height - 3.0;
|
- footer_height - 3.0;
|
||||||
|
|
||||||
ArdourCanvas::SimpleRect * ev_rect = new Gnome::Canvas::SimpleRect(*group);
|
ArdourCanvas::SimpleRect * ev_rect = new CanvasNote(*this, *group);
|
||||||
ev_rect->property_x1() = trackview.editor.frame_to_pixel((nframes_t)note.time());
|
ev_rect->property_x1() = trackview.editor.frame_to_pixel((nframes_t)note.time());
|
||||||
ev_rect->property_y1() = y1;
|
ev_rect->property_y1() = y1;
|
||||||
ev_rect->property_x2() = trackview.editor.frame_to_pixel((nframes_t)(note.end_time()));
|
ev_rect->property_x2() = trackview.editor.frame_to_pixel((nframes_t)(note.end_time()));
|
||||||
|
|
@ -437,7 +501,7 @@ MidiRegionView::add_note (const MidiModel::Note& note)
|
||||||
const double y = trackview.height - (pixel_range * (note.note() - view->lowest_note() + 1))
|
const double y = trackview.height - (pixel_range * (note.note() - view->lowest_note() + 1))
|
||||||
- footer_height - 3.0;
|
- footer_height - 3.0;
|
||||||
|
|
||||||
Diamond* ev_diamond = new Diamond(*group, std::min(pixel_range, 5.0));
|
CanvasHit* ev_diamond = new CanvasHit(*this, *group, std::min(pixel_range, 5.0));
|
||||||
ev_diamond->move(x, y);
|
ev_diamond->move(x, y);
|
||||||
ev_diamond->show();
|
ev_diamond->show();
|
||||||
ev_diamond->property_fill_color_rgba() = fill;
|
ev_diamond->property_fill_color_rgba() = fill;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include "automation_line.h"
|
#include "automation_line.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
|
#include "canvas-note.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class MidiRegion;
|
class MidiRegion;
|
||||||
|
|
@ -70,6 +71,8 @@ class MidiRegionView : public RegionView
|
||||||
void end_write();
|
void end_write();
|
||||||
void extend_active_notes();
|
void extend_active_notes();
|
||||||
|
|
||||||
|
void create_note_at(double x, double y);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* this constructor allows derived types
|
/* this constructor allows derived types
|
||||||
|
|
@ -101,7 +104,7 @@ class MidiRegionView : public RegionView
|
||||||
bool note_canvas_event(GdkEvent* ev);
|
bool note_canvas_event(GdkEvent* ev);
|
||||||
|
|
||||||
std::vector<ArdourCanvas::Item*> _events;
|
std::vector<ArdourCanvas::Item*> _events;
|
||||||
ArdourCanvas::SimpleRect** _active_notes;
|
ArdourCanvas::CanvasNote** _active_notes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __gtk_ardour_midi_region_view_h__ */
|
#endif /* __gtk_ardour_midi_region_view_h__ */
|
||||||
|
|
|
||||||
|
|
@ -827,18 +827,6 @@ MidiDiskstream::do_refill ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if there are 2+ chunks of disk i/o possible for
|
|
||||||
this track, let the caller know so that it can arrange
|
|
||||||
for us to be called again, ASAP.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// FIXME: using disk_io_chunk_frames as an event count, not good
|
|
||||||
// count vs duration semantic differences are nonexistant for audio,
|
|
||||||
// which makes translating for MIDI code confusing...
|
|
||||||
if (_playback_buf->write_space() >= (_slaved?3:2) * disk_io_chunk_frames) {
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we're running close to normal speed and there isn't enough
|
/* if we're running close to normal speed and there isn't enough
|
||||||
space to do disk_io_chunk_frames of I/O, then don't bother.
|
space to do disk_io_chunk_frames of I/O, then don't bother.
|
||||||
|
|
||||||
|
|
@ -847,7 +835,7 @@ MidiDiskstream::do_refill ()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((write_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
|
if ((write_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
|
||||||
cerr << "No refill 1\n";
|
//cerr << "No refill 1\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -857,12 +845,12 @@ MidiDiskstream::do_refill ()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_slaved && write_space < (_playback_buf->capacity() / 2)) {
|
if (_slaved && write_space < (_playback_buf->capacity() / 2)) {
|
||||||
cerr << "No refill 2\n";
|
//cerr << "No refill 2\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reversed) {
|
if (reversed) {
|
||||||
cerr << "No refill 3 (reverse)\n";
|
//cerr << "No refill 3 (reverse)\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -874,26 +862,10 @@ MidiDiskstream::do_refill ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
// At this point we...
|
||||||
// or this
|
|
||||||
if (file_frame > max_frames - total_space) {
|
|
||||||
|
|
||||||
/* to close to the end: read what we can, and zero fill the rest */
|
|
||||||
|
|
||||||
zero_fill = total_space - (max_frames - file_frame);
|
|
||||||
total_space = max_frames - file_frame;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
zero_fill = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// At this point we:
|
|
||||||
assert(_playback_buf->write_space() > 0); // ... have something to write to, and
|
assert(_playback_buf->write_space() > 0); // ... have something to write to, and
|
||||||
assert(file_frame <= max_frames); // ... something to write
|
assert(file_frame <= max_frames); // ... something to write
|
||||||
|
|
||||||
// So (read it, then) write it:
|
|
||||||
|
|
||||||
nframes_t file_frame_tmp = file_frame;
|
nframes_t file_frame_tmp = file_frame;
|
||||||
nframes_t to_read = min(disk_io_chunk_frames, (max_frames - file_frame));
|
nframes_t to_read = min(disk_io_chunk_frames, (max_frames - file_frame));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ MidiModel::read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframe
|
||||||
{
|
{
|
||||||
size_t read_events = 0;
|
size_t read_events = 0;
|
||||||
|
|
||||||
//cerr << "MM READ " << start << " .. " << nframes << endl;
|
cerr << "MM READ @ " << start << " + " << nframes << endl;
|
||||||
|
|
||||||
/* FIXME: cache last lookup value to avoid the search */
|
/* FIXME: cache last lookup value to avoid the search */
|
||||||
|
|
||||||
|
|
@ -140,6 +140,9 @@ MidiModel::read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (read_events > 0)
|
||||||
|
cerr << "MM READ " << read_events << " EVENTS" << endl;
|
||||||
|
|
||||||
return read_events;
|
return read_events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue