summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-04-21 20:42:22 +0000
committerCarl Hetherington <carl@carlh.net>2010-04-21 20:42:22 +0000
commit061a85191c301ac18f2e8ca59d43127a4499ba96 (patch)
tree469688f4dea1853c91372319a899b2efc71b30d5 /libs/ardour
parentd9cebc2edf8accded23c6f2a1caab73eb47a50fd (diff)
Move Diskstream ownership to Track, so that Session no longer holds lists of Diskstreams. Breaks 3.0 file format again.
git-svn-id: svn://localhost/ardour2/branches/3.0@6945 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h2
-rw-r--r--libs/ardour/ardour/audio_track.h3
-rw-r--r--libs/ardour/ardour/diskstream.h26
-rw-r--r--libs/ardour/ardour/midi_diskstream.h2
-rw-r--r--libs/ardour/ardour/midi_track.h3
-rw-r--r--libs/ardour/ardour/playlist.h1
-rwxr-xr-xlibs/ardour/ardour/public_diskstream.h80
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/session.h51
-rw-r--r--libs/ardour/ardour/session_event.h2
-rw-r--r--libs/ardour/ardour/track.h67
-rw-r--r--libs/ardour/audio_diskstream.cc17
-rw-r--r--libs/ardour/audio_track.cc69
-rw-r--r--libs/ardour/audio_track_importer.cc3
-rw-r--r--libs/ardour/butler.cc37
-rw-r--r--libs/ardour/diskstream.cc37
-rw-r--r--libs/ardour/enums.cc2
-rw-r--r--libs/ardour/midi_diskstream.cc13
-rw-r--r--libs/ardour/midi_track.cc63
-rw-r--r--libs/ardour/playlist.cc4
-rw-r--r--libs/ardour/session.cc314
-rw-r--r--libs/ardour/session_butler.cc20
-rw-r--r--libs/ardour/session_export.cc10
-rw-r--r--libs/ardour/session_process.cc37
-rw-r--r--libs/ardour/session_state.cc213
-rw-r--r--libs/ardour/session_transport.cc244
-rw-r--r--libs/ardour/track.cc298
27 files changed, 981 insertions, 639 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 0a8a7a0a8e..6cf064a61d 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -228,7 +228,7 @@ class AudioDiskstream : public Diskstream
ChannelInfo* channel_info, int channel, bool reversed);
void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>);
- void transport_stopped (struct tm&, time_t, bool abort);
+ void transport_stopped_wallclock (struct tm&, time_t, bool abort);
void transport_looped (nframes_t transport_frame);
void init ();
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 0c4f29ee86..d74f5e53b9 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -28,6 +28,7 @@ class Session;
class AudioDiskstream;
class AudioPlaylist;
class RouteGroup;
+class AudioFileSource;
class AudioTrack : public Track
{
@@ -56,6 +57,8 @@ class AudioTrack : public Track
int set_state(const XMLNode&, int version);
+ boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0);
+
protected:
XMLNode& state (bool full);
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index da6297e0fb..97a512cf3f 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -37,6 +37,7 @@
#include "ardour/session_object.h"
#include "ardour/types.h"
#include "ardour/utils.h"
+#include "ardour/public_diskstream.h"
struct tm;
@@ -46,10 +47,10 @@ class IO;
class Playlist;
class Processor;
class Region;
-class Route;
class Session;
+class Track;
-class Diskstream : public SessionObject
+class Diskstream : public SessionObject, public PublicDiskstream
{
public:
enum Flag {
@@ -66,7 +67,7 @@ class Diskstream : public SessionObject
bool set_name (const std::string& str);
boost::shared_ptr<ARDOUR::IO> io() const { return _io; }
- void set_route (ARDOUR::Route&);
+ void set_track (ARDOUR::Track *);
virtual float playback_buffer_load() const = 0;
virtual float capture_buffer_load() const = 0;
@@ -99,7 +100,6 @@ class Diskstream : public SessionObject
virtual void punch_in() {}
virtual void punch_out() {}
- void set_speed (double);
void non_realtime_set_speed ();
virtual void non_realtime_locate (nframes_t /*location*/) {};
virtual void playlist_modified ();
@@ -143,6 +143,14 @@ class Diskstream : public SessionObject
void move_processor_automation (boost::weak_ptr<Processor>,
std::list<Evoral::RangeMove<framepos_t> > const &);
+ /** For non-butler contexts (allocates temporary working buffers) */
+ virtual int do_refill_with_alloc() = 0;
+ virtual void set_block_size (nframes_t) = 0;
+
+ bool pending_overwrite () const {
+ return _pending_overwrite;
+ }
+
PBD::Signal0<void> RecordEnableChanged;
PBD::Signal0<void> SpeedChanged;
PBD::Signal0<void> ReverseChanged;
@@ -163,7 +171,6 @@ class Diskstream : public SessionObject
virtual void set_pending_overwrite (bool) = 0;
virtual int overwrite_existing_buffers () = 0;
- virtual void set_block_size (nframes_t) = 0;
virtual int internal_playback_seek (nframes_t distance) = 0;
virtual int can_internal_playback_seek (nframes_t distance) = 0;
virtual int rename_write_sources () = 0;
@@ -199,16 +206,13 @@ class Diskstream : public SessionObject
virtual int do_flush (RunContext context, bool force = false) = 0;
virtual int do_refill () = 0;
- /** For non-butler contexts (allocates temporary working buffers) */
- virtual int do_refill_with_alloc() = 0;
-
/* XXX fix this redundancy ... */
virtual void playlist_changed (const PBD::PropertyChange&);
virtual void playlist_deleted (boost::weak_ptr<Playlist>);
virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &);
- virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
+ virtual void transport_stopped_wallclock (struct tm&, time_t, bool abort) = 0;
virtual void transport_looped (nframes_t transport_frame) = 0;
struct CaptureInfo {
@@ -245,7 +249,7 @@ class Diskstream : public SessionObject
uint32_t i_am_the_modifier;
boost::shared_ptr<ARDOUR::IO> _io;
- Route* _route;
+ Track* _track;
ChanCount _n_channels;
boost::shared_ptr<Playlist> _playlist;
@@ -273,7 +277,7 @@ class Diskstream : public SessionObject
Location* loop_location;
nframes_t overwrite_frame;
off_t overwrite_offset;
- bool pending_overwrite;
+ bool _pending_overwrite;
bool overwrite_queued;
IOChange input_change_pending;
nframes_t wrap_buffer_size;
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index 81f2979f3f..abbfc28feb 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -151,7 +151,7 @@ class MidiDiskstream : public Diskstream
int read (nframes_t& start, nframes_t cnt, bool reversed);
void finish_capture (bool rec_monitors_input);
- void transport_stopped (struct tm&, time_t, bool abort);
+ void transport_stopped_wallclock (struct tm&, time_t, bool abort);
void transport_looped (nframes_t transport_frame);
void init ();
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index f4f29398b2..0399492a02 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -31,6 +31,7 @@ class Session;
class MidiDiskstream;
class MidiPlaylist;
class RouteGroup;
+class SMFSource;
class MidiTrack : public Track
{
@@ -90,6 +91,8 @@ public:
bool midi_thru() const { return _midi_thru; }
void set_midi_thru (bool yn);
+ boost::shared_ptr<SMFSource> write_source (uint32_t n = 0);
+
protected:
XMLNode& state (bool full);
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index d9a14c01fd..c5b79644c6 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -195,6 +195,7 @@ class Playlist : public SessionObject
uint32_t read_data_count() const { return _read_data_count; }
+ /* XXX: use of diskstream here is a little unfortunate */
const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; }
void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; }
diff --git a/libs/ardour/ardour/public_diskstream.h b/libs/ardour/ardour/public_diskstream.h
new file mode 100755
index 0000000000..90ca030af1
--- /dev/null
+++ b/libs/ardour/ardour/public_diskstream.h
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2010 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_public_diskstream_h__
+#define __ardour_public_diskstream_h__
+
+namespace ARDOUR {
+
+class Playlist;
+class Region;
+class Location;
+
+/** Public interface to a Diskstream */
+class PublicDiskstream
+{
+public:
+
+ virtual boost::shared_ptr<Playlist> playlist () = 0;
+ virtual void monitor_input (bool) = 0;
+ virtual bool destructive () const = 0;
+ virtual std::list<boost::shared_ptr<Region> > & last_capture_regions () = 0;
+ virtual void set_capture_offset () = 0;
+ virtual void reset_write_sources (bool, bool force = false) = 0;
+ virtual float playback_buffer_load () const = 0;
+ virtual float capture_buffer_load () const = 0;
+ virtual int do_refill () = 0;
+ virtual int do_flush (RunContext, bool force = false) = 0;
+ virtual uint32_t read_data_count() const = 0;
+ virtual uint32_t write_data_count() const = 0;
+ virtual void set_pending_overwrite (bool) = 0;
+ virtual int seek (nframes_t, bool complete_refill = false) = 0;
+ virtual bool hidden () const = 0;
+ virtual int can_internal_playback_seek (nframes_t) = 0;
+ virtual int internal_playback_seek (nframes_t) = 0;
+ virtual void non_realtime_input_change () = 0;
+ virtual void non_realtime_locate (nframes_t) = 0;
+ virtual void non_realtime_set_speed () = 0;
+ virtual int overwrite_existing_buffers () = 0;
+ virtual nframes_t get_captured_frames (uint32_t n = 0) = 0;
+ virtual int set_loop (Location *) = 0;
+ virtual void transport_looped (nframes_t) = 0;
+ virtual bool realtime_set_speed (double, bool) = 0;
+ virtual void transport_stopped_wallclock (struct tm &, time_t, bool) = 0;
+ virtual bool pending_overwrite () const = 0;
+ virtual double speed () const = 0;
+ virtual void prepare_to_stop (framepos_t) = 0;
+ virtual void set_slaved (bool) = 0;
+ virtual ChanCount n_channels () = 0;
+ virtual nframes_t get_capture_start_frame (uint32_t n = 0) = 0;
+ virtual AlignStyle alignment_style () const = 0;
+ virtual void set_record_enabled (bool) = 0;
+ virtual nframes_t current_capture_start () const = 0;
+ virtual nframes_t current_capture_end () const = 0;
+ virtual void playlist_modified () = 0;
+ virtual int use_playlist (boost::shared_ptr<Playlist>) = 0;
+ virtual void set_align_style (AlignStyle) = 0;
+ virtual int use_copy_playlist () = 0;
+ virtual int use_new_playlist () = 0;
+
+};
+
+}
+
+#endif
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index ae514e2f18..f9ba1a8e8a 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -338,10 +338,10 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
void catch_up_on_solo_mute_override ();
void mod_solo_by_others (int32_t);
- void set_block_size (nframes_t nframes);
bool has_external_redirects() const;
void curve_reallocate ();
void just_meter_input (sframes_t start_frame, sframes_t end_frame, nframes_t nframes);
+ virtual void set_block_size (nframes_t nframes);
protected:
nframes_t check_initial_delay (nframes_t, nframes_t&);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index ed1dc68f43..e2f3ff1625 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -77,7 +77,6 @@ namespace Evoral {
namespace ARDOUR {
-class AudioDiskstream;
class AudioEngine;
class AudioFileSource;
class AudioRegion;
@@ -96,7 +95,6 @@ class ExportStatus;
class IO;
class IOProcessor;
class ImportStatus;
-class MidiDiskstream;
class MidiRegion;
class MidiSource;
class MidiTrack;
@@ -121,6 +119,7 @@ class Slave;
class Source;
class TempoMap;
class VSTPlugin;
+class Track;
extern void setup_enum_writer ();
@@ -193,26 +192,18 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
- void add_diskstream (boost::shared_ptr<Diskstream>);
- boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id);
- boost::shared_ptr<Diskstream> diskstream_by_name (std::string name);
- bool have_rec_enabled_diskstream () const;
+ bool have_rec_enabled_track () const;
bool have_captured() const { return _have_captured; }
- void refill_all_diskstream_buffers ();
+ void refill_all_track_buffers ();
Butler* butler() { return _butler; }
void butler_transport_work ();
- uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
- uint32_t n_diskstreams() const;
-
void refresh_disk_space ();
- typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
-
- SerializedRCUManager<DiskstreamList>& diskstream_list() { return diskstreams; }
-
+ int load_diskstreams_2X (XMLNode const &, int);
+
int load_routes (const XMLNode&, int);
boost::shared_ptr<RouteList> get_routes() const {
return routes.reader ();
@@ -307,8 +298,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void use_rf_shuttle_speed ();
void allow_auto_play (bool yn);
void request_transport_speed (double speed);
- void request_overwrite_buffer (Diskstream*);
- void request_diskstream_speed (Diskstream&, double speed);
+ void request_overwrite_buffer (Track *);
+ void request_track_speed (Track *, double speed);
void request_input_change_handling ();
bool locate_pending() const { return static_cast<bool>(post_transport_work()&PostTransportLocate); }
@@ -542,9 +533,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
*/
static PBD::Signal0<int> AskAboutPendingState;
- boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
+ boost::shared_ptr<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t, bool);
- boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+ boost::shared_ptr<MidiSource> create_midi_source_for_session (std::string const &);
boost::shared_ptr<Source> source_by_id (const PBD::ID&);
boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
@@ -932,7 +923,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
PBD::ScopedConnection export_freewheel_connection;
- void get_diskstream_statistics ();
+ void get_track_statistics ();
int process_routes (nframes_t, bool& need_butler);
int silent_process_routes (nframes_t, bool& need_butler);
@@ -1174,13 +1165,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void set_play_loop (bool yn);
void unset_play_loop ();
- void overwrite_some_buffers (Diskstream*);
+ void overwrite_some_buffers (Track *);
void flush_all_inserts ();
int micro_locate (nframes_t distance);
void locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
void start_locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
void force_locate (nframes64_t frame, bool with_roll = false);
- void set_diskstream_speed (Diskstream*, double speed);
+ void set_track_speed (Track *, double speed);
void set_transport_speed (double speed, bool abort = false, bool clear_state = false);
void stop_transport (bool abort = false, bool clear_state = false);
void start_transport ();
@@ -1203,12 +1194,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
std::list<RouteGroup *> _route_groups;
- /* disk-streams */
-
- SerializedRCUManager<DiskstreamList> diskstreams;
-
- int load_diskstreams (const XMLNode&);
-
/* routes stuff */
SerializedRCUManager<RouteList> routes;
@@ -1217,6 +1202,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
uint32_t destructive_index;
boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int);
+ boost::shared_ptr<Route> XMLRouteFactory_2X (const XMLNode&, int);
void route_processors_changed (RouteProcessorChange);
@@ -1265,7 +1251,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void remove_playlist (boost::weak_ptr<Playlist>);
void playlist_length_changed ();
- void diskstream_playlist_changed (boost::weak_ptr<Diskstream>);
+ void track_playlist_changed (boost::weak_ptr<Track>);
/* NAMED SELECTIONS */
@@ -1342,7 +1328,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
XMLNode* _bundle_xml_node;
int load_bundles (XMLNode const &);
- void reverse_diskstream_buffers ();
+ void reverse_track_buffers ();
UndoHistory _history;
std::stack<UndoTransaction*> _current_trans;
@@ -1436,8 +1422,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
mutable bool have_looped; ///< Used in ::audible_frame(*)
- void update_have_rec_enabled_diskstream ();
- gint _have_rec_enabled_diskstream;
+ void update_have_rec_enabled_track ();
+ gint _have_rec_enabled_track;
static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
@@ -1450,6 +1436,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_record_enable (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+
+ /** temporary list of Diskstreams used only during load of 2.X sessions */
+ std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/session_event.h b/libs/ardour/ardour/session_event.h
index 2306bb7c1a..726c5be47b 100644
--- a/libs/ardour/ardour/session_event.h
+++ b/libs/ardour/ardour/session_event.h
@@ -19,7 +19,7 @@ class Region;
struct SessionEvent {
enum Type {
SetTransportSpeed,
- SetDiskstreamSpeed,
+ SetTrackSpeed,
Locate,
LocateRoll,
LocateRollLocate,
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index c05d222cc2..a40b82916b 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -22,16 +22,17 @@
#include <boost/shared_ptr.hpp>
#include "ardour/route.h"
+#include "ardour/public_diskstream.h"
namespace ARDOUR {
class Session;
-class Diskstream;
class Playlist;
class RouteGroup;
class Region;
+class Diskstream;
-class Track : public Route
+class Track : public Route, public PublicDiskstream
{
public:
Track (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
@@ -60,10 +61,8 @@ class Track : public Route
bool can_record();
- boost::shared_ptr<Diskstream> diskstream() const { return _diskstream; }
-
virtual void use_new_diskstream () = 0;
- virtual void set_diskstream (boost::shared_ptr<Diskstream>) = 0;
+ virtual void set_diskstream (boost::shared_ptr<Diskstream>);
nframes_t update_total_latency();
void set_latency_delay (nframes_t);
@@ -92,8 +91,60 @@ class Track : public Route
bool record_enabled() const;
void set_record_enable (bool yn, void *src);
+ /* XXX: unfortunate that this is exposed */
+ PBD::ID const & diskstream_id () const;
+
+ void set_block_size (nframes_t);
+
+ /* PublicDiskstream interface */
+ boost::shared_ptr<Playlist> playlist ();
+ void monitor_input (bool);
+ bool destructive () const;
+ std::list<boost::shared_ptr<Region> > & last_capture_regions ();
+ void set_capture_offset ();
+ void reset_write_sources (bool, bool force = false);
+ float playback_buffer_load () const;
+ float capture_buffer_load () const;
+ int do_refill ();
+ int do_flush (RunContext, bool force = false);
+ uint32_t read_data_count() const;
+ uint32_t write_data_count() const;
+ void set_pending_overwrite (bool);
+ int seek (nframes_t, bool complete_refill = false);
+ bool hidden () const;
+ int can_internal_playback_seek (nframes_t);
+ int internal_playback_seek (nframes_t);
+ void non_realtime_input_change ();
+ void non_realtime_locate (nframes_t);
+ void non_realtime_set_speed ();
+ int overwrite_existing_buffers ();
+ nframes_t get_captured_frames (uint32_t n = 0);
+ int set_loop (Location *);
+ void transport_looped (nframes_t);
+ bool realtime_set_speed (double, bool);
+ void transport_stopped_wallclock (struct tm &, time_t, bool);
+ bool pending_overwrite () const;
+ double speed () const;
+ void prepare_to_stop (framepos_t);
+ void set_slaved (bool);
+ ChanCount n_channels ();
+ nframes_t get_capture_start_frame (uint32_t n = 0);
+ AlignStyle alignment_style () const;
+ void set_record_enabled (bool);
+ nframes_t current_capture_start () const;
+ nframes_t current_capture_end () const;
+ void playlist_modified ();
+ int use_playlist (boost::shared_ptr<Playlist>);
+ void set_align_style (AlignStyle);
+ int use_copy_playlist ();
+ int use_new_playlist ();
+
PBD::Signal0<void> DiskstreamChanged;
PBD::Signal0<void> FreezeChange;
+ PBD::Signal0<void> PlaylistChanged;
+ PBD::Signal0<void> RecordEnableChanged;
+ PBD::Signal0<void> SpeedChanged;
+ PBD::Signal0<void> AlignmentStyleChanged;
protected:
virtual XMLNode& state (bool full) = 0;
@@ -144,6 +195,12 @@ class Track : public Route
bool _destructive;
boost::shared_ptr<RecEnableControllable> _rec_enable_control;
+
+private:
+ void diskstream_playlist_changed ();
+ void diskstream_record_enable_changed ();
+ void diskstream_speed_changed ();
+ void diskstream_alignment_style_changed ();
};
}; /* namespace ARDOUR*/
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index c8cc1c9ebf..91ca6a8f64 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -59,6 +59,7 @@
#include "ardour/source_factory.h"
#include "ardour/utils.h"
#include "ardour/session_playlists.h"
+#include "ardour/route.h"
#include "i18n.h"
#include <locale.h>
@@ -321,7 +322,7 @@ AudioDiskstream::use_copy_playlist ()
newname = Playlist::bump_name (_playlist->name(), _session);
- if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
+ if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
playlist->set_orig_diskstream_id (id());
return use_playlist (playlist);
} else {
@@ -729,7 +730,7 @@ AudioDiskstream::set_pending_overwrite (bool yn)
{
/* called from audio thread, so we can use the read ptr and playback sample as we wish */
- pending_overwrite = yn;
+ _pending_overwrite = yn;
overwrite_frame = playback_sample;
overwrite_offset = channels.reader()->front()->playback_buf->get_read_ptr();
@@ -798,7 +799,7 @@ AudioDiskstream::overwrite_existing_buffers ()
ret = 0;
out:
- pending_overwrite = false;
+ _pending_overwrite = false;
delete [] gain_buffer;
delete [] mixdown_buffer;
return ret;
@@ -1334,7 +1335,7 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush)
}
void
-AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
+AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
{
uint32_t buffer_position;
bool more_work = true;
@@ -1701,7 +1702,7 @@ AudioDiskstream::disengage_record_enable ()
XMLNode&
AudioDiskstream::get_state ()
{
- XMLNode* node = new XMLNode ("AudioDiskstream");
+ XMLNode* node = new XMLNode ("Diskstream");
char buf[64] = "";
LocaleGuard lg (X_("POSIX"));
boost::shared_ptr<ChannelList> c = channels.reader();
@@ -1827,7 +1828,7 @@ AudioDiskstream::set_state (const XMLNode& node, int /*version*/)
}
if (!had_playlist) {
- _playlist->set_orig_diskstream_id (_id);
+ _playlist->set_orig_diskstream_id (id());
}
if (!destructive() && capture_pending_node) {
@@ -1884,7 +1885,7 @@ AudioDiskstream::use_new_write_source (uint32_t n)
}
try {
- if ((chan->write_source = _session.create_audio_source_for_session (*this, n, destructive())) == 0) {
+ if ((chan->write_source = _session.create_audio_source_for_session (n_channels().n_audio(), name(), n, destructive())) == 0) {
throw failed_constructor();
}
}
@@ -1991,7 +1992,7 @@ AudioDiskstream::allocate_temporary_buffers ()
when slaving to MTC, Timecode etc.
*/
- double sp = max (fabsf (_actual_speed), 1.2f);
+ double const sp = max (fabsf (_actual_speed), 1.2f);
nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() * sp) + 1;
if (required_wrap_size > wrap_buffer_size) {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index f46e22143b..862f15b68c 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -81,7 +81,8 @@ AudioTrack::use_new_diskstream ()
AudioDiskstream* dsp (new AudioDiskstream (_session, name(), dflags));
boost::shared_ptr<AudioDiskstream> ds (dsp);
- _session.add_diskstream (ds);
+ ds->do_refill_with_alloc ();
+ ds->set_block_size (_session.get_block_size ());
set_diskstream (ds);
}
@@ -89,8 +90,9 @@ AudioTrack::use_new_diskstream ()
void
AudioTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
- _diskstream = ds;
- _diskstream->set_route (*this);
+ Track::set_diskstream (ds);
+
+ _diskstream->set_track (this);
_diskstream->set_destructive (_mode == Destructive);
_diskstream->set_non_layered (_mode == NonLayered);
@@ -234,6 +236,14 @@ AudioTrack::_set_state (const XMLNode& node, int version, bool call_base)
}
}
+ if (version >= 3000) {
+ if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
+ boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, *child));
+ ds->do_refill_with_alloc ();
+ set_diskstream (ds);
+ }
+ }
+
pending_state = const_cast<XMLNode*> (&node);
if (_session.state_of_the_state() & Session::Loading) {
@@ -246,7 +256,7 @@ AudioTrack::_set_state (const XMLNode& node, int version, bool call_base)
}
XMLNode&
-AudioTrack::state(bool full_state)
+AudioTrack::state (bool full_state)
{
XMLNode& root (Route::state(full_state));
XMLNode* freeze_node;
@@ -271,25 +281,9 @@ AudioTrack::state(bool full_state)
root.add_child_nocopy (*freeze_node);
}
- /* Alignment: act as a proxy for the diskstream */
-
- XMLNode* align_node = new XMLNode (X_("Alignment"));
- AlignStyle as = _diskstream->alignment_style ();
- align_node->add_property (X_("style"), enum_2_string (as));
- root.add_child_nocopy (*align_node);
-
root.add_property (X_("mode"), enum_2_string (_mode));
-
- /* we don't return diskstream state because we don't
- own the diskstream exclusively. control of the diskstream
- state is ceded to the Session, even if we create the
- diskstream.
- */
-
- _diskstream->id().print (buf, sizeof (buf));
- root.add_property ("diskstream-id", buf);
-
root.add_child_nocopy (_rec_enable_control->get_state());
+ root.add_child_nocopy (_diskstream->get_state ());
return root;
}
@@ -351,30 +345,6 @@ AudioTrack::set_state_part_two ()
_freeze_record.processor_info.push_back (frii);
}
}
-
- /* Alignment: act as a proxy for the diskstream */
-
- if ((fnode = find_named_node (*pending_state, X_("Alignment"))) != 0) {
-
- if ((prop = fnode->property (X_("style"))) != 0) {
-
- /* fix for older sessions from before EnumWriter */
-
- string pstr;
-
- if (prop->value() == "capture") {
- pstr = "CaptureTime";
- } else if (prop->value() == "existing") {
- pstr = "ExistingMaterial";
- } else {
- pstr = prop->value();
- }
-
- AlignStyle as = AlignStyle (string_2_enum (pstr, as));
- _diskstream->set_persistent_align_style (as);
- }
- }
- return;
}
int
@@ -713,7 +683,7 @@ AudioTrack::freeze_me (InterThreadInfo& itt)
boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
- new_playlist->set_orig_diskstream_id (diskstream->id());
+ new_playlist->set_orig_diskstream_id (_diskstream->id());
new_playlist->add_region (region, _session.current_start_frame());
new_playlist->set_frozen (true);
region->set_locked (true);
@@ -757,3 +727,10 @@ AudioTrack::unfreeze ()
FreezeChange (); /* EMIT SIGNAL */
}
+boost::shared_ptr<AudioFileSource>
+AudioTrack::write_source (uint32_t n)
+{
+ boost::shared_ptr<AudioDiskstream> ds = boost::dynamic_pointer_cast<AudioDiskstream> (_diskstream);
+ assert (ds);
+ return ds->write_source (n);
+}
diff --git a/libs/ardour/audio_track_importer.cc b/libs/ardour/audio_track_importer.cc
index aad20f9317..c5a584a7f4 100644
--- a/libs/ardour/audio_track_importer.cc
+++ b/libs/ardour/audio_track_importer.cc
@@ -278,7 +278,8 @@ AudioTrackImporter::_move ()
boost::shared_ptr<Diskstream> new_ds (new AudioDiskstream (session, *ds_node));
new_ds->set_name (name);
- session.add_diskstream (new_ds);
+ new_ds->do_refill_with_alloc ();
+ new_ds->set_block_size (session.get_block_size ());
/* Import playlists */
diff --git a/libs/ardour/butler.cc b/libs/ardour/butler.cc
index b201960e0e..35fb6bcc03 100644
--- a/libs/ardour/butler.cc
+++ b/libs/ardour/butler.cc
@@ -28,6 +28,7 @@
#include "ardour/io.h"
#include "ardour/midi_diskstream.h"
#include "ardour/session.h"
+#include "ardour/track.h"
#include "i18n.h"
@@ -131,7 +132,7 @@ Butler::thread_work ()
struct pollfd pfd[1];
bool disk_work_outstanding = false;
- Session::DiskstreamList::iterator i;
+ RouteList::iterator i;
while (true) {
pfd[0].fd = request_pipe[0];
@@ -207,30 +208,33 @@ Butler::thread_work ()
begin = get_microseconds();
- boost::shared_ptr<Session::DiskstreamList> dsl = _session.diskstream_list().reader ();
+ boost::shared_ptr<RouteList> rl = _session.get_routes();
// for (i = dsl->begin(); i != dsl->end(); ++i) {
// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
// }
- for (i = dsl->begin(); !transport_work_requested() && should_run && i != dsl->end(); ++i) {
+ for (i = rl->begin(); !transport_work_requested() && should_run && i != rl->end(); ++i) {
- boost::shared_ptr<Diskstream> ds = *i;
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (!tr) {
+ continue;
+ }
/* don't read inactive tracks */
- boost::shared_ptr<IO> io = ds->io();
+ boost::shared_ptr<IO> io = tr->input ();
if (io && !io->active()) {
continue;
}
- switch (ds->do_refill ()) {
+ switch (tr->do_refill ()) {
case 0:
- bytes += ds->read_data_count();
+ bytes += tr->read_data_count();
break;
case 1:
- bytes += ds->read_data_count();
+ bytes += tr->read_data_count();
disk_work_outstanding = true;
break;
@@ -242,7 +246,7 @@ Butler::thread_work ()
}
- if (i != dsl->begin() && i != dsl->end()) {
+ if (i != rl->begin() && i != rl->end()) {
/* we didn't get to all the streams */
disk_work_outstanding = true;
}
@@ -264,18 +268,23 @@ Butler::thread_work ()
compute_io = true;
begin = get_microseconds();
- for (i = dsl->begin(); !transport_work_requested() && should_run && i != dsl->end(); ++i) {
+ for (i = rl->begin(); !transport_work_requested() && should_run && i != rl->end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (!tr) {
+ continue;
+ }
+
/* note that we still try to flush diskstreams attached to inactive routes
*/
- switch ((*i)->do_flush (ButlerContext)) {
+ switch (tr->do_flush (ButlerContext)) {
case 0:
- bytes += (*i)->write_data_count();
+ bytes += tr->write_data_count();
break;
case 1:
- bytes += (*i)->write_data_count();
+ bytes += tr->write_data_count();
disk_work_outstanding = true;
break;
@@ -296,7 +305,7 @@ Butler::thread_work ()
_session.request_stop ();
}
- if (i != dsl->begin() && i != dsl->end()) {
+ if (i != rl->begin() && i != rl->end()) {
/* we didn't get to all the streams */
disk_work_outstanding = true;
}
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index ab4bd71663..40a2714dc0 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -52,7 +52,7 @@
#include "ardour/panner.h"
#include "ardour/session.h"
#include "ardour/io.h"
-#include "ardour/route.h"
+#include "ardour/track.h"
#include "i18n.h"
#include <locale.h>
@@ -74,7 +74,7 @@ PBD::Signal0<void> Diskstream::DiskUnderrun;
Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
: SessionObject(sess, name)
, i_am_the_modifier (0)
- , _route (0)
+ , _track (0)
, _record_enabled (0)
, _visible_speed (1.0f)
, _actual_speed (1.0f)
@@ -96,7 +96,7 @@ Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
, loop_location (0)
, overwrite_frame (0)
, overwrite_offset (0)
- , pending_overwrite (false)
+ , _pending_overwrite (false)
, overwrite_queued (false)
, input_change_pending (NoChange)
, wrap_buffer_size (0)
@@ -122,7 +122,7 @@ Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
Diskstream::Diskstream (Session& sess, const XMLNode& /*node*/)
: SessionObject(sess, "unnamed diskstream")
, i_am_the_modifier (0)
- , _route (0)
+ , _track (0)
, _record_enabled (0)
, _visible_speed (1.0f)
, _actual_speed (1.0f)
@@ -144,7 +144,7 @@ Diskstream::Diskstream (Session& sess, const XMLNode& /*node*/)
, loop_location (0)
, overwrite_frame (0)
, overwrite_offset (0)
- , pending_overwrite (false)
+ , _pending_overwrite (false)
, overwrite_queued (false)
, input_change_pending (NoChange)
, wrap_buffer_size (0)
@@ -176,10 +176,10 @@ Diskstream::~Diskstream ()
}
void
-Diskstream::set_route (Route& r)
+Diskstream::set_track (Track* t)
{
- _route = &r;
- _io = _route->input();
+ _track = t;
+ _io = _track->input();
ic_connection.disconnect();
_io->changed.connect_same_thread (ic_connection, boost::bind (&Diskstream::handle_input_change, this, _1, _2));
@@ -188,7 +188,7 @@ Diskstream::set_route (Route& r)
non_realtime_input_change ();
set_align_style_from_io ();
- _route->Destroyed.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this));
+ _track->Destroyed.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this));
}
void
@@ -331,15 +331,6 @@ Diskstream::set_roll_delay (ARDOUR::nframes_t nframes)
_roll_delay = nframes;
}
-void
-Diskstream::set_speed (double sp)
-{
- _session.request_diskstream_speed (*this, sp);
-
- /* to force a rebuffering at the right place */
- playlist_modified();
-}
-
int
Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
{
@@ -381,7 +372,7 @@ Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
*/
if (!overwrite_queued && prior_playlist) {
- _session.request_overwrite_buffer (this);
+ _session.request_overwrite_buffer (_track);
overwrite_queued = true;
}
@@ -401,7 +392,7 @@ void
Diskstream::playlist_modified ()
{
if (!i_am_the_modifier && !overwrite_queued) {
- _session.request_overwrite_buffer (this);
+ _session.request_overwrite_buffer (_track);
overwrite_queued = true;
}
}
@@ -459,7 +450,7 @@ Diskstream::remove_region_from_last_capture (boost::weak_ptr<Region> wregion)
void
Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<framepos_t> > const & movements_frames)
{
- if (!_route || Config->get_automation_follows_regions () == false) {
+ if (!_track || Config->get_automation_follows_regions () == false) {
return;
}
@@ -473,7 +464,7 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<framepos_t> > const &
}
/* move panner automation */
- boost::shared_ptr<Panner> p = _route->main_outs()->panner ();
+ boost::shared_ptr<Panner> p = _track->main_outs()->panner ();
if (p) {
for (uint32_t i = 0; i < p->npanners (); ++i) {
boost::shared_ptr<AutomationList> pan_alist = p->streampanner(i).pan_control()->alist();
@@ -485,7 +476,7 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<framepos_t> > const &
}
/* move processor automation */
- _route->foreach_processor (boost::bind (&Diskstream::move_processor_automation, this, _1, movements_frames));
+ _track->foreach_processor (boost::bind (&Diskstream::move_processor_automation, this, _1, movements_frames));
}
void
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index a758804564..3f7fee3aee 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -290,7 +290,7 @@ setup_enum_writer ()
REGISTER (_Session_RecordState);
REGISTER_CLASS_ENUM (SessionEvent, SetTransportSpeed);
- REGISTER_CLASS_ENUM (SessionEvent, SetDiskstreamSpeed);
+ REGISTER_CLASS_ENUM (SessionEvent, SetTrackSpeed);
REGISTER_CLASS_ENUM (SessionEvent, Locate);
REGISTER_CLASS_ENUM (SessionEvent, LocateRoll);
REGISTER_CLASS_ENUM (SessionEvent, LocateRollLocate);
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 8bf5ce89b7..8b047490e7 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -55,6 +55,7 @@
#include "ardour/smf_source.h"
#include "ardour/utils.h"
#include "ardour/session_playlists.h"
+#include "ardour/route.h"
#include "midi++/types.h"
@@ -608,7 +609,7 @@ MidiDiskstream::set_pending_overwrite (bool yn)
{
/* called from audio thread, so we can use the read ptr and playback sample as we wish */
- pending_overwrite = yn;
+ _pending_overwrite = yn;
overwrite_frame = playback_sample;
}
@@ -618,7 +619,7 @@ MidiDiskstream::overwrite_existing_buffers ()
{
//read(overwrite_frame, disk_io_chunk_frames, false);
overwrite_queued = false;
- pending_overwrite = false;
+ _pending_overwrite = false;
return 0;
}
@@ -882,7 +883,7 @@ out:
}
void
-MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
+MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
{
bool more_work = true;
int err = 0;
@@ -1160,7 +1161,7 @@ MidiDiskstream::disengage_record_enable ()
XMLNode&
MidiDiskstream::get_state ()
{
- XMLNode* node = new XMLNode ("MidiDiskstream");
+ XMLNode* node = new XMLNode ("Diskstream");
char buf[64];
LocaleGuard lg (X_("POSIX"));
@@ -1276,7 +1277,7 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/)
}
if (!had_playlist) {
- _playlist->set_orig_diskstream_id (_id);
+ _playlist->set_orig_diskstream_id (id());
}
if (capture_pending_node) {
@@ -1329,7 +1330,7 @@ MidiDiskstream::use_new_write_source (uint32_t n)
}
try {
- _write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (*this));
+ _write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (name ()));
if (!_write_source) {
throw failed_constructor();
}
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 2c543ed877..10bd7a23a5 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -77,7 +77,8 @@ MidiTrack::use_new_diskstream ()
assert(_mode != Destructive);
boost::shared_ptr<MidiDiskstream> ds (new MidiDiskstream (_session, name(), dflags));
- _session.add_diskstream (ds);
+ ds->do_refill_with_alloc ();
+ ds->set_block_size (_session.get_block_size ());
set_diskstream (boost::dynamic_pointer_cast<MidiDiskstream> (ds));
}
@@ -85,8 +86,9 @@ MidiTrack::use_new_diskstream ()
void
MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
- _diskstream = ds;
- _diskstream->set_route (*this);
+ Track::set_diskstream (ds);
+
+ _diskstream->set_track (this);
_diskstream->set_destructive (_mode == Destructive);
_diskstream->set_record_enabled (false);
@@ -185,25 +187,9 @@ MidiTrack::state(bool full_state)
root.add_child_nocopy (*freeze_node);
}
- /* Alignment: act as a proxy for the diskstream */
-
- XMLNode* align_node = new XMLNode (X_("Alignment"));
- AlignStyle as = _diskstream->alignment_style ();
- align_node->add_property (X_("style"), enum_2_string (as));
- root.add_child_nocopy (*align_node);
-
root.add_property (X_("note-mode"), enum_2_string (_note_mode));
-
- /* we don't return diskstream state because we don't
- own the diskstream exclusively. control of the diskstream
- state is ceded to the Session, even if we create the
- diskstream.
- */
-
- _diskstream->id().print (buf, sizeof(buf));
- root.add_property ("diskstream-id", buf);
-
root.add_child_nocopy (_rec_enable_control->get_state());
+ root.add_child_nocopy (_diskstream->get_state ());
root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
root.add_property ("note-mode", enum_2_string (_note_mode));
@@ -272,28 +258,13 @@ MidiTrack::set_state_part_two ()
}
}
- /* Alignment: act as a proxy for the diskstream */
-
- if ((fnode = find_named_node (*pending_state, X_("Alignment"))) != 0) {
-
- if ((prop = fnode->property (X_("style"))) != 0) {
-
- /* fix for older sessions from before EnumWriter */
-
- string pstr;
-
- if (prop->value() == "capture") {
- pstr = "CaptureTime";
- } else if (prop->value() == "existing") {
- pstr = "ExistingMaterial";
- } else {
- pstr = prop->value();
- }
-
- AlignStyle as = AlignStyle (string_2_enum (pstr, as));
- _diskstream->set_persistent_align_style (as);
- }
+ if ((fnode = find_named_node (*pending_state, X_("Diskstream"))) != 0) {
+ boost::shared_ptr<MidiDiskstream> ds (new MidiDiskstream (_session, *fnode));
+ ds->do_refill_with_alloc ();
+ ds->set_block_size (_session.get_block_size ());
+ set_diskstream (ds);
}
+
return;
}
@@ -392,7 +363,7 @@ MidiTrack::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_fram
{
int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing, can_record, rec_monitors_input);
- if (ret == 0 && diskstream()->record_enabled() && _step_editing) {
+ if (ret == 0 && _diskstream->record_enabled() && _step_editing) {
push_midi_input_to_step_edit_ringbuffer (nframes);
}
@@ -595,3 +566,11 @@ MidiTrack::set_midi_thru (bool yn)
{
_midi_thru = yn;
}
+
+boost::shared_ptr<SMFSource>
+MidiTrack::write_source (uint32_t n)
+{
+ boost::shared_ptr<MidiDiskstream> ds = boost::dynamic_pointer_cast<MidiDiskstream> (_diskstream);
+ assert (ds);
+ return ds->write_source ();
+}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 6fc7fdc2cf..649d549b86 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -178,7 +178,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, boo
: SessionObject(other->_session, namestr)
, regions (*this)
, _type(other->_type)
- , _orig_diskstream_id(other->_orig_diskstream_id)
+ , _orig_diskstream_id (other->_orig_diskstream_id)
{
init (hide);
@@ -213,7 +213,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, framepos_t start, f
: SessionObject(other->_session, str)
, regions (*this)
, _type(other->_type)
- , _orig_diskstream_id(other->_orig_diskstream_id)
+ , _orig_diskstream_id (other->_orig_diskstream_id)
{
RegionLock rlock2 (const_cast<Playlist*> (other.get()));
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 7f316c953a..5c9ee380c9 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -141,7 +141,6 @@ Session::Session (AudioEngine &eng,
_butler (new Butler (*this)),
_post_transport_work (0),
_send_timecode_update (false),
- diskstreams (new DiskstreamList),
routes (new RouteList),
_total_free_4k_blocks (0),
_bundles (new BundleList),
@@ -151,7 +150,7 @@ Session::Session (AudioEngine &eng,
click_emphasis_data (0),
main_outs (0),
_metadata (new SessionMetadata()),
- _have_rec_enabled_diskstream (false)
+ _have_rec_enabled_track (false)
{
playlists.reset (new SessionPlaylists);
@@ -246,7 +245,6 @@ Session::destroy ()
/* clear out any pending dead wood from RCU managed objects */
routes.flush ();
- diskstreams.flush ();
_bundles.flush ();
AudioDiskstream::free_working_buffers();
@@ -286,19 +284,6 @@ Session::destroy ()
boost::shared_ptr<RouteList> r = routes.reader ();
- DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
- {
- RCUWriter<DiskstreamList> dwriter (diskstreams);
- boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
- (*i)->drop_references ();
- }
-
- dsl->clear ();
- }
- diskstreams.flush ();
-
DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
@@ -722,16 +707,16 @@ Session::playlist_length_changed ()
}
void
-Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
+Session::track_playlist_changed (boost::weak_ptr<Track> wp)
{
- boost::shared_ptr<Diskstream> dstream = wp.lock ();
- if (!dstream) {
+ boost::shared_ptr<Track> track = wp.lock ();
+ if (!track) {
return;
}
boost::shared_ptr<Playlist> playlist;
- if ((playlist = dstream->playlist()) != 0) {
+ if ((playlist = track->playlist()) != 0) {
playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
}
@@ -758,21 +743,23 @@ Session::reset_input_monitor_state ()
{
if (transport_rolling()) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
+ tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
}
}
+
} else {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
//cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
+ tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
}
}
}
@@ -979,10 +966,12 @@ Session::enable_record ()
deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
- (*i)->monitor_input (true);
+
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
+ tr->monitor_input (true);
}
}
}
@@ -1014,11 +1003,12 @@ Session::disable_record (bool rt_context, bool force)
}
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
- (*i)->monitor_input (false);
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
+ tr->monitor_input (false);
}
}
}
@@ -1037,12 +1027,12 @@ Session::step_back_from_record ()
if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (false);
+ tr->monitor_input (false);
}
}
}
@@ -1194,9 +1184,12 @@ Session::set_block_size (nframes_t nframes)
(*i)->set_block_size (nframes);
}
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->set_block_size (nframes);
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->set_block_size (nframes);
+ }
}
set_worst_io_latencies ();
@@ -1482,36 +1475,12 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m
catch (failed_constructor &err) {
error << _("Session: could not create new midi track.") << endmsg;
-
- if (track) {
- /* we need to get rid of this, since the track failed to be created */
- /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
-
- {
- RCUWriter<DiskstreamList> writer (diskstreams);
- boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
- ds->remove (track->midi_diskstream());
- }
- }
-
goto failed;
}
catch (AudioEngine::PortRegistrationFailure& pfe) {
error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
-
- if (track) {
- /* we need to get rid of this, since the track failed to be created */
- /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
-
- {
- RCUWriter<DiskstreamList> writer (diskstreams);
- boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
- ds->remove (track->midi_diskstream());
- }
- }
-
goto failed;
}
@@ -1673,36 +1642,12 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
catch (failed_constructor &err) {
error << _("Session: could not create new audio track.") << endmsg;
-
- if (track) {
- /* we need to get rid of this, since the track failed to be created */
- /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
-
- {
- RCUWriter<DiskstreamList> writer (diskstreams);
- boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
- ds->remove (track->audio_diskstream());
- }
- }
-
goto failed;
}
catch (AudioEngine::PortRegistrationFailure& pfe) {
error << pfe.what() << endmsg;
-
- if (track) {
- /* we need to get rid of this, since the track failed to be created */
- /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
-
- {
- RCUWriter<DiskstreamList> writer (diskstreams);
- boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
- ds->remove (track->audio_diskstream());
- }
- }
-
goto failed;
}
@@ -1947,6 +1892,13 @@ Session::add_routes (RouteList& new_routes, bool save)
if (r->is_monitor()) {
_monitor_out = r;
}
+
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
+ if (tr) {
+ tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
+ track_playlist_changed (boost::weak_ptr<Track> (tr));
+ tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
+ }
}
if (_monitor_out && IO::connecting_legal) {
@@ -2068,28 +2020,6 @@ Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::
}
void
-Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
-{
- /* need to do this in case we're rolling at the time, to prevent false underruns */
- dstream->do_refill_with_alloc ();
-
- dstream->set_block_size (current_block_size);
-
- {
- RCUWriter<DiskstreamList> writer (diskstreams);
- boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
- ds->push_back (dstream);
- /* writer goes out of scope, copies ds back to main */
- }
-
- dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr<Diskstream> (dstream)));
- /* this will connect to future changes, and check the current length */
- diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
-
- dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this));
-}
-
-void
Session::remove_route (shared_ptr<Route> route)
{
{
@@ -2123,22 +2053,6 @@ Session::remove_route (shared_ptr<Route> route)
/* writer goes out of scope, forces route list update */
}
- boost::shared_ptr<Track> t;
- boost::shared_ptr<Diskstream> ds;
-
- if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
- ds = t->diskstream();
- }
-
- if (ds) {
-
- {
- RCUWriter<DiskstreamList> dsl (diskstreams);
- boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
- d->remove (ds);
- }
- }
-
find_current_end ();
// We need to disconnect the routes inputs and outputs
@@ -2385,13 +2299,16 @@ Session::get_maximum_extent () const
{
nframes_t max = 0;
nframes_t me;
-
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->destructive()) //ignore tape tracks when getting max extents
+
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (!tr || tr->destructive()) {
+ //ignore tape tracks when getting max extents
continue;
- boost::shared_ptr<Playlist> pl = (*i)->playlist();
+ }
+
+ boost::shared_ptr<Playlist> pl = tr->playlist();
if ((me = pl->get_maximum_extent()) > max) {
max = me;
}
@@ -2400,34 +2317,6 @@ Session::get_maximum_extent () const
return max;
}
-boost::shared_ptr<Diskstream>
-Session::diskstream_by_name (string name)
-{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->name() == name) {
- return *i;
- }
- }
-
- return boost::shared_ptr<Diskstream>((Diskstream*) 0);
-}
-
-boost::shared_ptr<Diskstream>
-Session::diskstream_by_id (const PBD::ID& id)
-{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->id() == id) {
- return *i;
- }
- }
-
- return boost::shared_ptr<Diskstream>((Diskstream*) 0);
-}
-
/* Region management */
boost::shared_ptr<Region>
@@ -2496,10 +2385,14 @@ Session::remove_last_capture ()
{
list<boost::shared_ptr<Region> > r;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (!tr) {
+ continue;
+ }
+
+ list<boost::shared_ptr<Region> >& l = tr->last_capture_regions();
if (!l.empty()) {
r.insert (r.end(), l.begin(), l.end());
@@ -2840,10 +2733,9 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
/** Create a new within-session audio source */
boost::shared_ptr<AudioFileSource>
-Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
+Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
{
- const size_t n_chans = ds.n_channels().n_audio();
- const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
+ const string name = new_audio_source_name (n, n_chans, chan, destructive);
const string path = new_source_path_from_name(DataType::AUDIO, name);
return boost::dynamic_pointer_cast<AudioFileSource> (
@@ -2901,9 +2793,9 @@ Session::new_midi_source_name (const string& base)
/** Create a new within-session MIDI source */
boost::shared_ptr<MidiSource>
-Session::create_midi_source_for_session (MidiDiskstream& ds)
+Session::create_midi_source_for_session (string const & n)
{
- const string name = new_midi_source_name (ds.name());
+ const string name = new_midi_source_name (n);
const string path = new_source_path_from_name (DataType::MIDI, name);
return boost::dynamic_pointer_cast<SMFSource> (
@@ -3050,21 +2942,6 @@ Session::is_auditioning () const
}
}
-uint32_t
-Session::n_diskstreams () const
-{
- uint32_t n = 0;
-
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- n++;
- }
- }
- return n;
-}
-
void
Session::graph_reordered ()
{
@@ -3088,10 +2965,12 @@ Session::graph_reordered ()
reflect any changes in latencies within the graph.
*/
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->set_capture_offset ();
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->set_capture_offset ();
+ }
}
}
@@ -3381,10 +3260,12 @@ Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selecti
void
Session::reset_native_file_format ()
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->reset_write_sources (false);
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->reset_write_sources (false);
+ }
}
}
@@ -3469,7 +3350,7 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
/* call tree *MUST* hold route_lock */
- if ((playlist = track.diskstream()->playlist()) == 0) {
+ if ((playlist = track.playlist()) == 0) {
goto out;
}
@@ -3725,28 +3606,34 @@ Session::sync_order_keys (std::string const & base)
set_remote_control_ids ();
}
-/** @return true if there is at least one record-enabled diskstream, otherwise false */
+/** @return true if there is at least one record-enabled track, otherwise false */
bool
-Session::have_rec_enabled_diskstream () const
+Session::have_rec_enabled_track () const
{
- return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
+ return g_atomic_int_get (&_have_rec_enabled_track) == 1;
}
-/** Update the state of our rec-enabled diskstreams flag */
+/** Update the state of our rec-enabled tracks flag */
void
-Session::update_have_rec_enabled_diskstream ()
+Session::update_have_rec_enabled_track ()
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
- DiskstreamList::iterator i = dsl->begin ();
- while (i != dsl->end () && (*i)->record_enabled () == false) {
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ RouteList::iterator i = rl->begin();
+ while (i != rl->end ()) {
+
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
+ break;
+ }
+
++i;
}
- int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
+ int const old = g_atomic_int_get (&_have_rec_enabled_track);
- g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
+ g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
- if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
+ if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
RecordStateChanged (); /* EMIT SIGNAL */
}
}
@@ -3821,12 +3708,7 @@ Session::get_routes_with_regions_at (nframes64_t const p) const
continue;
}
- boost::shared_ptr<Diskstream> ds = tr->diskstream ();
- if (!ds) {
- continue;
- }
-
- boost::shared_ptr<Playlist> pl = ds->playlist ();
+ boost::shared_ptr<Playlist> pl = tr->playlist ();
if (!pl) {
continue;
}
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 156784875a..1aa061313d 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -40,6 +40,7 @@
#include "ardour/midi_diskstream.h"
#include "ardour/session.h"
#include "ardour/timestamps.h"
+#include "ardour/track.h"
#include "i18n.h"
@@ -73,30 +74,33 @@ Session::schedule_curve_reallocation ()
}
void
-Session::request_overwrite_buffer (Diskstream* stream)
+Session::request_overwrite_buffer (Track* t)
{
SessionEvent *ev = new SessionEvent (SessionEvent::Overwrite, SessionEvent::Add, SessionEvent::Immediate, 0, 0, 0.0);
- ev->set_ptr (stream);
+ ev->set_ptr (t);
queue_event (ev);
}
/** Process thread. */
void
-Session::overwrite_some_buffers (Diskstream* ds)
+Session::overwrite_some_buffers (Track* t)
{
if (actively_recording()) {
return;
}
- if (ds) {
+ if (t) {
- ds->set_pending_overwrite (true);
+ t->set_pending_overwrite (true);
} else {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->set_pending_overwrite (true);
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->set_pending_overwrite (true);
+ }
}
}
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index ea215e6058..17387ebd5e 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -21,14 +21,13 @@
#include "pbd/error.h"
#include <glibmm/thread.h>
-#include "ardour/audio_diskstream.h"
#include "ardour/audioengine.h"
#include "ardour/butler.h"
#include "ardour/export_failed.h"
#include "ardour/export_handler.h"
#include "ardour/export_status.h"
-#include "ardour/route.h"
#include "ardour/session.h"
+#include "ardour/track.h"
#include "i18n.h"
@@ -105,10 +104,11 @@ Session::start_audio_export (nframes_t position, bool /* realtime */)
/* get everyone to the right position */
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ boost::shared_ptr<RouteList> rl = routes.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)-> seek (position, true)) {
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->seek (position, true)) {
error << string_compose (_("%1: cannot seek to %2 for export"),
(*i)->name(), position)
<< endmsg;
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 85c424e40c..e24b660fb6 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -28,7 +28,6 @@
#include <glibmm/thread.h>
#include "ardour/ardour.h"
-#include "ardour/audio_diskstream.h"
#include "ardour/audioengine.h"
#include "ardour/auditioner.h"
#include "ardour/butler.h"
@@ -37,6 +36,7 @@
#include "ardour/session.h"
#include "ardour/slave.h"
#include "ardour/timestamps.h"
+#include "ardour/port.h"
#include "midi++/manager.h"
@@ -194,20 +194,22 @@ Session::silent_process_routes (nframes_t nframes, bool& need_butler)
}
void
-Session::get_diskstream_statistics ()
+Session::get_track_statistics ()
{
float pworst = 1.0f;
float cworst = 1.0f;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
- if ((*i)->hidden()) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+
+ if (!tr || tr->hidden()) {
continue;
}
- pworst = min (pworst, (*i)->playback_buffer_load());
- cworst = min (cworst, (*i)->capture_buffer_load());
+ pworst = min (pworst, tr->playback_buffer_load());
+ cworst = min (cworst, tr->capture_buffer_load());
}
uint32_t pmin = g_atomic_int_get (&_playback_load);
@@ -639,18 +641,21 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame,
bool ok = true;
nframes_t frame_delta = slave_transport_frame - _transport_frame;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->can_internal_playback_seek (frame_delta)) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->can_internal_playback_seek (frame_delta)) {
ok = false;
break;
}
}
if (ok) {
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->internal_playback_seek (frame_delta);
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->internal_playback_seek (frame_delta);
+ }
}
_transport_frame += frame_delta;
@@ -1048,11 +1053,11 @@ Session::process_event (SessionEvent* ev)
break;
case SessionEvent::Overwrite:
- overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
+ overwrite_some_buffers (static_cast<Track*>(ev->ptr));
break;
- case SessionEvent::SetDiskstreamSpeed:
- set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
+ case SessionEvent::SetTrackSpeed:
+ set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
break;
case SessionEvent::SetSyncSource:
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 9f1adcfe99..833ead56e2 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -605,40 +605,6 @@ Session::create (const string& mix_template, nframes_t initial_length, BusProfil
return 0;
}
-
-int
-Session::load_diskstreams (const XMLNode& node)
-{
- XMLNodeList clist;
- XMLNodeConstIterator citer;
-
- clist = node.children();
-
- for (citer = clist.begin(); citer != clist.end(); ++citer) {
-
- try {
- /* diskstreams added automatically by DiskstreamCreated handler */
- if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
- AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
- boost::shared_ptr<AudioDiskstream> dstream (dsp);
- add_diskstream (dstream);
- } else if ((*citer)->name() == "MidiDiskstream") {
- boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
- add_diskstream (dstream);
- } else {
- error << _("Session: unknown diskstream type in XML") << endmsg;
- }
- }
-
- catch (failed_constructor& err) {
- error << _("Session: could not load diskstream via XML state") << endmsg;
- return -1;
- }
- }
-
- return 0;
-}
-
void
Session::maybe_write_autosave()
{
@@ -1075,17 +1041,6 @@ Session::state(bool full_state)
}
}
- child = node->add_child ("DiskStreams");
-
- {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- child->add_child_nocopy ((*i)->get_state());
- }
- }
- }
-
if (full_state) {
node->add_child_nocopy (_locations.get_state());
} else {
@@ -1236,7 +1191,6 @@ Session::set_state (const XMLNode& node, int version)
Locations
Sources
AudioRegions
- AudioDiskstreams
Connections
Routes
RouteGroups
@@ -1327,13 +1281,6 @@ Session::set_state (const XMLNode& node, int version)
}
}
- if ((child = find_named_node (node, "DiskStreams")) == 0) {
- error << _("Session: XML state has no diskstreams section") << endmsg;
- goto out;
- } else if (load_diskstreams (*child)) {
- goto out;
- }
-
if (version >= 3000) {
if ((child = find_named_node (node, "Bundles")) == 0) {
warning << _("Session: XML state has no bundles section") << endmsg;
@@ -1353,6 +1300,13 @@ Session::set_state (const XMLNode& node, int version)
goto out;
}
+ if (version < 3000 && ((child = find_named_node (node, X_("DiskStreams"))) == 0)) {
+ error << _("Session: XML state has no diskstreams section") << endmsg;
+ goto out;
+ } else if (load_diskstreams_2X (*child, version)) {
+ goto out;
+ }
+
if ((child = find_named_node (node, "Routes")) == 0) {
error << _("Session: XML state has no routes section") << endmsg;
goto out;
@@ -1360,6 +1314,9 @@ Session::set_state (const XMLNode& node, int version)
goto out;
}
+ /* our diskstreams list is no longer needed as they are now all owned by their Route */
+ _diskstreams_2X.clear ();
+
if (version >= 3000) {
if ((child = find_named_node (node, "RouteGroups")) == 0) {
@@ -1419,8 +1376,13 @@ Session::load_routes (const XMLNode& node, int version)
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
-
+ boost::shared_ptr<Route> route;
+ if (version < 3000) {
+ route = XMLRouteFactory_2X (**niter, version);
+ } else {
+ route = XMLRouteFactory (**niter, version);
+ }
+
if (route == 0) {
error << _("Session: cannot create Route from XML description.") << endmsg;
return -1;
@@ -1445,12 +1407,8 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
return ret;
}
- const XMLProperty* dsprop;
+ XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
- if ((dsprop = node.property (X_("diskstream-id"))) == 0) {
- dsprop = node.property (X_("diskstream"));
- }
-
DataType type = DataType::AUDIO;
const XMLProperty* prop = node.property("default-type");
@@ -1460,28 +1418,80 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
assert (type != DataType::NIL);
- if (dsprop) {
+ if (ds_child) {
- boost::shared_ptr<Diskstream> ds;
- PBD::ID diskstream_id (dsprop->value());
- PBD::ID zero ("0");
-
- /* this wierd hack is used when creating
- tracks from a template. We have a special
- ID for the diskstream that means "you
- should create a new diskstream here, not
- look for an old one."
- */
+ Track* track;
+
+ if (type == DataType::AUDIO) {
+ track = new AudioTrack (*this, X_("toBeResetFroXML"));
+
+ } else {
+ track = new MidiTrack (*this, X_("toBeResetFroXML"));
+ }
+
+ if (track->init()) {
+ delete track;
+ return ret;
+ }
+
+ if (track->set_state (node, version)) {
+ delete track;
+ return ret;
+ }
+
+ boost_debug_shared_ptr_mark_interesting (track, "Track");
+ ret.reset (track);
- if (diskstream_id != zero) {
+ } else {
+ Route* rt = new Route (*this, X_("toBeResetFroXML"));
- ds = diskstream_by_id (diskstream_id);
+ if (rt->init () == 0 && rt->set_state (node, version) == 0) {
+ boost_debug_shared_ptr_mark_interesting (rt, "Route");
+ ret.reset (rt);
+ } else {
+ delete rt;
+ }
+ }
- if (!ds) {
- error << string_compose (_("cannot find diskstream ID %1"), diskstream_id.to_s()) << endmsg;
- return ret;
- }
- }
+ return ret;
+}
+
+boost::shared_ptr<Route>
+Session::XMLRouteFactory_2X (const XMLNode& node, int version)
+{
+ boost::shared_ptr<Route> ret;
+
+ if (node.name() != "Route") {
+ return ret;
+ }
+
+ XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
+ if (!ds_prop) {
+ ds_prop = node.property (X_("diskstream"));
+ }
+
+ cout << "ds_prop " << ds_prop << "\n";
+
+ DataType type = DataType::AUDIO;
+ const XMLProperty* prop = node.property("default-type");
+
+ if (prop) {
+ type = DataType (prop->value());
+ }
+
+ assert (type != DataType::NIL);
+
+ if (ds_prop) {
+
+ list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
+ while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
+ ++i;
+ }
+
+ if (i == _diskstreams_2X.end()) {
+ error << _("Could not find diskstream for route") << endmsg;
+ return boost::shared_ptr<Route> ();
+ }
Track* track;
@@ -1497,16 +1507,12 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
return ret;
}
- if (ds) {
- track->set_diskstream (ds);
- } else {
- track->use_new_diskstream ();
- }
-
if (track->set_state (node, version)) {
delete track;
return ret;
}
+
+ track->set_diskstream (*i);
boost_debug_shared_ptr_mark_interesting (track, "Track");
ret.reset (track);
@@ -3099,11 +3105,11 @@ Session::config_changed (std::string p, bool ours)
if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
/* auto-input only makes a difference if we're rolling */
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
- (*i)->monitor_input (!config.get_auto_input());
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
+ tr->monitor_input (!config.get_auto_input());
}
}
}
@@ -3317,3 +3323,32 @@ Session::set_history_depth (uint32_t d)
{
_history.set_depth (d);
}
+
+int
+Session::load_diskstreams_2X (XMLNode const & node, int)
+{
+ XMLNodeList clist;
+ XMLNodeConstIterator citer;
+
+ clist = node.children();
+
+ for (citer = clist.begin(); citer != clist.end(); ++citer) {
+
+ try {
+ /* diskstreams added automatically by DiskstreamCreated handler */
+ if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
+ boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
+ _diskstreams_2X.push_back (dsp);
+ } else {
+ error << _("Session: unknown diskstream type in XML") << endmsg;
+ }
+ }
+
+ catch (failed_constructor& err) {
+ error << _("Session: could not load diskstream via XML state") << endmsg;
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index c5e6795325..aab27fe68b 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -32,7 +32,6 @@
#include "midi++/port.h"
#include "ardour/ardour.h"
-#include "ardour/audio_diskstream.h"
#include "ardour/audioengine.h"
#include "ardour/auditioner.h"
#include "ardour/butler.h"
@@ -107,10 +106,10 @@ Session::request_transport_speed (double speed)
}
void
-Session::request_diskstream_speed (Diskstream& ds, double speed)
+Session::request_track_speed (Track* tr, double speed)
{
- SessionEvent* ev = new SessionEvent (SessionEvent::SetDiskstreamSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
- ev->set_ptr (&ds);
+ SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
+ ev->set_ptr (tr);
queue_event (ev);
}
@@ -155,7 +154,7 @@ Session::request_play_loop (bool yn, bool leave_rolling)
queue_event (ev);
if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
- // request an immediate locate to refresh the diskstreams
+ // request an immediate locate to refresh the tracks
// after disabling looping
request_locate (_transport_frame-1, false);
}
@@ -252,7 +251,6 @@ Session::butler_transport_work ()
bool finished;
PostTransportWork ptw;
boost::shared_ptr<RouteList> r = routes.reader ();
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
finished = true;
@@ -267,8 +265,11 @@ Session::butler_transport_work ()
}
if (ptw & PostTransportInputChange) {
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->non_realtime_input_change ();
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->non_realtime_input_change ();
+ }
}
}
@@ -286,9 +287,10 @@ Session::butler_transport_work ()
if (!(ptw & PostTransportLocate)) {
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->non_realtime_locate (_transport_frame);
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->hidden()) {
+ tr->non_realtime_locate (_transport_frame);
}
if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
/* new request, stop seeking, and start again */
@@ -331,21 +333,23 @@ Session::butler_transport_work ()
void
Session::non_realtime_set_speed ()
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->non_realtime_set_speed ();
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->non_realtime_set_speed ();
+ }
}
}
void
Session::non_realtime_overwrite (int on_entry, bool& finished)
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->pending_overwrite) {
- (*i)->overwrite_existing_buffers ();
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->pending_overwrite ()) {
+ tr->overwrite_existing_buffers ();
}
if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
finished = false;
@@ -358,10 +362,12 @@ Session::non_realtime_overwrite (int on_entry, bool& finished)
void
Session::non_realtime_locate ()
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->non_realtime_locate (_transport_frame);
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->non_realtime_locate (_transport_frame);
+ }
}
}
@@ -378,10 +384,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
did_record = false;
saved = false;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->get_captured_frames () != 0) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->get_captured_frames () != 0) {
did_record = true;
break;
}
@@ -436,8 +442,11 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
}
DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->transport_stopped (*now, xnow, abort);
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->transport_stopped_wallclock (*now, xnow, abort);
+ }
}
boost::shared_ptr<RouteList> r = routes.reader ();
@@ -531,7 +540,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
}
- /* do this before seeking, because otherwise the Diskstreams will do the wrong thing in seamless loop mode.
+ /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
*/
if (ptw & PostTransportClearSubstate) {
@@ -541,13 +550,12 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
/* this for() block can be put inside the previous if() and has the effect of ... ??? what */
-
DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
- (*i)->non_realtime_locate (_transport_frame);
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->hidden()) {
+ tr->non_realtime_locate (_transport_frame);
}
if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
@@ -631,11 +639,12 @@ Session::unset_play_loop ()
play_loop = false;
clear_events (SessionEvent::AutoLoop);
- // set all diskstreams to NOT use internal looping
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->set_loop (0);
+ // set all tracks to NOT use internal looping
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->hidden()) {
+ tr->set_loop (0);
}
}
}
@@ -670,20 +679,22 @@ Session::set_play_loop (bool yn)
unset_play_range ();
if (Config->get_seamless_loop()) {
- // set all diskstreams to use internal looping
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->set_loop (loc);
+ // set all tracks to use internal looping
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->hidden()) {
+ tr->set_loop (loc);
}
}
}
else {
- // set all diskstreams to NOT use internal looping
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->set_loop (0);
+ // set all tracks to NOT use internal looping
+ boost::shared_ptr<RouteList> rl = routes.reader ();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->hidden()) {
+ tr->set_loop (0);
}
}
}
@@ -749,16 +760,19 @@ Session::start_locate (nframes64_t target_frame, bool with_roll, bool with_flush
int
Session::micro_locate (nframes_t distance)
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->can_internal_playback_seek (distance)) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->can_internal_playback_seek (distance)) {
return -1;
}
}
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->internal_playback_seek (distance);
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->internal_playback_seek (distance);
+ }
}
_transport_frame += distance;
@@ -834,24 +848,25 @@ Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool
/* switch from input if we're going to roll */
if (Config->get_monitoring_model() == HardwareMonitoring) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (!config.get_auto_input());
+ tr->monitor_input (!config.get_auto_input());
}
}
}
} else {
/* otherwise we're going to stop, so do the opposite */
if (Config->get_monitoring_model() == HardwareMonitoring) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (true);
+ tr->monitor_input (true);
}
}
}
@@ -869,12 +884,12 @@ Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool
if (with_loop) {
// this is only necessary for seamless looping
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
// tell it we've looped, so it can deal with the record state
- (*i)->transport_looped(_transport_frame);
+ tr->transport_looped(_transport_frame);
}
}
}
@@ -921,12 +936,12 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state)
if (Config->get_monitoring_model() == HardwareMonitoring)
{
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (true);
+ tr->monitor_input (true);
}
}
}
@@ -950,12 +965,12 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state)
if (Config->get_monitoring_model() == HardwareMonitoring) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (config.get_auto_input() && (*i)->record_enabled ()) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (config.get_auto_input() && tr && tr->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
- (*i)->monitor_input (false);
+ tr->monitor_input (false);
}
}
}
@@ -1002,9 +1017,10 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state)
_last_transport_speed = _transport_speed;
_transport_speed = speed;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && tr->realtime_set_speed (tr->speed(), true)) {
todo = PostTransportWork (todo | PostTransportSpeed);
break;
}
@@ -1028,10 +1044,12 @@ Session::stop_transport (bool abort, bool clear_state)
if (actively_recording() && !(transport_sub_state & StopPendingCapture) && _worst_output_latency > current_block_size) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->prepare_to_stop (_transport_frame);
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->prepare_to_stop (_transport_frame);
+ }
}
/* we need to capture the audio that has still not yet been received by the system
@@ -1056,10 +1074,12 @@ Session::stop_transport (bool abort, bool clear_state)
if ((transport_sub_state & PendingDeclickOut) == 0) {
if (!(transport_sub_state & StopPendingCapture)) {
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->prepare_to_stop (_transport_frame);
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->prepare_to_stop (_transport_frame);
+ }
}
}
@@ -1105,9 +1125,12 @@ Session::start_transport ()
_transport_speed = 1.0;
_target_transport_speed = 1.0;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->realtime_set_speed ((*i)->speed(), true);
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->realtime_set_speed (tr->speed(), true);
+ }
}
deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
@@ -1185,13 +1208,14 @@ Session::use_sync_source (Slave* new_slave)
delete _slave;
_slave = new_slave;
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- if (!(*i)->hidden()) {
- if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr && !tr->hidden()) {
+ if (tr->realtime_set_speed (tr->speed(), true)) {
non_rt_required = true;
}
- (*i)->set_slaved (_slave != 0);
+ tr->set_slaved (_slave != 0);
}
}
@@ -1274,16 +1298,16 @@ Session::switch_to_sync_source (SyncSource src)
}
void
-Session::reverse_diskstream_buffers ()
+Session::reverse_track_buffers ()
{
add_post_transport_work (PostTransportReverse);
_butler->schedule_transport_work ();
}
void
-Session::set_diskstream_speed (Diskstream* stream, double speed)
+Session::set_track_speed (Track* track, double speed)
{
- if (stream->realtime_set_speed (speed, false)) {
+ if (track->realtime_set_speed (speed, false)) {
add_post_transport_work (PostTransportSpeed);
_butler->schedule_transport_work ();
set_dirty ();
@@ -1501,11 +1525,13 @@ Session::update_latency_compensation (bool with_stop, bool abort)
/* reflect any changes in latencies into capture offsets
*/
-
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- (*i)->set_capture_offset ();
+
+ boost::shared_ptr<RouteList> rl = routes.reader();
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+ if (tr) {
+ tr->set_capture_offset ();
+ }
}
}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 47ec248d59..a7325189c8 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -261,7 +261,7 @@ Track::no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame,
*/
}
- diskstream()->check_record_status (start_frame, nframes, can_record);
+ _diskstream->check_record_status (start_frame, nframes, can_record);
bool send_silence;
@@ -346,7 +346,7 @@ Track::silent_roll (nframes_t nframes, framepos_t /*start_frame*/, framepos_t /*
silence (nframes);
- return diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input, need_butler);
+ return _diskstream->process (_session.transport_frame(), nframes, can_record, rec_monitors_input, need_butler);
}
ChanCount
@@ -361,3 +361,297 @@ Track::input_streams () const
return cc;
}
+void
+Track::set_diskstream (boost::shared_ptr<Diskstream> ds)
+{
+ _diskstream = ds;
+
+ ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this));
+ diskstream_playlist_changed ();
+ ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this));
+ ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this));
+ ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this));
+}
+
+void
+Track::diskstream_playlist_changed ()
+{
+ PlaylistChanged (); /* EMIT SIGNAL */
+}
+
+void
+Track::diskstream_record_enable_changed ()
+{
+ RecordEnableChanged (); /* EMIT SIGNAL */
+}
+
+void
+Track::diskstream_speed_changed ()
+{
+ SpeedChanged (); /* EMIT SIGNAL */
+}
+
+void
+Track::diskstream_alignment_style_changed ()
+{
+ AlignmentStyleChanged (); /* EMIT SIGNAL */
+}
+
+boost::shared_ptr<Playlist>
+Track::playlist ()
+{
+ return _diskstream->playlist ();
+}
+
+void
+Track::monitor_input (bool m)
+{
+ _diskstream->monitor_input (m);
+}
+
+bool
+Track::destructive () const
+{
+ return _diskstream->destructive ();
+}
+
+list<boost::shared_ptr<Region> > &
+Track::last_capture_regions ()
+{
+ return _diskstream->last_capture_regions ();
+}
+
+void
+Track::set_capture_offset ()
+{
+ _diskstream->set_capture_offset ();
+}
+
+void
+Track::reset_write_sources (bool r, bool force)
+{
+ _diskstream->reset_write_sources (r, force);
+}
+
+float
+Track::playback_buffer_load () const
+{
+ return _diskstream->playback_buffer_load ();
+}
+
+float
+Track::capture_buffer_load () const
+{
+ return _diskstream->capture_buffer_load ();
+}
+
+int
+Track::do_refill ()
+{
+ return _diskstream->do_refill ();
+}
+
+int
+Track::do_flush (RunContext c, bool force)
+{
+ return _diskstream->do_flush (c, force);
+}
+
+void
+Track::set_pending_overwrite (bool o)
+{
+ _diskstream->set_pending_overwrite (o);
+}
+
+int
+Track::seek (nframes_t s, bool complete_refill)
+{
+ return _diskstream->seek (s, complete_refill);
+}
+
+bool
+Track::hidden () const
+{
+ return _diskstream->hidden ();
+}
+
+int
+Track::can_internal_playback_seek (nframes_t d)
+{
+ return _diskstream->can_internal_playback_seek (d);
+}
+
+int
+Track::internal_playback_seek (nframes_t d)
+{
+ return _diskstream->internal_playback_seek (d);
+}
+
+void
+Track::non_realtime_input_change ()
+{
+ _diskstream->non_realtime_input_change ();
+}
+
+void
+Track::non_realtime_locate (nframes_t p)
+{
+ _diskstream->non_realtime_locate (p);
+}
+
+void
+Track::non_realtime_set_speed ()
+{
+ _diskstream->non_realtime_set_speed ();
+}
+
+int
+Track::overwrite_existing_buffers ()
+{
+ return _diskstream->overwrite_existing_buffers ();
+}
+
+nframes_t
+Track::get_captured_frames (uint32_t n)
+{
+ return _diskstream->get_captured_frames (n);
+}
+
+int
+Track::set_loop (Location* l)
+{
+ return _diskstream->set_loop (l);
+}
+
+void
+Track::transport_looped (nframes_t f)
+{
+ _diskstream->transport_looped (f);
+}
+
+bool
+Track::realtime_set_speed (double s, bool g)
+{
+ return _diskstream->realtime_set_speed (s, g);
+}
+
+void
+Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
+{
+ _diskstream->transport_stopped_wallclock (n, t, g);
+}
+
+bool
+Track::pending_overwrite () const
+{
+ return _diskstream->pending_overwrite ();
+}
+
+double
+Track::speed () const
+{
+ return _diskstream->speed ();
+}
+
+void
+Track::prepare_to_stop (framepos_t p)
+{
+ _diskstream->prepare_to_stop (p);
+}
+
+void
+Track::set_slaved (bool s)
+{
+ _diskstream->set_slaved (s);
+}
+
+ChanCount
+Track::n_channels ()
+{
+ return _diskstream->n_channels ();
+}
+
+nframes_t
+Track::get_capture_start_frame (uint32_t n)
+{
+ return _diskstream->get_capture_start_frame (n);
+}
+
+AlignStyle
+Track::alignment_style () const
+{
+ return _diskstream->alignment_style ();
+}
+
+void
+Track::set_record_enabled (bool r)
+{
+ _diskstream->set_record_enabled (r);
+}
+
+nframes_t
+Track::current_capture_start () const
+{
+ return _diskstream->current_capture_start ();
+}
+
+nframes_t
+Track::current_capture_end () const
+{
+ return _diskstream->current_capture_end ();
+}
+
+void
+Track::playlist_modified ()
+{
+ _diskstream->playlist_modified ();
+}
+
+int
+Track::use_playlist (boost::shared_ptr<Playlist> p)
+{
+ return _diskstream->use_playlist (p);
+}
+
+int
+Track::use_copy_playlist ()
+{
+ return _diskstream->use_copy_playlist ();
+}
+
+int
+Track::use_new_playlist ()
+{
+ return _diskstream->use_new_playlist ();
+}
+
+uint32_t
+Track::read_data_count () const
+{
+ return _diskstream->read_data_count ();
+}
+
+void
+Track::set_align_style (AlignStyle s)
+{
+ _diskstream->set_align_style (s);
+}
+
+uint32_t
+Track::write_data_count () const
+{
+ return _diskstream->write_data_count ();
+}
+
+PBD::ID const &
+Track::diskstream_id () const
+{
+ return _diskstream->id ();
+}
+
+void
+Track::set_block_size (nframes_t n)
+{
+ Route::set_block_size (n);
+ _diskstream->set_block_size (n);
+}