Deep "automation regions" support.

Fix zoom/height/etc changing for automation region views.
Broke smooth automation region dragging (make omelette, break eggs, etc).


git-svn-id: svn://localhost/ardour2/trunk@2424 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-09-06 02:30:39 +00:00
parent 7423ad46a7
commit c190aca4a0
30 changed files with 516 additions and 93 deletions

View File

@ -99,6 +99,7 @@ audio_region_editor.cc
control_point.cc
automation_line.cc
automation_time_axis.cc
automation_streamview.cc
automation_controller.cc
automation_region_view.cc
midi_port_dialog.cc

View File

@ -1438,7 +1438,7 @@ ARDOUR_UI::engine_running ()
ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
Glib::RefPtr<Action> action;
char* action_name = 0;
const char* action_name = 0;
switch (engine->frames_per_cycle()) {
case 32:
@ -2788,7 +2788,7 @@ ARDOUR_UI::TransportControllable::set_value (float val)
return;
}
char *action = 0;
const char *action = 0;
switch (type) {
case Roll:

View File

@ -576,7 +576,7 @@ void
ARDOUR_UI::set_jack_buffer_size (nframes_t nframes)
{
Glib::RefPtr<Action> action;
char* action_name = 0;
const char* action_name = 0;
switch (nframes) {
case 32:

View File

@ -310,6 +310,7 @@ AudioTimeAxisView::create_automation_child (Parameter param, bool show)
_route, _route, c,
editor,
*this,
false,
parent_canvas,
_route->describe_parameter(param)));
@ -343,6 +344,7 @@ AudioTimeAxisView::update_pans (bool show)
_route, _route/*FIXME*/, pan_control,
editor,
*this,
false,
parent_canvas,
_route->describe_parameter(pan_control->parameter())));
add_automation_child(Parameter(PanAutomation, i), pan_track, show);

View File

@ -17,7 +17,11 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <pbd/memento_command.h>
#include "automation_region_view.h"
#include "public_editor.h"
#include "i18n.h"
AutomationRegionView::AutomationRegionView(ArdourCanvas::Group* parent,
AutomationTimeAxisView& time_axis,
@ -32,20 +36,73 @@ AutomationRegionView::AutomationRegionView(ArdourCanvas::Group*
_line.show();
_line.show_all_control_points();
group->raise_to_top ();
//group->raise_to_top ();
group->signal_event().connect (mem_fun (this, &AutomationRegionView::canvas_event), false);
}
void
AutomationRegionView::init (Gdk::Color& basic_color, bool wfd)
{
_enable_display = false;
RegionView::init(basic_color, false);
compute_colors (basic_color);
reset_width_dependent_items ((double) _region->length() / samples_per_unit);
set_y_position_and_height (0, trackview.height);
_region->StateChanged.connect (mem_fun(*this, &AutomationRegionView::region_changed));
set_colors ();
_enable_display = true;
}
bool
AutomationRegionView::canvas_event(GdkEvent* ev)
{
cerr << "AUTOMATION EVENT" << endl;
if (ev->type == GDK_BUTTON_RELEASE) {
const nframes_t when = trackview.editor.pixel_to_frame((nframes_t)ev->button.x)
- _region->position();
add_automation_event(ev, when, ev->button.y);
}
return false;
}
void
AutomationRegionView::add_automation_event (GdkEvent* event, nframes_t when, double y)
{
double x = 0;
AutomationTimeAxisView* const view = automation_view();
view->canvas_display->w2i (x, y);
/* compute vertical fractional position */
const double height = trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2;
y = 1.0 - (y / height);
/* map using line */
_line.view_to_model_y (y);
view->session().begin_reversible_command (_("add automation event"));
XMLNode& before = _line.the_list()->get_state();
_line.the_list()->add (when, y);
XMLNode& after = _line.the_list()->get_state();
view->session().commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(
*_line.the_list(), &before, &after));
view->session().set_dirty ();
}
void
AutomationRegionView::set_y_position_and_height (double y, double h)
@ -55,10 +112,31 @@ AutomationRegionView::set_y_position_and_height (double y, double h)
_line.set_y_position_and_height ((uint32_t)y, (uint32_t) rint (h - NAME_HIGHLIGHT_SIZE));
}
bool
AutomationRegionView::set_position (nframes_t pos, void* src, double* ignored)
{
// Do nothing, region parent will move us
//return false;
return RegionView::set_position(pos, src, ignored); // FIXME: eventually...
}
void
AutomationRegionView::reset_width_dependent_items (double pixel_width)
{
RegionView::reset_width_dependent_items(pixel_width);
_line.reset();
}
void
AutomationRegionView::region_resized (ARDOUR::Change what_changed)
{
// Do nothing, parent will move us
RegionView::region_resized(what_changed);
_line.reset();
}

View File

@ -47,13 +47,24 @@ public:
~AutomationRegionView() {}
void init (Gdk::Color& basic_color, bool wfd);
inline AutomationTimeAxisView* automation_view() const
{ return dynamic_cast<AutomationTimeAxisView*>(&trackview); }
AutomationLine& line() { return _line; }
// We are a ghost. Meta ghosts? Crazy talk.
virtual GhostRegion* add_ghost(AutomationTimeAxisView&) { return NULL; }
void reset_width_dependent_items(double pixel_width);
protected:
bool set_position(nframes_t pos, void* src, double* ignored);
void set_y_position_and_height(double y, double h);
void region_resized(ARDOUR::Change what_changed);
bool canvas_event(GdkEvent* ev);
void add_automation_event (GdkEvent* event, nframes_t when, double y);
void entered();
void exited();

View File

@ -0,0 +1,211 @@
/*
Copyright (C) 2001-2007 Paul Davis
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 <cmath>
#include <cassert>
#include <utility>
#include <gtkmm.h>
#include <gtkmm2ext/gtk_ui.h>
#include <ardour/midi_playlist.h>
#include <ardour/midi_region.h>
#include <ardour/midi_source.h>
#include <ardour/midi_diskstream.h>
#include <ardour/midi_track.h>
#include <ardour/midi_events.h>
#include <ardour/smf_source.h>
#include <ardour/region_factory.h>
#include "automation_streamview.h"
#include "region_view.h"
#include "automation_region_view.h"
#include "automation_time_axis.h"
#include "canvas-simplerect.h"
#include "region_selection.h"
#include "selection.h"
#include "public_editor.h"
#include "ardour_ui.h"
#include "rgb_macros.h"
#include "gui_thread.h"
#include "utils.h"
#include "simplerect.h"
#include "simpleline.h"
using namespace std;
using namespace ARDOUR;
using namespace PBD;
using namespace Editing;
AutomationStreamView::AutomationStreamView (AutomationTimeAxisView& tv)
: StreamView (*dynamic_cast<RouteTimeAxisView*>(tv.get_parent()),
new ArdourCanvas::Group(*tv.canvas_display))
, _controller(tv.controller())
, _automation_view(tv)
{
//canvas_rect->property_fill_color_rgba() = stream_base_color;
canvas_rect->property_outline_color_rgba() = RGBA_BLACK;
canvas_rect->lower(2);
use_rec_regions = tv.editor.show_waveforms_recording ();
}
AutomationStreamView::~AutomationStreamView ()
{
}
RegionView*
AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region, bool wfd)
{
if ( ! region) {
cerr << "No region" << endl;
return NULL;
}
if (wfd) {
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
if (mr)
mr->midi_source()->load_model();
}
const boost::shared_ptr<AutomationControl> control = region->control(_controller->controllable()->parameter());
if ( ! control) {
cerr << "No " << _controller->controllable()->parameter().to_string()
<< " for " << region->name() << endl;
return NULL;
}
const boost::shared_ptr<AutomationList> list = control->list();
AutomationRegionView *region_view;
std::list<RegionView *>::iterator i;
for (i = region_views.begin(); i != region_views.end(); ++i) {
if ((*i)->region() == region) {
/* great. we already have a MidiRegionView for this Region. use it again. */
(*i)->set_valid (true);
(*i)->enable_display(wfd);
display_region(dynamic_cast<AutomationRegionView*>(*i));
return NULL;
}
}
region_view = new AutomationRegionView (canvas_group, _automation_view, region, list,
_samples_per_unit, region_color);
region_view->init (region_color, false);
region_views.push_front (region_view);
/* follow global waveform setting */
if (wfd) {
region_view->enable_display(true);
//region_view->midi_region()->midi_source(0)->load_model();
}
/* display events */
display_region(region_view);
/* catch regionview going away */
region->GoingAway.connect (bind (mem_fun (*this, &AutomationStreamView::remove_region_view), region));
RegionViewAdded (region_view);
return region_view;
}
void
AutomationStreamView::display_region(AutomationRegionView* region_view)
{
region_view->line().reset();
region_view->raise();
}
void
AutomationStreamView::redisplay_diskstream ()
{
list<RegionView *>::iterator i, tmp;
for (i = region_views.begin(); i != region_views.end(); ++i)
(*i)->set_valid (false);
if (_trackview.is_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
}
for (i = region_views.begin(); i != region_views.end(); ) {
tmp = i;
tmp++;
if (!(*i)->is_valid()) {
delete *i;
region_views.erase (i);
} else {
(*i)->enable_display(true);
(*i)->set_y_position_and_height(0, height);
}
i = tmp;
}
/* now fix layering */
for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
region_layered (*i);
}
}
void
AutomationStreamView::setup_rec_box ()
{
}
void
AutomationStreamView::update_rec_regions (nframes_t start, nframes_t dur)
{
}
void
AutomationStreamView::rec_data_range_ready (jack_nframes_t start, jack_nframes_t dur)
{
// this is called from the butler thread for now
ENSURE_GUI_THREAD(bind (mem_fun (*this, &AutomationStreamView::rec_data_range_ready), start, dur));
this->update_rec_regions (start, dur);
}
void
AutomationStreamView::color_handler ()
{
/*if (_trackview.is_midi_track()) {
canvas_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiTrackBase.get();
}
if (!_trackview.is_midi_track()) {
canvas_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiBusBase.get();;
}*/
}

View File

@ -0,0 +1,72 @@
/*
Copyright (C) 2001, 2007 Paul Davis
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 __ardour_automation_streamview_h__
#define __ardour_automation_streamview_h__
#include <list>
#include <cmath>
#include <ardour/location.h>
#include "enums.h"
#include "simplerect.h"
#include "streamview.h"
#include "time_axis_view_item.h"
#include "route_time_axis.h"
#include "automation_controller.h"
namespace Gdk {
class Color;
}
class PublicEditor;
class Selectable;
class Selection;
class AutomationRegionView;
class AutomationStreamView : public StreamView
{
public:
AutomationStreamView (AutomationTimeAxisView& tv);
~AutomationStreamView ();
void set_selected_regionviews (RegionSelection&);
void get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable* >&);
void get_inverted_selectables (Selection&, list<Selectable* >& results);
void redisplay_diskstream ();
inline double contents_height() const
{ return (_trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
private:
void setup_rec_box ();
void rec_data_range_ready (jack_nframes_t start, jack_nframes_t dur);
void update_rec_regions (jack_nframes_t start, jack_nframes_t dur);
RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data);
void display_region(AutomationRegionView* region_view);
void color_handler ();
boost::shared_ptr<AutomationController> _controller;
AutomationTimeAxisView& _automation_view;
};
#endif /* __ardour_automation_streamview_h__ */

View File

@ -25,6 +25,7 @@
#include "ardour_ui.h"
#include "automation_time_axis.h"
#include "automation_streamview.h"
#include "route_time_axis.h"
#include "automation_line.h"
#include "public_editor.h"
@ -51,16 +52,17 @@ const string AutomationTimeAxisView::state_node_name = "AutomationChild";
AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
boost::shared_ptr<Automatable> a, boost::shared_ptr<AutomationControl> c,
PublicEditor& e, TimeAxisView& rent,
PublicEditor& e, TimeAxisView& parent, bool show_regions,
ArdourCanvas::Canvas& canvas, const string & nom, const string & nomparent)
: AxisView (s),
TimeAxisView (s, e, &rent, canvas),
TimeAxisView (s, e, &parent, canvas),
_route (r),
_control (c),
_automatable (a),
_controller(AutomationController::create(a, c->list(), c)),
_base_rect (0),
_view (show_regions ? new AutomationStreamView(*this) : NULL),
_name (nom),
height_button (_("h")),
clear_button (_("clear")),
@ -196,15 +198,25 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Ro
set_state (*xml_node);
}
boost::shared_ptr<AutomationLine> line(new AutomationLine (
_control->parameter().to_string(),
*this,
*canvas_display,
_control->list()));
line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
line->queue_reset ();
add_line (line);
/* ask for notifications of any new RegionViews */
if (show_regions) {
assert(_view);
_view->attach ();
/* no regions, just a single line for the entire track (e.g. bus gain) */
} else {
boost::shared_ptr<AutomationLine> line(new AutomationLine (
_control->parameter().to_string(),
*this,
*canvas_display,
_control->list()));
line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
line->queue_reset ();
add_line (line);
}
/* make sure labels etc. are correct */
@ -338,13 +350,15 @@ AutomationTimeAxisView::interpolation_changed ()
}
}
_line->set_interpolation(style);
if (_line)
_line->set_interpolation(style);
}
void
AutomationTimeAxisView::set_interpolation (AutomationList::InterpolationStyle style)
{
_control->list()->set_interpolation(style);
if (_line)
_line->set_interpolation(style);
}
@ -358,7 +372,8 @@ void
AutomationTimeAxisView::clear_clicked ()
{
_session.begin_reversible_command (_("clear automation"));
_line->clear ();
if (_line)
_line->clear ();
_session.commit_reversible_command ();
}
@ -373,9 +388,14 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
TimeAxisView::set_height (ht);
_base_rect->property_y2() = h;
if (_line)
_line->set_y_position_and_height (0, h);
if (_view) {
_view->set_height(h);
_view->update_contents_y_position_and_height();
}
for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
(*i)->set_height ();
@ -480,9 +500,13 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
void
AutomationTimeAxisView::set_samples_per_unit (double spu)
{
TimeAxisView::set_samples_per_unit (editor.get_current_zoom());
TimeAxisView::set_samples_per_unit (spu);
_line->reset ();
if (_line)
_line->reset ();
if (_view)
_view->set_samples_per_unit (spu);
}
void
@ -578,6 +602,9 @@ AutomationTimeAxisView::build_display_menu ()
void
AutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent* event, nframes_t when, double y)
{
if (!_line)
return;
double x = 0;
canvas_display->w2i (x, y);
@ -826,20 +853,23 @@ AutomationTimeAxisView::get_selectables (nframes_t start, nframes_t end, double
botfrac = 1.0 - ((bot - y_position) / height);
}
_line->get_selectables (start, end, botfrac, topfrac, results);
if (_line)
_line->get_selectables (start, end, botfrac, topfrac, results);
}
}
void
AutomationTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& result)
{
_line->get_inverted_selectables (sel, result);
if (_line)
_line->get_inverted_selectables (sel, result);
}
void
AutomationTimeAxisView::set_selected_points (PointSelection& points)
{
_line->set_selected_points (points);
if (_line)
_line->set_selected_points (points);
}
void
@ -873,13 +903,15 @@ AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
void
AutomationTimeAxisView::entered()
{
_line->track_entered();
if (_line)
_line->track_entered();
}
void
AutomationTimeAxisView::exited ()
{
_line->track_exited();
if (_line)
_line->track_exited();
}
void
@ -889,7 +921,8 @@ AutomationTimeAxisView::set_colors ()
(*i)->set_colors();
}
_line->set_colors();
if (_line)
_line->set_colors();
}
void

View File

@ -42,6 +42,7 @@ using std::string;
namespace ARDOUR {
class Session;
class Route;
class AutomationControl;
}
class PublicEditor;
@ -52,6 +53,8 @@ class AutomationLine;
class GhostRegion;
class Selection;
class Selectable;
class AutomationStreamView;
class AutomationController;
class AutomationTimeAxisView : public TimeAxisView {
@ -62,6 +65,7 @@ class AutomationTimeAxisView : public TimeAxisView {
boost::shared_ptr<ARDOUR::AutomationControl>,
PublicEditor&,
TimeAxisView& parent,
bool show_regions,
ArdourCanvas::Canvas& canvas,
const string & name, /* translatable */
const string & plug_name = "");
@ -101,6 +105,9 @@ class AutomationTimeAxisView : public TimeAxisView {
static const string state_node_name;
XMLNode* get_state_node();
boost::shared_ptr<ARDOUR::AutomationControl> control() { return _control; }
boost::shared_ptr<AutomationController> controller() { return _controller; }
protected:
boost::shared_ptr<ARDOUR::Route> _route; ///< Parent route
@ -111,6 +118,7 @@ class AutomationTimeAxisView : public TimeAxisView {
ArdourCanvas::SimpleRect* _base_rect;
boost::shared_ptr<AutomationLine> _line;
AutomationStreamView* _view;
string _name;
bool in_destructor;

View File

@ -410,7 +410,7 @@ MidiRegionView::redisplay_model()
end_write();
for (Automatable::Controls::const_iterator i = _model->controls().begin();
/*for (Automatable::Controls::const_iterator i = _model->controls().begin();
i != _model->controls().end(); ++i) {
assert(i->second);
@ -431,14 +431,13 @@ MidiRegionView::redisplay_model()
new AutomationRegionView(at->canvas_display,
*at.get(), _region, i->second->list(),
midi_stream_view()->get_samples_per_unit(), col));
arv->set_duration(_region->length(), this);
_automation_children.insert(std::make_pair(i->second->parameter(), arv));
}
arv->set_duration(_region->length(), this);
arv->init(col, true);
}
_automation_children.insert(std::make_pair(i->second->parameter(), arv));
}*/
_model->read_unlock();
@ -794,7 +793,6 @@ MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote)
void
MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev)
{
cerr << "NOTE ENTERED: " << _mouse_state << endl;
if (ev->note() && _mouse_state == EraseTouchDragging) {
start_delta_command();
ev->selected(true);

View File

@ -172,7 +172,7 @@ MidiStreamView::redisplay_diskstream ()
list<RegionView *>::iterator i, tmp;
for (i = region_views.begin(); i != region_views.end(); ++i) {
(*i)->enable_display(true); // FIXME: double display
(*i)->enable_display(true); // FIXME: double display, remove
(*i)->set_valid (false);
/* FIXME: slow. MidiRegionView needs a find_note_range method

View File

@ -118,15 +118,9 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar
controls_base_unselected_name = "MidiTrackControlsBaseUnselected";
/* ask for notifications of any new RegionViews */
_view->RegionViewAdded.connect (mem_fun(*this, &MidiTimeAxisView::region_view_added));
_view->attach ();
} /*else { // no MIDI busses yet
controls_ebox.set_name ("MidiBusControlsBaseUnselected");
controls_base_selected_name = "MidiBusControlsBaseSelected";
controls_base_unselected_name = "MidiBusControlsBaseUnselected";
}*/
}
}
MidiTimeAxisView::~MidiTimeAxisView ()
@ -267,7 +261,7 @@ MidiTimeAxisView::create_automation_child (Parameter param, bool show)
{
if (param.type() == MidiCCAutomation) {
/* FIXME: this all probably leaks */
/* FIXME: don't create AutomationList for track itself */
boost::shared_ptr<AutomationControl> c = _route->control(param);
@ -281,6 +275,7 @@ MidiTimeAxisView::create_automation_child (Parameter param, bool show)
_route, _route, c,
editor,
*this,
true,
parent_canvas,
_route->describe_parameter(param)));

View File

@ -258,10 +258,10 @@ RegionView::reset_width_dependent_items (double pixel_width)
TimeAxisViewItem::reset_width_dependent_items (pixel_width);
_pixel_width = pixel_width;
for (AutomationChildren::iterator i = _automation_children.begin();
/*for (AutomationChildren::iterator i = _automation_children.begin();
i != _automation_children.end(); ++i) {
i->second->reset_width_dependent_items(pixel_width);
}
}*/
}
void

View File

@ -1723,7 +1723,7 @@ RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor>
pan->view = boost::shared_ptr<AutomationTimeAxisView>(
new AutomationTimeAxisView (_session, _route, processor, control,
editor, *this, parent_canvas, name, state_name));
editor, *this, false, parent_canvas, name, state_name));
pan->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::processor_automation_track_hidden), pan, processor));

View File

@ -45,9 +45,9 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Editing;
StreamView::StreamView (RouteTimeAxisView& tv)
StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group)
: _trackview (tv)
, canvas_group(new ArdourCanvas::Group(*_trackview.canvas_display))
, canvas_group(group ? group : new ArdourCanvas::Group(*_trackview.canvas_display))
, canvas_rect(new ArdourCanvas::SimpleRect (*canvas_group))
, _samples_per_unit(_trackview.editor.get_current_zoom())
, rec_updating(false)

View File

@ -93,13 +93,14 @@ public:
void add_region_view (boost::shared_ptr<ARDOUR::Region>);
void region_layered (RegionView*);
void update_contents_y_position_and_height ();
virtual void redisplay_diskstream () = 0;
sigc::signal<void,RegionView*> RegionViewAdded;
protected:
StreamView (RouteTimeAxisView&);
StreamView (RouteTimeAxisView&, ArdourCanvas::Group* group = NULL);
//private: (FIXME?)
@ -111,7 +112,7 @@ protected:
void update_rec_box ();
//virtual void update_rec_regions () = 0;
virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves) = 0;
virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data) = 0;
virtual void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
//void remove_rec_region (boost::shared_ptr<ARDOUR::Region>); (unused)
@ -125,8 +126,6 @@ protected:
virtual void color_handler () = 0;
virtual void update_contents_y_position_and_height ();
RouteTimeAxisView& _trackview;
ArdourCanvas::Group* canvas_group;
ArdourCanvas::SimpleRect* canvas_rect; /* frame around the whole thing */

View File

@ -201,6 +201,7 @@ class TimeAxisView : public virtual AxisView
/* state/serialization management */
TimeAxisView* get_parent () { return parent; }
void set_parent (TimeAxisView& p);
bool has_state () const;

View File

@ -170,7 +170,7 @@ class AudioRegion : public Region
protected:
/* default constructor for derived (compound) types */
AudioRegion (nframes_t, nframes_t, std::string name);
AudioRegion (Session& s, nframes_t, nframes_t, std::string name);
AudioRegion (boost::shared_ptr<const AudioRegion>);
int set_live_state (const XMLNode&, Change&, bool send);

View File

@ -31,6 +31,7 @@
#include <ardour/gain.h>
#include <ardour/logcurve.h>
#include <ardour/export.h>
#include <ardour/midi_source.h>
class XMLNode;
@ -69,6 +70,17 @@ class MidiRegion : public Region
UndoAction get_memento() const;
// Act as a proxy for MidiModel automation stuff (for CC)
// Yep, this is pretty ugly...
Controls& controls() { return midi_source()->model()->controls(); }
const Controls& controls() const { return midi_source()->model()->controls(); }
boost::shared_ptr<AutomationControl> control(Parameter id, bool create_if_missing=false)
{ return midi_source()->model()->control(id, create_if_missing); }
boost::shared_ptr<const AutomationControl> control(Parameter id) const
{ return midi_source()->model()->control(id); }
private:
friend class RegionFactory;

View File

@ -25,10 +25,10 @@
#include <boost/enable_shared_from_this.hpp>
#include <pbd/undo.h>
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/data_type.h>
#include <ardour/automatable.h>
class XMLNode;
@ -43,7 +43,7 @@ enum RegionEditState {
EditChangesID = 2
};
class Region : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Region>
class Region : public Automatable, public boost::enable_shared_from_this<Region>
{
public:
typedef std::vector<boost::shared_ptr<Source> > SourceList;
@ -86,10 +86,8 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
virtual ~Region();
/* Note: changing the name of a Region does not constitute an edit */
string name() const { return _name; }
void set_name (string str);
/** Note: changing the name of a Region does not constitute an edit */
bool set_name (const std::string& str);
const DataType& data_type() const { return _type; }
@ -214,7 +212,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
/* this one is for derived types of derived types */
Region (nframes_t start, nframes_t length, const string& name, DataType, layer_t = 0, Flag flags = DefaultFlags);
Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType, layer_t = 0, Flag flags = DefaultFlags);
protected:
XMLNode& get_short_state (); /* used only by Session */
@ -234,7 +232,6 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
virtual void recompute_at_start () = 0;
virtual void recompute_at_end () = 0;
string _name;
DataType _type;
Flag _flags;
nframes_t _start;

View File

@ -110,8 +110,8 @@ class SMFSource : public MidiSource {
void seek_to_end();
void write_footer();
void write_chunk_header(char id[4], uint32_t length);
void write_chunk(char id[4], uint32_t length, void* data);
void write_chunk_header(const char id[4], uint32_t length);
void write_chunk(const char id[4], uint32_t length, void* data);
size_t write_var_len(uint32_t val);
uint32_t read_var_len() const;
int read_event(uint32_t* delta_t, uint32_t* size, Byte** buf) const;

View File

@ -40,7 +40,7 @@ namespace {
const char* const sfdb_file_name = "sfdb";
} // anonymous namespace
static char* TAG = "http://ardour.org/ontology/Tag";
static const char* TAG = "http://ardour.org/ontology/Tag";
AudioLibrary::AudioLibrary ()
{
@ -91,7 +91,7 @@ AudioLibrary::get_tags (string member)
lrdf_statement pattern;
pattern.subject = strdup(Glib::filename_to_uri(member).c_str());
pattern.predicate = TAG;
pattern.predicate = (char*)TAG;
pattern.object = 0;
pattern.object_type = lrdf_literal;
@ -123,8 +123,8 @@ AudioLibrary::search_members_and (vector<string>& members, const vector<string>
vector<string>::const_iterator i;
for (i = tags.begin(); i != tags.end(); ++i){
pattern = new lrdf_statement;
pattern->subject = "?";
pattern->predicate = TAG;
pattern->subject = (char*)"?";
pattern->predicate = (char*)TAG;
pattern->object = strdup((*i).c_str());
pattern->next = old;

View File

@ -70,8 +70,8 @@ AudioRegion::init ()
}
/* constructor for use by derived types only */
AudioRegion::AudioRegion (nframes_t start, nframes_t length, string name)
: Region (start, length, name, DataType::AUDIO)
AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name)
: Region (s, start, length, name, DataType::AUDIO)
, _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0))
, _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0))
, _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0))

View File

@ -77,7 +77,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
nframes_t length,
nframes_t position,
AnchorPoint ap)
: AudioRegion (position, length, "foobar"),
: AudioRegion (in->session(), position, length, "foobar"),
_fade_in (Parameter(FadeInAutomation), 0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (Parameter(FadeOutAutomation), 0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
@ -95,7 +95,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
}
Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model, bool act)
: AudioRegion (0, 0, "foobar"),
: AudioRegion (a->session(), 0, 0, "foobar"),
_fade_in (Parameter(FadeInAutomation), 0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (Parameter(FadeOutAutomation), 0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
@ -114,7 +114,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioR
}
Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
: AudioRegion (0, 0, "foobar"),
: AudioRegion (playlist.session(), 0, 0, "foobar"),
_fade_in (Parameter(FadeInAutomation), 0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (Parameter(FadeOutAutomation), 0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB

View File

@ -223,7 +223,7 @@ MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes
if (start != _next_read) {
_read_iter = const_iterator(*this, (double)start);
cerr << "Repositioning iterator from " << _next_read << " to " << start << endl;
// cerr << "Repositioning iterator from " << _next_read << " to " << start << endl;
//} else {
// cerr << "Using cached iterator at " << _next_read << endl;
}

View File

@ -287,7 +287,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
pattern.subject = buf;
pattern.predicate = RDF_TYPE;
pattern.predicate = (char*)RDF_TYPE;
pattern.object = 0;
pattern.object_type = lrdf_uri;
@ -298,7 +298,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
}
pattern.subject = matches1->object;
pattern.predicate = LADSPA_BASE "hasLabel";
pattern.predicate = (char*)LADSPA_BASE "hasLabel";
pattern.object = 0;
pattern.object_type = lrdf_literal;

View File

@ -52,8 +52,8 @@ Change Region::HiddenChanged = ARDOUR::new_change ();
/* derived-from-derived constructor (no sources in constructor) */
Region::Region (nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: _name(name)
Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: Automatable(s, name)
, _type(type)
, _flags(flags)
, _start(start)
@ -73,7 +73,7 @@ Region::Region (nframes_t start, nframes_t length, const string& name, DataType
/** Basic Region constructor (single source) */
Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: _name(name)
: Automatable(src->session(), name)
, _type(type)
, _flags(flags)
, _start(start)
@ -97,7 +97,7 @@ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length
/** Basic Region constructor (many sources) */
Region::Region (SourceList& srcs, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: _name(name)
: Automatable(srcs.front()->session(), name)
, _type(type)
, _flags(flags)
, _start(start)
@ -132,7 +132,7 @@ Region::Region (SourceList& srcs, nframes_t start, nframes_t length, const strin
/** Create a new Region from part of an existing one */
Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
: _name(name)
: Automatable(other->session(), name)
, _type(other->data_type())
, _flags(Flag(flags & ~(Locked|PositionLocked|WholeFile|Hidden)))
, _start(other->_start + offset)
@ -173,7 +173,7 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
/** Pure copy constructor */
Region::Region (boost::shared_ptr<const Region> other)
: _name(other->_name)
: Automatable(other->session(), other->name())
, _type(other->data_type())
, _flags(Flag(other->_flags & ~(Locked|PositionLocked)))
, _start(other->_start)
@ -214,7 +214,7 @@ Region::Region (boost::shared_ptr<const Region> other)
}
Region::Region (SourceList& srcs, const XMLNode& node)
: _name(X_("error: XML did not reset this"))
: Automatable(srcs.front()->session(), X_("error: XML did not reset this"))
, _type(DataType::NIL) // to be loaded from XML
, _flags(Flag(0))
, _start(0)
@ -252,7 +252,7 @@ Region::Region (SourceList& srcs, const XMLNode& node)
}
Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
: _name(X_("error: XML did not reset this"))
: Automatable(src->session(), X_("error: XML did not reset this"))
, _type(DataType::NIL)
, _flags(Flag(0))
, _start(0)
@ -323,13 +323,16 @@ Region::set_playlist (boost::weak_ptr<Playlist> wpl)
}
}
void
Region::set_name (string str)
bool
Region::set_name (const std::string& str)
{
if (_name != str) {
_name = str;
send_change (NameChanged);
SessionObject::set_name(str); // EMIT SIGNAL NameChanged()
assert(_name == str);
send_change (ARDOUR::NameChanged);
}
return true;
}
void
@ -383,7 +386,7 @@ Region::first_edit ()
_name = pl->session().new_region_name (_name);
_first_edit = EditChangesNothing;
send_change (NameChanged);
send_change (ARDOUR::NameChanged);
RegionFactory::CheckNewRegion (shared_from_this());
}
}
@ -907,7 +910,7 @@ Region::state (bool full_state)
{
XMLNode *node = new XMLNode ("Region");
char buf[64];
char* fe = NULL;
const char* fe = NULL;
_id.print (buf, sizeof (buf));
node->add_property ("id", buf);

View File

@ -783,7 +783,7 @@ SMFSource::is_empty () const
void
SMFSource::write_chunk_header(char id[4], uint32_t length)
SMFSource::write_chunk_header(const char id[4], uint32_t length)
{
const uint32_t length_be = GUINT32_TO_BE(length);
@ -792,7 +792,7 @@ SMFSource::write_chunk_header(char id[4], uint32_t length)
}
void
SMFSource::write_chunk(char id[4], uint32_t length, void* data)
SMFSource::write_chunk(const char id[4], uint32_t length, void* data)
{
write_chunk_header(id, length);
@ -857,6 +857,8 @@ SMFSource::load_model(bool lock, bool force_reload)
//cerr << _name << " NOT reloading model " << _model.get() << " (" << _model->n_notes()
// << " notes)" << endl;
return;
} else {
cerr << _name << " loading model" << endl;
}
if (! _model) {

View File

@ -414,7 +414,7 @@ UI::process_error_message (Transmitter::Channel chn, const char *str)
RefPtr<Style> style;
RefPtr<TextBuffer::Tag> ptag;
RefPtr<TextBuffer::Tag> mtag;
char *prefix;
const char *prefix;
size_t prefix_len;
bool fatal_received = false;
#ifndef OLD_STYLE_ERRORS