From e0ff70cf86c01c42f98faf8b0eaf1a8ccf867946 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 16 May 2016 07:30:28 -0400 Subject: first vaguely working version using PresentationInfo remote control ID and "order keys" have been removed. --- libs/ardour/ardour/audio_track.h | 2 +- libs/ardour/ardour/midi_track.h | 2 +- libs/ardour/ardour/mute_control.h | 1 + libs/ardour/ardour/presentation_info.h | 303 +++++++++++++++++++++++++++++++++ libs/ardour/ardour/route.h | 50 +----- libs/ardour/ardour/route_sorters.h | 44 ----- libs/ardour/ardour/session.h | 60 +++---- libs/ardour/ardour/stripable.h | 64 ++++++- libs/ardour/ardour/track.h | 2 +- 9 files changed, 396 insertions(+), 132 deletions(-) create mode 100644 libs/ardour/ardour/presentation_info.h delete mode 100644 libs/ardour/ardour/route_sorters.h (limited to 'libs/ardour/ardour') diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 17e2223680..d80042a252 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -34,7 +34,7 @@ class AudioFileSource; class LIBARDOUR_API AudioTrack : public Track { public: - AudioTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); + AudioTrack (Session&, std::string name, TrackMode m = Normal); ~AudioTrack (); int set_mode (TrackMode m); diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 69f4981047..f756812e71 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -37,7 +37,7 @@ class Session; class LIBARDOUR_API MidiTrack : public Track { public: - MidiTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); + MidiTrack (Session&, std::string name, TrackMode m = Normal); ~MidiTrack (); int init (); diff --git a/libs/ardour/ardour/mute_control.h b/libs/ardour/ardour/mute_control.h index 5332fd4fa7..36d5e112cc 100644 --- a/libs/ardour/ardour/mute_control.h +++ b/libs/ardour/ardour/mute_control.h @@ -25,6 +25,7 @@ #include "ardour/slavable_automation_control.h" +#include "ardour/mute_master.h" #include "ardour/libardour_visibility.h" namespace ARDOUR { diff --git a/libs/ardour/ardour/presentation_info.h b/libs/ardour/ardour/presentation_info.h new file mode 100644 index 0000000000..f7446a7713 --- /dev/null +++ b/libs/ardour/ardour/presentation_info.h @@ -0,0 +1,303 @@ +/* + Copyright (C) 2016 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 __libardour_presentation_info_h__ +#define __libardour_presentation_info_h__ + +#include +#include + +#include + +#include "ardour/libardour_visibility.h" + +class XMLNode; + +namespace ARDOUR { + +class LIBARDOUR_API PresentationInfo +{ + public: + + /* a PresentationInfo object exists to share information between + * different user interfaces (e.g. GUI and a Mackie Control surface) + * about: + * + * - ordering + * - selection status + * - visibility + * - object identity + * + * ORDERING + * + * One UI takes control of ordering by setting the "order" value for + * the PresentationInfo component of every Stripable object. In Ardour, + * this is done by the GUI (mostly because it is very hard for the user + * to re-order things on a control surface). + * + * Ordering is a complex beast, however. Different user interfaces may + * display things in different ways. For example, the GUI of Ardour + * allows the user to mix busses in between tracks. A control surface + * may do the same, but may also allow the user to press a button that + * makes it show only busses, or only MIDI tracks. At that point, the + * ordering on the surface differs from the ordering in the GUI. + * + * The ordering is given via a combination of an object type and a + * simple numeric position within that type. The object types at this + * time are: + * + * Route + * - object has inputs and outputs; processes data + * Output + * - Route used to connect to outside the application (MasterOut, MonitorOut) + * Special + * - special type of Route (e.g. Auditioner) + * VCA + * - no data flows through; control only + * + * Objects with a numeric order of zero are considered unsorted. This + * applies (for now) to special objects such as the master out, + * auditioner and monitor out. The rationale here is that the GUI + * presents these objects in special ways, rather than as part of some + * (potentially) re-orderable container. The same is true for hardware + * surfaces, where the master fader (for instance) is typically + * separate and distinct from anything else. + * + * There are several pathways for the order being set: + * + * - object created during session loading from XML + * - numeric order will be set during ::set_state(), based on + * - type will be set during ctor call + * + * - object created in response to user request + * - numeric order will be set by Session, before adding + * to container. + * - type set during ctor call + * + * + * OBJECT IDENTITY + * + * Control surfaces/protocols often need to be able to get a handle on + * an object identified only abstractly, such as the "5th audio track" + * or "the master out". A PresentationInfo object uniquely identifies + * all objects in this way through the combination of its _order member + * and part of its _flags member. The _flags member identifies the type + * of object, as well as selection/hidden status. The type may never + * change after construction (not strictly the constructor itself, but + * a more generalized notion of construction, as in "ready to use"). + * + * SELECTION + * + * When an object is selected, its _flags member will have the Selected + * bit set. + * + * VISIBILITY + * + * When an object is hidden, its _flags member will have the Hidden + * bit set. + * + * + */ + + + enum Flag { + /* Type information */ + AudioTrack = 0x1, + MidiTrack = 0x2, + AudioBus = 0x4, + MidiBus = 0x8, + VCA = 0x10, + + /* These need to be at the high end */ + MasterOut = 0x800, + MonitorOut = 0x1000, + Auditioner = 0x2000, + + /* These are for sharing Stripable states between the GUI and other + * user interfaces/control surfaces + */ + Selected = 0x4000, + Hidden = 0x8000, + + /* single bit indicates that the group order is set */ + GroupOrderSet = 0x100000000, + + /* Masks */ + + GroupMask = (AudioTrack|MidiTrack|AudioBus|MidiBus|VCA), + SpecialMask = (MasterOut|MonitorOut|Auditioner), + StatusMask = (Selected|Hidden), + }; + + static const Flag Route; + static const Flag Track; + static const Flag Bus; + + typedef uint32_t order_t; + typedef uint64_t global_order_t; + + PresentationInfo (Flag f) : _order (0), _flags (Flag (f & ~GroupOrderSet)) { /* GroupOrderSet is not set */ } + PresentationInfo (order_t o, Flag f) : _order (o), _flags (Flag (f | GroupOrderSet)) { /* GroupOrderSet is set */ } + + static const order_t max_order; + + order_t group_order() const { return _order; } + global_order_t global_order () const { + if (_flags & Route) { + + /* set all bits related to Route so that all Routes + sort together, with order() in the range of + 64424509440..68719476735 + + Consider the following arrangement: + + Track 1 + Bus 1 + Track 2 + --------- + VCA 1 + --------- + Master + --------- + Monitor + + these translate into the following + + _order | _flags | order() + -------------------------------------- + 1 | 0x1 AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|1 = 64424509441 + 2 | 0x2 AudioBus | ((0x1|0x2|0x4|0x8)<<32)|2 = 64424509442 + 3 | 0x1 AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|3 = 64424509443 + + 1 | 0x10 VCA | ((0x10)<<32)|1 = 68719476737 + + 0 | 0x800 Master | (0x800<<32) = 8796093022208 + + 0 | 0x1000 Monitor | (0x1000<<32) = 17592186044416 + + */ + + return (((global_order_t) (_flags | Route)) << sizeof(order_t)) | _order; + } else { + return (((global_order_t) _flags) << sizeof(order_t)) | _order; + } + } + + PresentationInfo::Flag flags() const { return _flags; } + + bool order_set() const { return _order != 0; } + + /* these objects have no defined order */ + bool special () const { return _flags & SpecialMask; } + + /* detect group order set/not set */ + bool unordered() const { return !(_flags & GroupOrderSet); } + bool ordered() const { return _flags & GroupOrderSet; } + + void set_flag (PresentationInfo::Flag f) { + _flags = PresentationInfo::Flag (_flags | f); + } + + void unset_flag (PresentationInfo::Flag f) { + _flags = PresentationInfo::Flag (_flags & ~f); + } + + void set_flags (Flag f) { + _flags = f; + } + + bool flag_match (Flag f) const { + /* no flags, match all */ + + if (f == Flag (0)) { + return true; + } + + if (f & StatusMask) { + /* status bits set, must match them */ + if ((_flags & StatusMask) != (f & StatusMask)) { + return false; + } + } + + /* Generic flags in f, match the right stuff */ + + if (f == Bus && (_flags & Bus)) { + /* some kind of bus */ + return true; + } + if (f == Track && (_flags & Track)) { + /* some kind of track */ + return true; + } + if (f == Route && (_flags & Route)) { + /* any kind of route */ + return true; + } + + return f == _flags; + } + + std::string to_string () const; + + uint64_t to_integer () const { + return ((uint64_t) _flags << sizeof(order_t)) | _order; + } + + bool operator< (PresentationInfo const& other) const { + return global_order() < other.global_order(); + } + + PresentationInfo& operator= (std::string const& str) { + parse (str); + return *this; + } + + bool match (PresentationInfo const& other) const { + return (_order == other.group_order()) && flag_match (other.flags()); + } + + bool operator==(PresentationInfo const& other) { + return (_order == other.group_order()) && (_flags == other.flags()); + } + + bool operator!=(PresentationInfo const& other) { + return (_order != other.group_order()) || (_flags != other.flags()); + } + + static Flag get_flags (XMLNode const& node); + + protected: + friend class Stripable; + void set_group_order (order_t order) { _order = order; _flags = Flag (_flags|GroupOrderSet); } + + private: + order_t _order; + Flag _flags; + + PresentationInfo (std::string const & str); + int parse (std::string const&); + int parse (order_t, Flag f); +}; + +} + +std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid); + +#endif /* __libardour_presentation_info_h__ */ diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 2e2c1ccf72..7a6b504368 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -97,13 +97,7 @@ public: typedef std::list > ProcessorList; - enum Flag { - Auditioner = 0x1, - MasterOut = 0x2, - MonitorOut = 0x4 - }; - - Route (Session&, std::string name, Flag flags = Flag(0), DataType default_type = DataType::AUDIO); + Route (Session&, std::string name, PresentationInfo::Flag flags = PresentationInfo::Flag(0), DataType default_type = DataType::AUDIO); virtual ~Route(); virtual int init (); @@ -127,14 +121,6 @@ public: bool set_name (const std::string& str); static void set_name_in_state (XMLNode &, const std::string &, bool rename_playlist = true); - uint32_t order_key () const; - bool has_order_key () const; - void set_order_key (uint32_t); - - bool is_auditioner() const { return _flags & Auditioner; } - bool is_master() const { return _flags & MasterOut; } - bool is_monitor() const { return _flags & MonitorOut; } - MonitorState monitoring_state () const; virtual MeterState metering_state () const; @@ -569,28 +555,6 @@ public: void protect_automation (); - enum { - /* These numbers are taken from MIDI Machine Control, - which can only control up to 317 tracks without - doing sysex segmentation. - */ - MasterBusRemoteControlID = 318, - MonitorBusRemoteControlID = 319, - }; - - void set_remote_control_id (uint32_t id, bool notify_class_listeners = true); - uint32_t remote_control_id () const; - void set_remote_control_id_explicit (uint32_t order_key); - - /* for things concerned about *this* route's RID */ - - PBD::Signal0 RemoteControlIDChanged; - - /* for things concerned about *any* route's RID changes */ - - static PBD::Signal0 RemoteControlIDChange; - static PBD::Signal0 SyncOrderKeys; - bool has_external_redirects() const; /* can only be executed by a route for which is_monitor() is true @@ -663,7 +627,6 @@ public: gint _pending_process_reorder; // atomic gint _pending_signals; // atomic - Flag _flags; int _pending_declick; MeterPoint _meter_point; MeterPoint _pending_meter_point; @@ -718,16 +681,12 @@ protected: boost::shared_ptr the_instrument_unlocked() const; -private: + private: + int64_t _track_number; + int set_state_2X (const XMLNode&, int); void set_processor_state_2X (XMLNodeList const &, int); - uint32_t _order_key; - bool _has_order_key; - uint32_t _remote_control_id; - - int64_t _track_number; - void input_change_handler (IOChange, void *src); void output_change_handler (IOChange, void *src); void sidechain_change_handler (IOChange, void *src); @@ -810,7 +769,6 @@ private: void reset_instrument_info (); - void set_remote_control_id_internal (uint32_t id, bool notify_class_listeners = true); void solo_control_changed (bool self, PBD::Controllable::GroupControlDisposition); }; diff --git a/libs/ardour/ardour/route_sorters.h b/libs/ardour/ardour/route_sorters.h deleted file mode 100644 index 022d5a24c3..0000000000 --- a/libs/ardour/ardour/route_sorters.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2000-2014 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 __libardour_route_sorters_h__ -#define __libardour_route_sorters_h__ - -#include "ardour/route.h" - -namespace ARDOUR { - -struct SignalOrderRouteSorter { - bool operator() (boost::shared_ptr a, boost::shared_ptr b) { - if (a->is_master() || a->is_monitor()) { - /* "a" is a special route (master, monitor, etc), and comes - * last in the mixer ordering - */ - return false; - } else if (b->is_master() || b->is_monitor()) { - /* everything comes before b */ - return true; - } - return a->order_key () < b->order_key (); - } -}; - -} // namespace - -#endif /* __libardour_route_sorters_h__ */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 6f2c0f1fa9..f3a11a953c 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -64,11 +64,13 @@ #include "ardour/luascripting.h" #include "ardour/location.h" #include "ardour/monitor_processor.h" +#include "ardour/presentation_info.h" #include "ardour/rc_configuration.h" #include "ardour/session_configuration.h" #include "ardour/session_event.h" #include "ardour/interpolation.h" #include "ardour/plugin.h" +#include "ardour/presentation_info.h" #include "ardour/route.h" #include "ardour/route_graph.h" @@ -215,8 +217,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop PBD::Signal0 DirtyChanged; - PBD::Signal1 RouteAddedOrRemoved; - const SessionDirectory& session_directory () const { return *(_session_dir.get()); } static PBD::Signal1 Dialog; @@ -293,22 +293,20 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop bool operator() (boost::shared_ptr, boost::shared_ptr b); }; - void set_order_hint (int32_t order_hint) {_order_hint = order_hint;}; - void notify_remote_id_change (); - void sync_order_keys (); + void notify_presentation_info_change (); template void foreach_route (T *obj, void (T::*func)(Route&), bool sort = true); template void foreach_route (T *obj, void (T::*func)(boost::shared_ptr), bool sort = true); template void foreach_route (T *obj, void (T::*func)(Route&, A), A arg, bool sort = true); static char session_name_is_legal (const std::string&); - bool io_name_is_legal (const std::string&); - boost::shared_ptr route_by_name (std::string); - boost::shared_ptr route_by_id (PBD::ID); - boost::shared_ptr route_by_remote_id (uint32_t id); - boost::shared_ptr stripable_by_remote_id (uint32_t id); - boost::shared_ptr route_by_selected_count (uint32_t cnt); - boost::shared_ptr track_by_diskstream_id (PBD::ID); + bool io_name_is_legal (const std::string&) const; + boost::shared_ptr route_by_name (std::string) const; + boost::shared_ptr route_by_id (PBD::ID) const; + boost::shared_ptr get_remote_nth_stripable (uint16_t n, PresentationInfo::Flag) const; + boost::shared_ptr get_remote_nth_route (uint16_t n) const; + boost::shared_ptr route_by_selected_count (uint32_t cnt) const; + boost::shared_ptr track_by_diskstream_id (PBD::ID) const; void routes_using_input_from (const std::string& str, RouteList& rl); bool route_name_unique (std::string) const; @@ -595,29 +593,24 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop std::list > new_audio_track ( int input_channels, int output_channels, - TrackMode mode = Normal, - RouteGroup* route_group = 0, - uint32_t how_many = 1, - std::string name_template = "" - ); - - RouteList new_audio_route ( - int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template = "" + RouteGroup* route_group, + uint32_t how_many, + std::string name_template, + PresentationInfo::order_t order, + TrackMode mode = Normal ); std::list > new_midi_track ( const ChanCount& input, const ChanCount& output, - boost::shared_ptr instrument = boost::shared_ptr(), - TrackMode mode = Normal, - RouteGroup* route_group = 0, uint32_t how_many = 1, std::string name_template = "", - Plugin::PresetRecord* pset = 0 + boost::shared_ptr instrument, + Plugin::PresetRecord* pset = 0, + RouteGroup* route_group, uint32_t how_many, std::string name_template, + PresentationInfo::order_t, + TrackMode mode = Normal ); - RouteList new_midi_route (RouteGroup* route_group, - uint32_t how_many, - std::string name_template = "", - boost::shared_ptr instrument = boost::shared_ptr(), - Plugin::PresetRecord* pset = 0); + RouteList new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template, PresentationInfo::Flag, PresentationInfo::order_t); + RouteList new_midi_route (RouteGroup* route_group, uint32_t how_many, std::string name_template, boost::shared_ptr instrument, Plugin::PresetRecord*, PresentationInfo::Flag, PresentationInfo::order_t); void remove_routes (boost::shared_ptr); void remove_route (boost::shared_ptr); @@ -1658,8 +1651,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop SerializedRCUManager routes; - void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save); - void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect); + void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t); + void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t); bool _adding_routes_in_progress; bool _reconnecting_routes_in_progress; bool _route_deletion_in_progress; @@ -1976,8 +1969,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop */ GraphEdges _current_route_graph; - uint32_t next_control_id () const; - int32_t _order_hint; + void ensure_presentation_info_gap (PresentationInfo::order_t, uint32_t gap_size); bool ignore_route_processor_changes; MidiClockTicker* midi_clock; @@ -2005,6 +1997,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop std::string _template_state_dir; VCAManager* _vca_manager; + + boost::shared_ptr get_midi_nth_route_by_id (PresentationInfo::order_t n) const; }; diff --git a/libs/ardour/ardour/stripable.h b/libs/ardour/ardour/stripable.h index cee6075a51..1b82397074 100644 --- a/libs/ardour/ardour/stripable.h +++ b/libs/ardour/ardour/stripable.h @@ -26,7 +26,11 @@ #include #include +#include "pbd/signals.h" + +#include "ardour/presentation_info.h" #include "ardour/session_object.h" +#include "ardour/libardour_visibility.h" namespace ARDOUR { @@ -46,18 +50,44 @@ class MonitorControl; * and behaviour of the object. */ -class Stripable : public SessionObject { +class LIBARDOUR_API Stripable : public SessionObject { public: - Stripable (Session& session, const std::string& name) - : SessionObject (session, name) {} + Stripable (Session& session, std::string const & name, PresentationInfo const &); + virtual ~Stripable () {} /* XXX midi on/off - selected status - visible/hidden */ - virtual uint32_t remote_control_id () const = 0; + bool is_auditioner() const { return _presentation_info.flags() & PresentationInfo::Auditioner; } + bool is_master() const { return _presentation_info.flags() & PresentationInfo::MasterOut; } + bool is_monitor() const { return _presentation_info.flags() & PresentationInfo::MonitorOut; } + + int set_state (XMLNode const&, int); + + bool is_hidden() const { return _presentation_info.flags() & PresentationInfo::Hidden; } + bool is_selected() const { return _presentation_info.flags() & PresentationInfo::Selected; } + + PresentationInfo const & presentation_info () const { return _presentation_info; } + PresentationInfo& presentation_info () { return _presentation_info; } + + /* set just the order */ + + void set_presentation_group_order (PresentationInfo::order_t, bool notify_class_listeners = true); + void set_presentation_group_order_explicit (PresentationInfo::order_t); + + /* for things concerned about *this* route's RID */ + + PBD::Signal0 PresentationInfoChanged; + + /* for things concerned about *any* route's RID changes */ + + static PBD::Signal0 PresentationInfoChange; + + /*************************************************************** + * Pure interface begins here + ***************************************************************/ + virtual boost::shared_ptr peak_meter() = 0; virtual boost::shared_ptr peak_meter() const = 0; @@ -140,6 +170,28 @@ class Stripable : public SessionObject { virtual boost::shared_ptr master_send_enable_controllable () const = 0; virtual bool muted_by_others_soloing () const = 0; + + protected: + PresentationInfo _presentation_info; + + /* set the entire info. This should only be used in cases where the + * derived could not supply the correct Flag and/or order information + * in its constructor. + */ + + void set_presentation_info (PresentationInfo id, bool notify_class_listeners = true); + void set_presentation_info_explicit (PresentationInfo); + + void add_state (XMLNode&) const; + + private: + void set_presentation_info_internal (PresentationInfo id, bool notify_class_listeners = true); +}; + +struct PresentationInfoSorter { + bool operator() (boost::shared_ptr a, boost::shared_ptr b) { + return a->presentation_info() < b->presentation_info(); + } }; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index bb955265c8..d57e0a2b5a 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -45,7 +45,7 @@ class MonitorControl; class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskstream { public: - Track (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO); + Track (Session&, std::string name, PresentationInfo::Flag f = PresentationInfo::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO); virtual ~Track (); int init (); -- cgit v1.2.3