Drop some unused files - avoid trying to maintain stuff that can't be tested
This commit is contained in:
parent
140670541f
commit
8a5f21d8e3
@ -1323,10 +1323,6 @@
|
||||
RelativePath="..\gtk2_ardour\tempo_dialog.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gtk2_ardour\tempo_lines.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gtk2_ardour\time_axis_view.cc"
|
||||
>
|
||||
@ -1645,10 +1641,6 @@
|
||||
RelativePath="..\gtk2_ardour\crossfade_edit.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gtk2_ardour\crossfade_view.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gtk2_ardour\cursor_context.h"
|
||||
>
|
||||
@ -2537,10 +2529,6 @@
|
||||
RelativePath="..\gtk2_ardour\tempo_dialog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gtk2_ardour\tempo_lines.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gtk2_ardour\time_axis_view.h"
|
||||
>
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2005 Nick Mainsbridge <mainsbridge@gmail.com>
|
||||
* Copyright (C) 2005 Taybin Rutkin <taybin@taybin.com>
|
||||
* Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2007-2011 Carl Hetherington <carl@carlh.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "pbd/signals.h"
|
||||
#include "ardour/crossfade.h"
|
||||
|
||||
#include "time_axis_view_item.h"
|
||||
|
||||
class RouteTimeAxisView;
|
||||
class AudioRegionView;
|
||||
|
||||
namespace ArdourCanvas {
|
||||
class PolyLine;
|
||||
}
|
||||
|
||||
class CrossfadeView : public TimeAxisViewItem
|
||||
{
|
||||
public:
|
||||
CrossfadeView (ArdourCanvas::Container*,
|
||||
RouteTimeAxisView&,
|
||||
std::shared_ptr<ARDOUR::Crossfade>,
|
||||
double initial_samples_per_pixel,
|
||||
Gdk::Color& basic_color,
|
||||
AudioRegionView& leftview,
|
||||
AudioRegionView& rightview);
|
||||
|
||||
~CrossfadeView ();
|
||||
|
||||
std::shared_ptr<ARDOUR::Crossfade> crossfade; // ok, let 'em have it
|
||||
|
||||
AudioRegionView& left_view; // and these too
|
||||
AudioRegionView& right_view;
|
||||
|
||||
void set_heights (double, double);
|
||||
|
||||
bool valid() const { return _valid; }
|
||||
bool visible() const { return _visible; }
|
||||
void set_valid (bool yn);
|
||||
|
||||
static PBD::Signal<void(CrossfadeView*)> CatchDeletion;
|
||||
|
||||
void fake_hide ();
|
||||
void hide ();
|
||||
void show ();
|
||||
void horizontal_position_changed ();
|
||||
|
||||
protected:
|
||||
void reset_width_dependent_items (double pixel_width);
|
||||
|
||||
private:
|
||||
bool _valid;
|
||||
bool _visible;
|
||||
bool _all_in_view;
|
||||
double _child_height;
|
||||
|
||||
ArdourCanvas::PolyLine *fade_in;
|
||||
ArdourCanvas::PolyLine *fade_out;
|
||||
|
||||
void crossfade_changed (const PBD::PropertyChange&);
|
||||
void crossfade_fades_changed ();
|
||||
void active_changed ();
|
||||
void redraw_curves ();
|
||||
void color_handler ();
|
||||
};
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "audio_clock.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class BeatsSamplesConverter;
|
||||
class Session;
|
||||
class InstrumentInfo;
|
||||
}
|
||||
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2015 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2010-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2012 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2014-2017 Nick Mainsbridge <mainsbridge@gmail.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "pbd/compose.h"
|
||||
|
||||
#include "canvas/canvas.h"
|
||||
#include "canvas/debug.h"
|
||||
|
||||
#include "tempo_lines.h"
|
||||
#include "public_editor.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "ui_config.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
TempoLines::TempoLines (ArdourCanvas::Container* group, double, ARDOUR::BeatsSamplesConverter* bfc)
|
||||
: lines (group, ArdourCanvas::LineSet::Vertical)
|
||||
, _bfc (bfc)
|
||||
{
|
||||
lines.set_extent (ArdourCanvas::COORD_MAX);
|
||||
}
|
||||
|
||||
TempoLines::~TempoLines ()
|
||||
{
|
||||
delete _bfc;
|
||||
_bfc = 0;
|
||||
}
|
||||
|
||||
void
|
||||
TempoLines::tempo_map_changed (samplepos_t new_origin)
|
||||
{
|
||||
lines.clear ();
|
||||
_bfc->set_origin_b (new_origin);
|
||||
}
|
||||
|
||||
void
|
||||
TempoLines::show ()
|
||||
{
|
||||
lines.show ();
|
||||
}
|
||||
|
||||
void
|
||||
TempoLines::hide ()
|
||||
{
|
||||
lines.hide ();
|
||||
}
|
||||
|
||||
void
|
||||
TempoLines::draw_ticks (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
unsigned divisions,
|
||||
samplecnt_t leftmost_sample,
|
||||
samplecnt_t sample_rate)
|
||||
{
|
||||
const uint32_t base = UIConfiguration::instance().color_mod("measure line beat", "measure line beat");
|
||||
|
||||
for (unsigned l = 1; l < divisions; ++l) {
|
||||
/* find the coarsest division level this tick falls on */
|
||||
unsigned level = divisions;
|
||||
for (unsigned d = divisions; d >= 4; d /= 2) {
|
||||
if (l % (divisions / d) == 0) {
|
||||
level = d;
|
||||
}
|
||||
}
|
||||
/* draw line with alpha corresponding to coarsest level */
|
||||
const uint8_t a = max(8, (int)rint(UINT_RGBA_A(base) / (0.8 * log2(level))));
|
||||
const uint32_t c = UINT_RGBA_CHANGE_A(base, a);
|
||||
const samplepos_t f = _bfc->to (Temporal::Beats (grid.begin()->qn + (l / (double) divisions))) + _bfc->origin_b();
|
||||
|
||||
if (f > leftmost_sample) {
|
||||
lines.add (PublicEditor::instance().sample_to_pixel_unrounded (f), 1.0, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TempoLines::draw (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
unsigned divisions,
|
||||
samplecnt_t leftmost_sample,
|
||||
samplecnt_t sample_rate)
|
||||
{
|
||||
std::vector<ARDOUR::TempoMap::BBTPoint>::const_iterator i;
|
||||
double beat_density;
|
||||
|
||||
uint32_t beats = 0;
|
||||
uint32_t bars = 0;
|
||||
const uint32_t bar_color = UIConfiguration::instance().color ("measure line bar");
|
||||
const uint32_t beat_color = UIConfiguration::instance().color_mod ("measure line beat", "measure line beat");
|
||||
uint32_t color;
|
||||
|
||||
bool all_bars = false;
|
||||
/* get the first bar spacing */
|
||||
|
||||
i = grid.end();
|
||||
i--;
|
||||
bars = (*i).bar - (*grid.begin()).bar;
|
||||
|
||||
int32_t bar_mod = 4;
|
||||
|
||||
if (bars < distance (grid.begin(), grid.end()) - 1) {
|
||||
/* grid contains beats and bars */
|
||||
beats = distance (grid.begin(), grid.end()) - bars;
|
||||
} else {
|
||||
/* grid contains only bars */
|
||||
beats = distance (grid.begin(), grid.end());
|
||||
|
||||
if (i != grid.begin()) {
|
||||
const int32_t last_bar = (*i).bar;
|
||||
i--;
|
||||
bar_mod = (last_bar - (*i).bar) * 4;
|
||||
}
|
||||
|
||||
all_bars = true;
|
||||
}
|
||||
|
||||
double canvas_width_used = 1.0;
|
||||
if (leftmost_sample < grid.front().sample) {
|
||||
const samplecnt_t sample_distance = max ((samplecnt_t) 1, grid.back().sample - grid.front().sample);
|
||||
canvas_width_used = 1.0 - ((grid.front().sample - leftmost_sample) / (double) (sample_distance + grid.front().sample));
|
||||
}
|
||||
|
||||
beat_density = (beats * 10.0f) / (lines.canvas()->width() * canvas_width_used);
|
||||
|
||||
if (beat_density > 2.0f) {
|
||||
/* if the lines are too close together, they become useless */
|
||||
lines.clear ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* constrain divisions to a log2 factor to cap line density */
|
||||
while (divisions > 3 && beat_density * divisions > 0.4) {
|
||||
divisions /= 2;
|
||||
}
|
||||
|
||||
lines.clear ();
|
||||
if (beat_density <= 0.12 && grid.begin() != grid.end() && grid.begin()->sample > 0 && !all_bars) {
|
||||
/* draw subdivisions of the beat before the first visible beat line XX this shouldn't happen now */
|
||||
std::vector<ARDOUR::TempoMap::BBTPoint> vec;
|
||||
vec.push_back (*i);
|
||||
draw_ticks (vec, divisions, leftmost_sample, sample_rate);
|
||||
}
|
||||
|
||||
for (i = grid.begin(); i != grid.end(); ++i) {
|
||||
|
||||
if ((*i).is_bar()) {
|
||||
/* keep all_bar beat density down */
|
||||
if (all_bars && beat_density > 0.3 && ((*i).bar % bar_mod) != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
color = bar_color;
|
||||
} else {
|
||||
if (beat_density > 0.3) {
|
||||
continue; /* only draw beat lines if the gaps between beats are large. */
|
||||
}
|
||||
color = beat_color;
|
||||
}
|
||||
|
||||
ArdourCanvas::Coord xpos = PublicEditor::instance().sample_to_pixel_unrounded ((*i).sample);
|
||||
|
||||
lines.add (xpos, 1.0, color);
|
||||
|
||||
if (beat_density <= 0.12 && !all_bars) {
|
||||
/* draw subdivisions of this beat */
|
||||
std::vector<ARDOUR::TempoMap::BBTPoint> vec;
|
||||
vec.push_back (*i);
|
||||
draw_ticks (vec, divisions, leftmost_sample, sample_rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2015 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2012-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2015-2017 Nick Mainsbridge <mainsbridge@gmail.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ardour/tempo.h"
|
||||
|
||||
#include "canvas/line_set.h"
|
||||
|
||||
class TempoLines {
|
||||
public:
|
||||
TempoLines (ArdourCanvas::Container* group, double screen_height, ARDOUR::BeatsSamplesConverter* bfc);
|
||||
~TempoLines ();
|
||||
|
||||
void tempo_map_changed(samplepos_t new_origin);
|
||||
|
||||
void draw (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
unsigned divisions,
|
||||
ARDOUR::samplecnt_t leftmost_sample,
|
||||
ARDOUR::samplecnt_t sample_rate);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
private:
|
||||
void draw_ticks (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
unsigned divisions,
|
||||
ARDOUR::samplecnt_t leftmost_sample,
|
||||
ARDOUR::samplecnt_t sample_rate);
|
||||
|
||||
ArdourCanvas::LineSet lines;
|
||||
ARDOUR::BeatsSamplesConverter* _bfc;
|
||||
};
|
||||
|
@ -1881,10 +1881,6 @@
|
||||
RelativePath="..\ardour\export_handler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ardour\export_multiplication.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ardour\export_pointers.h"
|
||||
>
|
||||
@ -2545,10 +2541,6 @@
|
||||
RelativePath="..\ardour\soundcloud_upload.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ardour\soundseq.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ardour\source.h"
|
||||
>
|
||||
|
@ -43,7 +43,6 @@
|
||||
namespace ARDOUR {
|
||||
|
||||
class AutomationList;
|
||||
class BeatsSamplesConverter;
|
||||
|
||||
/** A SharedStatefulProperty for AutomationLists */
|
||||
class LIBARDOUR_API AutomationListProperty : public PBD::SharedStatefulProperty<AutomationList>
|
||||
|
@ -1,207 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 Paul Davis <paul@linuxaudiosystems.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* This file is not used at the moment. It includes code related to export a
|
||||
* multiplication graph system that can be used together with the ExportMultiplicator
|
||||
* class in the gtk2_ardour folder.
|
||||
* - Sakari Bergen 6.8.2008 -
|
||||
*/
|
||||
|
||||
/*** Graph classes ***/
|
||||
public:
|
||||
|
||||
/// A node in the hierarchical graph that represents a multiplicatable export item
|
||||
class GraphNode {
|
||||
public:
|
||||
GraphNode ();
|
||||
virtual ~GraphNode ();
|
||||
|
||||
uint32_t id() const { return _id; }
|
||||
|
||||
/* Children and parents. Note: only children are kept in order! */
|
||||
|
||||
list<GraphNode *> const & get_parents () const { return parents; }
|
||||
|
||||
void add_child (GraphNode * child, GraphNode * left_sibling);
|
||||
void remove_child (GraphNode * child);
|
||||
GraphNode * first_child () const { return children.front(); }
|
||||
GraphNode * last_child () const { return children.back(); }
|
||||
list<GraphNode *> const & get_children () const { return children; }
|
||||
|
||||
/* Relation functions */
|
||||
|
||||
bool is_ancestor_of (GraphNode const * node) const;
|
||||
bool is_descendant_of (GraphNode const * node) const;
|
||||
bool equals (GraphNode const * node) const { return node == this; }
|
||||
|
||||
/* Selection functions */
|
||||
|
||||
bool selected () const { return _selected; }
|
||||
void select (bool value);
|
||||
|
||||
PBD::Signal<void(bool)> SelectChanged;
|
||||
|
||||
protected:
|
||||
|
||||
/* Parent manipulation functions should be used only from child manipulation functions! */
|
||||
|
||||
void add_parent (GraphNode * parent);
|
||||
void remove_parent (GraphNode * parent);
|
||||
|
||||
list<GraphNode *> parents;
|
||||
list<GraphNode *> children;
|
||||
|
||||
bool _selected;
|
||||
uint32_t _id;
|
||||
static uint32_t id_counter;
|
||||
};
|
||||
|
||||
/// A graph node that contains data
|
||||
template <typename T>
|
||||
class DataNode : public GraphNode {
|
||||
private:
|
||||
typedef std::shared_ptr<T> DataPtr;
|
||||
typedef std::shared_ptr<DataNode<T> > SelfPtr;
|
||||
typedef std::weak_ptr<DataNode<T> > WeakSelfPtr;
|
||||
|
||||
DataNode (DataPtr data) : _data (data) {}
|
||||
void set_self_ptr (std::shared_ptr<DataNode<T> > ptr) { _self_ptr = ptr; }
|
||||
|
||||
public:
|
||||
static SelfPtr create (T * data)
|
||||
{
|
||||
SelfPtr ptr = SelfPtr (new DataNode<T> (DataPtr (data)));
|
||||
ptr->set_self_ptr (ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static SelfPtr create (DataPtr data)
|
||||
{
|
||||
SelfPtr ptr = SelfPtr (new DataNode<T> (data));
|
||||
ptr->set_self_ptr (ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
DataPtr data() { return _data; }
|
||||
SelfPtr self_ptr () { return _self_ptr.lock(); }
|
||||
|
||||
template<typename P> // Parent's data type
|
||||
void sort_parents (list<std::shared_ptr<DataNode<P> > > const & sort_list)
|
||||
{
|
||||
parents.sort (NodeSorter<P> (sort_list));
|
||||
}
|
||||
|
||||
private:
|
||||
DataPtr _data;
|
||||
WeakSelfPtr _self_ptr;
|
||||
};
|
||||
|
||||
private:
|
||||
/* Sorts GraphNodes according to a list of DataNodes */
|
||||
|
||||
template<typename T>
|
||||
class NodeSorter {
|
||||
public:
|
||||
typedef list<std::shared_ptr<DataNode<T> > > ListType;
|
||||
|
||||
NodeSorter (ListType const & list) : list (list) {}
|
||||
|
||||
bool operator() (GraphNode * one, GraphNode * other) // '<' operator
|
||||
{
|
||||
if (one == other) { return false; } // Strict weak ordering
|
||||
for (typename ListType::const_iterator it = list.begin(); it != list.end(); ++it) {
|
||||
if (it->get() == one) {
|
||||
return true;
|
||||
}
|
||||
if (it->get() == other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Invalid comparison list given to NodeSorter" << std::endl;
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
private:
|
||||
ListType const & list;
|
||||
};
|
||||
|
||||
/*** Multiplication management ***/
|
||||
public:
|
||||
|
||||
typedef DataNode<TimespanState> TimespanNode;
|
||||
typedef std::shared_ptr<TimespanNode> TimespanNodePtr;
|
||||
|
||||
typedef DataNode<ChannelConfigState> ChannelConfigNode;
|
||||
typedef std::shared_ptr<ChannelConfigNode> ChannelConfigNodePtr;
|
||||
|
||||
typedef DataNode<FormatState> FormatNode;
|
||||
typedef std::shared_ptr<FormatNode> FormatNodePtr;
|
||||
|
||||
typedef DataNode<FilenameState> FilenameNode;
|
||||
typedef std::shared_ptr<FilenameNode> FilenameNodePtr;
|
||||
|
||||
struct MultiplicationGraph {
|
||||
list<TimespanNodePtr> timespans;
|
||||
list<ChannelConfigNodePtr> channel_configs;
|
||||
list<FormatNodePtr> formats;
|
||||
list<FilenameNodePtr> filenames;
|
||||
};
|
||||
|
||||
MultiplicationGraph const & get_graph () { return graph; }
|
||||
|
||||
void split_node (GraphNode * node, float position);
|
||||
void remove_node (GraphNode * node);
|
||||
|
||||
PBD::Signal<void()> GraphChanged;
|
||||
|
||||
private:
|
||||
|
||||
void purge_graph ();
|
||||
|
||||
template<typename T>
|
||||
static void insert_after (list<T> & the_list, T const & position, T const & element);
|
||||
|
||||
template<typename T>
|
||||
static void remove_by_element (list<T> & the_list, T const & element);
|
||||
|
||||
bool nodes_have_one_common_child (list<GraphNode *> const & the_list);
|
||||
list<GraphNode *>::const_iterator end_of_common_child_range (list<GraphNode *> const & the_list, list<GraphNode *>::const_iterator beginning);
|
||||
void split_node_at_position (GraphNode * old_node, GraphNode * new_node, float position);
|
||||
|
||||
void split_timespan (TimespanNodePtr node, float position = 0.5);
|
||||
void split_channel_config (ChannelConfigNodePtr node, float position = 0.5);
|
||||
void split_format (FormatNodePtr node, float position = 0.5);
|
||||
void split_filename (FilenameNodePtr node, float position = 0.5);
|
||||
|
||||
void duplicate_timespan_children (TimespanNodePtr source, TimespanNodePtr target, GraphNode * insertion_point = 0);
|
||||
void duplicate_channel_config_children (ChannelConfigNodePtr source, ChannelConfigNodePtr target, GraphNode * insertion_point = 0);
|
||||
void duplicate_format_children (FormatNodePtr source, FormatNodePtr target, GraphNode * insertion_point = 0);
|
||||
|
||||
TimespanNodePtr duplicate_timespan_node (TimespanNodePtr node);
|
||||
ChannelConfigNodePtr duplicate_channel_config_node (ChannelConfigNodePtr node);
|
||||
FormatNodePtr duplicate_format_node (FormatNodePtr node);
|
||||
FilenameNodePtr duplicate_filename_node (FilenameNodePtr node);
|
||||
|
||||
void remove_timespan (TimespanNodePtr node);
|
||||
void remove_channel_config (ChannelConfigNodePtr node);
|
||||
void remove_format (FormatNodePtr node);
|
||||
void remove_filename (FilenameNodePtr node);
|
||||
|
||||
MultiplicationGraph graph;
|
@ -44,7 +44,6 @@ class Beats;
|
||||
namespace ARDOUR
|
||||
{
|
||||
|
||||
class BeatsSamplesConverter;
|
||||
class MidiChannelFilter;
|
||||
class MidiRegion;
|
||||
class Session;
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "edl.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
typedef gint16 peak_datum;
|
||||
|
||||
struct LIBARDOUR_API peak_data_t {
|
||||
peak_datum min;
|
||||
peak_datum max;
|
||||
};
|
||||
|
||||
const uint32_t samples_per_peak = 2048;
|
||||
|
||||
class LIBARDOUR_API Sound : public EDL::Piece {
|
||||
public:
|
||||
int peak (peak_data_t& pk, uint32_t start, uint32_t cnt);
|
||||
int read_peaks (peak_data_t *, uint32_t npeaks, uint32_t start, uint32_t cnt);
|
||||
int build_peak (uint32_t first_sample, uint32_t cnt);
|
||||
};
|
||||
|
||||
class LIBARDOUR_API SoundPlaylist : public EDL::Playlist {
|
||||
public:
|
||||
int read_peaks (peak_data_t *, uint32_t npeaks, uint32_t start, uint32_t cnt);
|
||||
};
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
||||
|
||||
|
||||
|
@ -483,10 +483,6 @@
|
||||
RelativePath="..\evoral\midi_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\evoral\MIDIXML.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\evoral\Note.h"
|
||||
>
|
||||
@ -523,10 +519,6 @@
|
||||
RelativePath="..\libsmf\smf_private.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\evoral\SMFReader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\evoral\TimeConverter.h"
|
||||
>
|
||||
|
@ -1,285 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2011 David Robillard <d@drobilla.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <glibmm/miscutils.h>
|
||||
|
||||
#include "evoral/midi_util.h"
|
||||
#include "evoral/SMFReader.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
|
||||
SMFReader::SMFReader(const string& filename)
|
||||
: _fd(NULL)
|
||||
, _ppqn(0)
|
||||
, _track(0)
|
||||
, _track_size(0)
|
||||
{
|
||||
if (filename.length() > 0) {
|
||||
open(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SMFReader::~SMFReader()
|
||||
{
|
||||
if (_fd)
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SMFReader::open(const string& filename) throw (logic_error, UnsupportedTime)
|
||||
{
|
||||
if (_fd)
|
||||
throw logic_error("Attempt to start new read while write in progress.");
|
||||
|
||||
cout << "Opening SMF file " << filename << " for reading." << endl;
|
||||
|
||||
_fd = g_fopen(filename.c_str(), "r+b");
|
||||
|
||||
if (_fd) {
|
||||
// Read type (bytes 8..9)
|
||||
fseek(_fd, 0, SEEK_SET);
|
||||
char mthd[5];
|
||||
mthd[4] = '\0';
|
||||
fread(mthd, 1, 4, _fd);
|
||||
if (strcmp(mthd, "MThd")) {
|
||||
cerr << filename << " is not an SMF file, aborting." << endl;
|
||||
fclose(_fd);
|
||||
_fd = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read type (bytes 8..9)
|
||||
fseek(_fd, 8, SEEK_SET);
|
||||
uint16_t type_be = 0;
|
||||
fread(&type_be, 2, 1, _fd);
|
||||
_type = GUINT16_FROM_BE(type_be);
|
||||
|
||||
// Read number of tracks (bytes 10..11)
|
||||
uint16_t num_tracks_be = 0;
|
||||
fread(&num_tracks_be, 2, 1, _fd);
|
||||
_num_tracks = GUINT16_FROM_BE(num_tracks_be);
|
||||
|
||||
// Read PPQN (bytes 12..13)
|
||||
uint16_t ppqn_be = 0;
|
||||
fread(&ppqn_be, 2, 1, _fd);
|
||||
_ppqn = GUINT16_FROM_BE(ppqn_be);
|
||||
|
||||
// TODO: Absolute (SMPTE seconds) time support
|
||||
if ((_ppqn & 0x8000) != 0)
|
||||
throw UnsupportedTime();
|
||||
|
||||
seek_to_track(1);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Seek to the start of a given track, starting from 1.
|
||||
* Returns true if specified track was found.
|
||||
*/
|
||||
bool
|
||||
SMFReader::seek_to_track(unsigned track) throw (std::logic_error)
|
||||
{
|
||||
if (track == 0)
|
||||
throw logic_error("Seek to track 0 out of range (must be >= 1)");
|
||||
|
||||
if (!_fd)
|
||||
throw logic_error("Attempt to seek to track on unopened SMF file.");
|
||||
|
||||
unsigned track_pos = 0;
|
||||
|
||||
fseek(_fd, 14, SEEK_SET);
|
||||
char id[5];
|
||||
id[4] = '\0';
|
||||
uint32_t chunk_size = 0;
|
||||
|
||||
while (!feof(_fd)) {
|
||||
fread(id, 1, 4, _fd);
|
||||
|
||||
if (!strcmp(id, "MTrk")) {
|
||||
++track_pos;
|
||||
} else {
|
||||
std::cerr << "Unknown chunk ID " << id << endl;
|
||||
}
|
||||
|
||||
uint32_t chunk_size_be;
|
||||
fread(&chunk_size_be, 4, 1, _fd);
|
||||
chunk_size = GUINT32_FROM_BE(chunk_size_be);
|
||||
|
||||
if (track_pos == track)
|
||||
break;
|
||||
|
||||
fseek(_fd, chunk_size, SEEK_CUR);
|
||||
}
|
||||
|
||||
if (!feof(_fd) && track_pos == track) {
|
||||
_track = track;
|
||||
_track_size = chunk_size;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Read an event from the current position in file.
|
||||
*
|
||||
* File position MUST be at the beginning of a delta time, or this will die very messily.
|
||||
* ev.buffer must be of size ev.size, and large enough for the event. The returned event
|
||||
* will have it's time field set to it's delta time (so it's the caller's responsibility
|
||||
* to keep track of delta time, even for ignored events).
|
||||
*
|
||||
* Returns event length (including status byte) on success, 0 if event was
|
||||
* skipped (eg a meta event), or -1 on EOF (or end of track).
|
||||
*
|
||||
* If @a buf is not large enough to hold the event, 0 will be returned, but ev_size
|
||||
* set to the actual size of the event.
|
||||
*/
|
||||
int
|
||||
SMFReader::read_event(size_t buf_len,
|
||||
uint8_t* buf,
|
||||
uint32_t* ev_size,
|
||||
uint32_t* delta_time)
|
||||
throw (std::logic_error, PrematureEOF, CorruptFile)
|
||||
{
|
||||
if (_track == 0)
|
||||
throw logic_error("Attempt to read from unopened SMF file");
|
||||
|
||||
if (!_fd || feof(_fd)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(buf_len > 0);
|
||||
assert(buf);
|
||||
assert(ev_size);
|
||||
assert(delta_time);
|
||||
|
||||
// Running status state
|
||||
static uint8_t last_status = 0;
|
||||
static uint32_t last_size = 0;
|
||||
|
||||
*delta_time = read_var_len(_fd);
|
||||
int status = fgetc(_fd);
|
||||
if (status == EOF)
|
||||
throw PrematureEOF();
|
||||
else if (status > 0xFF)
|
||||
throw CorruptFile();
|
||||
|
||||
if (status < 0x80) {
|
||||
if (last_status == 0)
|
||||
throw CorruptFile();
|
||||
status = last_status;
|
||||
*ev_size = last_size;
|
||||
fseek(_fd, -1, SEEK_CUR);
|
||||
} else {
|
||||
last_status = status;
|
||||
*ev_size = midi_event_size(status);
|
||||
last_size = *ev_size;
|
||||
}
|
||||
|
||||
buf[0] = (uint8_t)status;
|
||||
|
||||
if (status == 0xFF) {
|
||||
*ev_size = 0;
|
||||
if (feof(_fd))
|
||||
throw PrematureEOF();
|
||||
uint8_t type = fgetc(_fd);
|
||||
const uint32_t size = read_var_len(_fd);
|
||||
/*cerr.flags(ios::hex);
|
||||
cerr << "SMF - meta 0x" << (int)type << ", size = ";
|
||||
cerr.flags(ios::dec);
|
||||
cerr << size << endl;*/
|
||||
|
||||
if ((uint8_t)type == 0x2F) {
|
||||
return -1; // we hit the logical EOF anyway...
|
||||
} else {
|
||||
fseek(_fd, size, SEEK_CUR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ev_size > buf_len || *ev_size == 0 || feof(_fd)) {
|
||||
//cerr << "SMF - Skipping event" << endl;
|
||||
// Skip event, return 0
|
||||
fseek(_fd, *ev_size - 1, SEEK_CUR);
|
||||
return 0;
|
||||
} else {
|
||||
// Read event, return size
|
||||
if (ferror(_fd))
|
||||
throw CorruptFile();
|
||||
|
||||
fread(buf+1, 1, *ev_size - 1, _fd);
|
||||
|
||||
if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) {
|
||||
buf[0] = (0x80 | (buf[0] & 0x0F));
|
||||
buf[2] = 0x40;
|
||||
}
|
||||
|
||||
return *ev_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SMFReader::close()
|
||||
{
|
||||
if (_fd)
|
||||
fclose(_fd);
|
||||
|
||||
_fd = NULL;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
SMFReader::read_var_len(FILE* fd) throw (PrematureEOF)
|
||||
{
|
||||
if (feof(fd))
|
||||
throw PrematureEOF();
|
||||
|
||||
uint32_t value;
|
||||
uint8_t c;
|
||||
|
||||
if ( (value = getc(fd)) & 0x80 ) {
|
||||
value &= 0x7F;
|
||||
do {
|
||||
if (feof(fd))
|
||||
throw PrematureEOF();
|
||||
value = (value << 7) + ((c = getc(fd)) & 0x7F);
|
||||
} while (c & 0x80);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Evoral
|
||||
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 David Robillard <d@drobilla.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef EVORAL_MIDI_XML_HPP
|
||||
#define EVORAL_MIDI_XML_HPP
|
||||
|
||||
#include "evoral/Event.h"
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
namespace Evoral {
|
||||
namespace MIDIXML {
|
||||
|
||||
template<typename Time>
|
||||
bool
|
||||
xml_to_midi(const XMLNode& node, Evoral::Event<Time>& ev)
|
||||
{
|
||||
if (node.name() == "ControlChange") {
|
||||
ev.set_type(MIDI_CMD_CONTROL);
|
||||
ev.set_cc_number(atoi(node.property("Control")->value().c_str()));
|
||||
ev.set_cc_value(atoi(node.property("Value")->value().c_str()));
|
||||
return true;
|
||||
} else if (node.name() == "ProgramChange") {
|
||||
ev.set_type(MIDI_CMD_PGM_CHANGE);
|
||||
ev.set_pgm_number(atoi(node.property("Number")->value().c_str()));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Time>
|
||||
std::shared_ptr<XMLNode>
|
||||
midi_to_xml(const Evoral::Event<Time>& ev)
|
||||
{
|
||||
XMLNode* result = 0;
|
||||
|
||||
switch (ev.type()) {
|
||||
case MIDI_CMD_CONTROL:
|
||||
result = new XMLNode("ControlChange");
|
||||
result->add_property("Channel", long(ev.channel()));
|
||||
result->add_property("Control", long(ev.cc_number()));
|
||||
result->add_property("Value", long(ev.cc_value()));
|
||||
break;
|
||||
|
||||
case MIDI_CMD_PGM_CHANGE:
|
||||
result = new XMLNode("ProgramChange");
|
||||
result->add_property("Channel", long(ev.channel()));
|
||||
result->add_property("Number", long(ev.pgm_number()));
|
||||
break;
|
||||
|
||||
case MIDI_CMD_NOTE_ON:
|
||||
result = new XMLNode("NoteOn");
|
||||
result->add_property("Channel", long(ev.channel()));
|
||||
result->add_property("Note", long(ev.note()));
|
||||
result->add_property("Velocity", long(ev.velocity()));
|
||||
break;
|
||||
|
||||
case MIDI_CMD_NOTE_OFF:
|
||||
result = new XMLNode("NoteOff");
|
||||
result->add_property("Channel", long(ev.channel()));
|
||||
result->add_property("Note", long(ev.note()));
|
||||
result->add_property("Velocity", long(ev.velocity()));
|
||||
break;
|
||||
|
||||
case MIDI_CMD_BENDER:
|
||||
result = new XMLNode("PitchBendChange");
|
||||
result->add_property("Channel", long(ev.channel()));
|
||||
result->add_property("Value", long(ev.pitch_bender_value()));
|
||||
break;
|
||||
|
||||
default:
|
||||
return std::shared_ptr<XMLNode>();
|
||||
}
|
||||
|
||||
return std::shared_ptr<XMLNode>(result);
|
||||
}
|
||||
|
||||
} // namespace MIDIXML
|
||||
} // namespace Evoral
|
||||
|
||||
#endif // EVORAL_MIDI_XML_HPP
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2011 David Robillard <d@drobilla.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef EVORAL_SMF_READER_HPP
|
||||
#define EVORAL_SMF_READER_HPP
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "evoral/visibility.h"
|
||||
|
||||
namespace Evoral {
|
||||
|
||||
|
||||
/** Standard MIDI File (Type 0) Reader
|
||||
*
|
||||
* Currently this only reads SMF files with tempo-based timing.
|
||||
*/
|
||||
class LIBEVORAL_API SMFReader {
|
||||
public:
|
||||
class PrematureEOF : public std::exception {
|
||||
const char* what() const throw() { return "Unexpected end of file"; }
|
||||
};
|
||||
class CorruptFile : public std::exception {
|
||||
const char* what() const throw() { return "Corrupted file"; }
|
||||
};
|
||||
class UnsupportedTime : public std::exception {
|
||||
const char* what() const throw() { return "Unsupported time stamp type (SMPTE)"; }
|
||||
};
|
||||
|
||||
SMFReader(const std::string& filename="");
|
||||
~SMFReader();
|
||||
|
||||
bool open(const std::string& filename) throw (std::logic_error, UnsupportedTime);
|
||||
|
||||
bool seek_to_track(unsigned track) throw (std::logic_error);
|
||||
|
||||
const std::string& filename() const { return _filename; };
|
||||
|
||||
uint16_t type() const { return _type; }
|
||||
uint16_t ppqn() const { return _ppqn; }
|
||||
uint16_t num_tracks() const { return _num_tracks; }
|
||||
|
||||
int read_event(size_t buf_len,
|
||||
uint8_t* buf,
|
||||
uint32_t* ev_size,
|
||||
uint32_t* ev_delta_time)
|
||||
throw (std::logic_error, PrematureEOF, CorruptFile);
|
||||
|
||||
void close();
|
||||
|
||||
static uint32_t read_var_len(FILE* fd) throw (PrematureEOF);
|
||||
|
||||
protected:
|
||||
/** size of SMF header, including MTrk chunk header */
|
||||
static const uint32_t HEADER_SIZE = 22;
|
||||
|
||||
std::string _filename;
|
||||
FILE* _fd;
|
||||
uint16_t _type;
|
||||
uint16_t _ppqn;
|
||||
uint16_t _num_tracks;
|
||||
uint32_t _track;
|
||||
uint32_t _track_size;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Evoral
|
||||
|
||||
#endif // EVORAL_SMF_READER_HPP
|
||||
|
@ -696,10 +696,6 @@
|
||||
RelativePath="..\pbd\floating.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pbd\functor_command.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\msvc\getopt.h"
|
||||
>
|
||||
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2015 Paul Davis <paul@linuxaudiosystems.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "pbd/libpbd_visibility.h"
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/shiva.h"
|
||||
#include "pbd/command.h"
|
||||
#include "pbd/failed_constructor.h"
|
||||
|
||||
/** This command class is initialized
|
||||
*/
|
||||
|
||||
namespace PBD {
|
||||
|
||||
template <class obj_type, class arg_type>
|
||||
class /*LIBPBD_API*/ FunctorCommand : public PBD::Command
|
||||
{
|
||||
private:
|
||||
typedef void (obj_type::*functor_type)(arg_type);
|
||||
typedef std::map< std::string, functor_type > FunctorMap;
|
||||
typedef typename FunctorMap::iterator FunctorMapIterator;
|
||||
|
||||
public:
|
||||
FunctorCommand(std::string functor, obj_type& object, arg_type b, arg_type a)
|
||||
: functor_name(functor)
|
||||
, object(object)
|
||||
, before(b)
|
||||
, after(a)
|
||||
{
|
||||
method = find_functor(functor);
|
||||
|
||||
/* catch destruction of the object */
|
||||
new PBD::Shiva< obj_type, FunctorCommand<obj_type, arg_type> > (object, *this);
|
||||
}
|
||||
|
||||
~FunctorCommand() {
|
||||
GoingAway();
|
||||
}
|
||||
|
||||
void operator() () {
|
||||
(object.*method) (after);
|
||||
}
|
||||
|
||||
void undo() {
|
||||
(object.*method) (before);
|
||||
}
|
||||
|
||||
virtual XMLNode &get_state() {
|
||||
std::stringstream ss;
|
||||
|
||||
XMLNode *node = new XMLNode("FunctorCommand");
|
||||
node->add_property("type_name", typeid(obj_type).name());
|
||||
node->add_property("functor", functor_name);
|
||||
ss << before;
|
||||
node->add_property("before", ss.str());
|
||||
ss.clear ();
|
||||
ss << after;
|
||||
node->add_property("after", ss.str());
|
||||
|
||||
return *node;
|
||||
}
|
||||
|
||||
static void register_functor(std::string name, functor_type f) {
|
||||
functor_map[name] = f;
|
||||
}
|
||||
|
||||
private:
|
||||
static functor_type find_functor(std::string name) {
|
||||
FunctorMapIterator iter;
|
||||
|
||||
if((iter = functor_map.find(name)) == functor_map.end()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string functor_name;
|
||||
obj_type &object;
|
||||
arg_type before;
|
||||
arg_type after;
|
||||
functor_type method;
|
||||
static FunctorMap functor_map;
|
||||
};
|
||||
|
||||
// static initialization of functor_map...
|
||||
template <class obj_type, class arg_type>
|
||||
typename FunctorCommand<obj_type, arg_type>::FunctorMap
|
||||
FunctorCommand<obj_type, arg_type>::functor_map;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user