mega-commit to save state of first "it compilesand links" state for separated disk i/o changes.

THIS WILL NOT RUN. THIS REQUIRES MANY CHANGES
This commit is contained in:
Paul Davis 2017-03-31 17:28:14 +02:00
parent 94604c6979
commit a4a87f56e9
22 changed files with 1301 additions and 703 deletions

View file

@ -692,10 +692,6 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
_route->panner_shell()->Changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::connect_to_pan, this), gui_context()); _route->panner_shell()->Changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::connect_to_pan, this), gui_context());
} }
if (is_audio_track()) {
audio_track()->DiskstreamChanged.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::diskstream_changed, this), gui_context());
}
_route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::setup_comment_button, this), gui_context()); _route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::setup_comment_button, this), gui_context());
set_stuff_from_route (); set_stuff_from_route ();

View file

@ -272,7 +272,7 @@ PlaylistSelector::selection_changed ()
return; return;
} }
at->use_playlist (apl); at->use_playlist (DataType::AUDIO, apl);
hide (); hide ();
} }

View file

@ -1643,7 +1643,7 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist>
return; return;
} }
track()->use_playlist (pl); track()->use_playlist (track()->data_type(), pl);
RouteGroup* rg = route_group(); RouteGroup* rg = route_group();
@ -1683,7 +1683,7 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist>
track->use_new_playlist(); track->use_new_playlist();
track->playlist()->set_name(playlist_name); track->playlist()->set_name(playlist_name);
} else { } else {
track->use_playlist(ipl); track->use_playlist(track->data_type(), ipl);
} }
} }
} }

View file

@ -77,7 +77,6 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Container* canvas_g
canvas_rect->Event.connect (sigc::bind (sigc::mem_fun (_trackview.editor(), &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview)); canvas_rect->Event.connect (sigc::bind (sigc::mem_fun (_trackview.editor(), &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview));
if (_trackview.is_track()) { if (_trackview.is_track()) {
_trackview.track()->DiskstreamChanged.connect (*this, invalidator (*this), boost::bind (&StreamView::diskstream_changed, this), gui_context());
_trackview.track()->rec_enable_control()->Changed.connect (*this, invalidator (*this), boost::bind (&StreamView::rec_enable_changed, this), gui_context()); _trackview.track()->rec_enable_control()->Changed.connect (*this, invalidator (*this), boost::bind (&StreamView::rec_enable_changed, this), gui_context());
_trackview.session()->TransportStateChange.connect (*this, invalidator (*this), boost::bind (&StreamView::transport_changed, this), gui_context()); _trackview.session()->TransportStateChange.connect (*this, invalidator (*this), boost::bind (&StreamView::transport_changed, this), gui_context());

View file

@ -40,13 +40,6 @@ class LIBARDOUR_API AudioTrack : public Track
int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
int declick, bool& need_butler); int declick, bool& need_butler);
boost::shared_ptr<Diskstream> create_diskstream ();
void set_diskstream (boost::shared_ptr<Diskstream>);
DataType data_type () const {
return DataType::AUDIO;
}
void freeze_me (InterThreadInfo&); void freeze_me (InterThreadInfo&);
void unfreeze (); void unfreeze ();
@ -62,13 +55,9 @@ class LIBARDOUR_API AudioTrack : public Track
boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0); boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0);
protected: protected:
boost::shared_ptr<AudioDiskstream> audio_diskstream () const;
XMLNode& state (bool full); XMLNode& state (bool full);
private: private:
boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &);
int deprecated_use_diskstream_connections (); int deprecated_use_diskstream_connections ();
void set_state_part_two (); void set_state_part_two ();
void set_state_part_three (); void set_state_part_three ();

View file

@ -80,9 +80,6 @@ class LIBARDOUR_API Auditioner : public Track
int roll_audio (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler); int roll_audio (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
int roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler); int roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
boost::shared_ptr<Diskstream> create_diskstream ();
void set_diskstream (boost::shared_ptr<Diskstream> ds);
/* fake track */ /* fake track */
void set_state_part_two () {} void set_state_part_two () {}
int set_state (const XMLNode&, int) { return 0; } int set_state (const XMLNode&, int) { return 0; }
@ -102,9 +99,6 @@ class LIBARDOUR_API Auditioner : public Track
boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &) boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &)
{ return boost::shared_ptr<Diskstream> (); } { return boost::shared_ptr<Diskstream> (); }
boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
boost::shared_ptr<MidiDiskstream> midi_diskstream() const;
private: private:
boost::shared_ptr<AudioRegion> the_region; boost::shared_ptr<AudioRegion> the_region;
boost::shared_ptr<MidiRegion> midi_region; boost::shared_ptr<MidiRegion> midi_region;

View file

@ -65,12 +65,11 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
bool configure_io (ChanCount in, ChanCount out); bool configure_io (ChanCount in, ChanCount out);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
/** @return A number between 0 and 1, where 0 indicates that the playback buffer /** @return A number between 0 and 1, where 0 indicates that the playback/capture buffer
* is dry (ie the disk subsystem could not keep up) and 1 indicates that the * is dry (ie the disk subsystem could not keep up) and 1 indicates that the
* buffer is full. * buffer is full.
*/ */
virtual float playback_buffer_load() const = 0; virtual float buffer_load() const = 0;
virtual float capture_buffer_load() const = 0;
void set_flag (Flag f) { _flags = Flag (_flags | f); } void set_flag (Flag f) { _flags = Flag (_flags | f); }
void unset_flag (Flag f) { _flags = Flag (_flags & ~f); } void unset_flag (Flag f) { _flags = Flag (_flags & ~f); }
@ -89,8 +88,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
virtual void punch_in() {} virtual void punch_in() {}
virtual void punch_out() {} virtual void punch_out() {}
virtual float buffer_load() const = 0;
bool slaved() const { return _slaved; } bool slaved() const { return _slaved; }
void set_slaved(bool yn) { _slaved = yn; } void set_slaved(bool yn) { _slaved = yn; }
@ -113,8 +110,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
virtual void playlist_modified () {} virtual void playlist_modified () {}
virtual int use_playlist (DataType, boost::shared_ptr<Playlist>); virtual int use_playlist (DataType, boost::shared_ptr<Playlist>);
virtual int use_new_playlist (DataType);
virtual int use_copy_playlist (DataType);
PBD::Signal1<void,DataType> PlaylistChanged; PBD::Signal1<void,DataType> PlaylistChanged;
@ -135,6 +130,8 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
bool _slaved; bool _slaved;
Location* loop_location; Location* loop_location;
bool in_set_state; bool in_set_state;
framepos_t file_frame;
framepos_t playback_sample;
framecnt_t wrap_buffer_size; framecnt_t wrap_buffer_size;
framecnt_t speed_buffer_size; framecnt_t speed_buffer_size;
bool _need_butler; bool _need_butler;
@ -202,7 +199,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
virtual void playlist_changed (const PBD::PropertyChange&) {} virtual void playlist_changed (const PBD::PropertyChange&) {}
virtual void playlist_deleted (boost::weak_ptr<Playlist>); virtual void playlist_deleted (boost::weak_ptr<Playlist>);
virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &, bool) {} virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &, bool) {}
int find_and_use_playlist (DataType, std::string const &);
/* The MIDI stuff */ /* The MIDI stuff */
@ -210,6 +206,8 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
gint _frames_written_to_ringbuffer; gint _frames_written_to_ringbuffer;
gint _frames_read_from_ringbuffer; gint _frames_read_from_ringbuffer;
CubicMidiInterpolation midi_interpolation; CubicMidiInterpolation midi_interpolation;
static void get_location_times (const Location* location, framepos_t* start, framepos_t* end, framepos_t* length);
}; };
} // namespace ARDOUR } // namespace ARDOUR

View file

@ -86,14 +86,18 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor
void adjust_buffering (); void adjust_buffering ();
int can_internal_playback_seek (framecnt_t distance); int can_internal_playback_seek (framecnt_t distance);
int internal_playback_seek (framecnt_t distance);
int seek (framepos_t frame, bool complete_refill = false); int seek (framepos_t frame, bool complete_refill = false);
static PBD::Signal0<void> Underrun; static PBD::Signal0<void> Underrun;
void playlist_modified (); void playlist_modified ();
void reset_tracker ();
protected: protected:
void reset_tracker (); friend class Track;
friend class MidiTrack;
void resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time); void resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time);
boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const; boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
@ -113,8 +117,6 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor
IOChange input_change_pending; IOChange input_change_pending;
framecnt_t wrap_buffer_size; framecnt_t wrap_buffer_size;
framecnt_t speed_buffer_size; framecnt_t speed_buffer_size;
framepos_t file_frame;
framepos_t playback_sample;
MonitorChoice _monitoring_choice; MonitorChoice _monitoring_choice;
int _do_refill_with_alloc (bool partial_fill); int _do_refill_with_alloc (bool partial_fill);
@ -142,7 +144,6 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor
int refill_audio (Sample *mixdown_buffer, float *gain_buffer, framecnt_t fill_level); int refill_audio (Sample *mixdown_buffer, float *gain_buffer, framecnt_t fill_level);
int refill_midi (); int refill_midi ();
int internal_playback_seek (framecnt_t distance);
frameoffset_t calculate_playback_distance (pframes_t); frameoffset_t calculate_playback_distance (pframes_t);
void get_playback (MidiBuffer& dst, framecnt_t nframes); void get_playback (MidiBuffer& dst, framecnt_t nframes);

View file

@ -24,12 +24,14 @@
#include <vector> #include <vector>
#include "ardour/disk_io.h" #include "ardour/disk_io.h"
#include "ardour/midi_buffer.h"
namespace ARDOUR namespace ARDOUR
{ {
class AudioFileSource; class AudioFileSource;
class SMFSource; class SMFSource;
class MidiSource;
class LIBARDOUR_API DiskWriter : public DiskIOProcessor class LIBARDOUR_API DiskWriter : public DiskIOProcessor
{ {
@ -50,8 +52,6 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
virtual XMLNode& state (bool full); virtual XMLNode& state (bool full);
int set_state (const XMLNode&, int version); int set_state (const XMLNode&, int version);
virtual int use_new_write_source (uint32_t n=0) = 0;
std::string write_source_name () const { std::string write_source_name () const {
if (_write_source_name.empty()) { if (_write_source_name.empty()) {
return name(); return name();
@ -72,6 +72,8 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
boost::shared_ptr<SMFSource> midi_write_source () { return _midi_write_source; } boost::shared_ptr<SMFSource> midi_write_source () { return _midi_write_source; }
virtual std::string steal_write_source_name () { return std::string(); } virtual std::string steal_write_source_name () { return std::string(); }
int use_new_write_source (DataType, uint32_t n = 0);
void reset_write_sources (bool, bool force = false);
AlignStyle alignment_style() const { return _alignment_style; } AlignStyle alignment_style() const { return _alignment_style; }
AlignChoice alignment_choice() const { return _alignment_choice; } AlignChoice alignment_choice() const { return _alignment_choice; }
@ -87,8 +89,8 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
bool record_enabled() const { return g_atomic_int_get (const_cast<gint*>(&_record_enabled)); } bool record_enabled() const { return g_atomic_int_get (const_cast<gint*>(&_record_enabled)); }
bool record_safe () const { return g_atomic_int_get (const_cast<gint*>(&_record_safe)); } bool record_safe () const { return g_atomic_int_get (const_cast<gint*>(&_record_safe)); }
virtual void set_record_enabled (bool yn) = 0; virtual void set_record_enabled (bool yn);
virtual void set_record_safe (bool yn) = 0; virtual void set_record_safe (bool yn);
bool destructive() const { return _flags & Destructive; } bool destructive() const { return _flags & Destructive; }
int set_destructive (bool yn); int set_destructive (bool yn);
@ -109,16 +111,31 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
framecnt_t capture_offset() const { return _capture_offset; } framecnt_t capture_offset() const { return _capture_offset; }
virtual void set_capture_offset (); virtual void set_capture_offset ();
int seek (framepos_t frame, bool complete_refill);
static PBD::Signal0<void> Overrun; static PBD::Signal0<void> Overrun;
void set_note_mode (NoteMode m);
/** Emitted when some MIDI data has been received for recording.
* Parameter is the source that it is destined for.
* A caller can get a copy of the data with get_gui_feed_buffer ()
*/
PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded;
PBD::Signal0<void> RecordEnableChanged; PBD::Signal0<void> RecordEnableChanged;
PBD::Signal0<void> RecordSafeChanged; PBD::Signal0<void> RecordSafeChanged;
void check_record_status (framepos_t transport_frame, bool can_record);
void transport_looped (framepos_t transport_frame);
void transport_stopped_wallclock (struct tm&, time_t, bool abort);
protected: protected:
virtual int do_flush (RunContext context, bool force = false) = 0; friend class Track;
int do_flush (RunContext context, bool force = false);
void get_input_sources (); void get_input_sources ();
void check_record_status (framepos_t transport_frame, bool can_record);
void prepare_record_status (framepos_t /*capture_start_frame*/); void prepare_record_status (framepos_t /*capture_start_frame*/);
void set_align_style_from_io(); void set_align_style_from_io();
void setup_destructive_playlist (); void setup_destructive_playlist ();
@ -138,9 +155,6 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
framecnt_t& rec_nframes, framecnt_t& rec_offset framecnt_t& rec_nframes, framecnt_t& rec_offset
); );
static framecnt_t disk_read_chunk_frames;
static framecnt_t disk_write_chunk_frames;
struct CaptureInfo { struct CaptureInfo {
framepos_t start; framepos_t start;
framecnt_t frames; framecnt_t frames;
@ -168,7 +182,7 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
std::list<boost::shared_ptr<Source> > _last_capture_sources; std::list<boost::shared_ptr<Source> > _last_capture_sources;
std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources; std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
static framecnt_t _chunk_frames; static framecnt_t _chunk_frames;
NoteMode _note_mode; NoteMode _note_mode;
@ -176,6 +190,12 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
volatile gint _num_captured_loops; volatile gint _num_captured_loops;
framepos_t _accumulated_capture_offset; framepos_t _accumulated_capture_offset;
/** A buffer that we use to put newly-arrived MIDI data in for
the GUI to read (so that it can update itself).
*/
MidiBuffer _gui_feed_buffer;
mutable Glib::Threads::Mutex _gui_feed_buffer_mutex;
void finish_capture (boost::shared_ptr<ChannelList> c); void finish_capture (boost::shared_ptr<ChannelList> c);
}; };

View file

@ -54,10 +54,6 @@ public:
bool can_be_record_enabled (); bool can_be_record_enabled ();
bool can_be_record_safe (); bool can_be_record_safe ();
DataType data_type () const {
return DataType::MIDI;
}
void freeze_me (InterThreadInfo&); void freeze_me (InterThreadInfo&);
void unfreeze (); void unfreeze ();
@ -156,8 +152,6 @@ private:
virtual boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &); virtual boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &);
boost::shared_ptr<MidiDiskstream> midi_diskstream () const;
void write_out_of_band_data (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, framecnt_t nframes); void write_out_of_band_data (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, framecnt_t nframes);
void set_state_part_two (); void set_state_part_two ();

View file

@ -68,7 +68,7 @@ public:
virtual framepos_t current_capture_start () const = 0; virtual framepos_t current_capture_start () const = 0;
virtual framepos_t current_capture_end () const = 0; virtual framepos_t current_capture_end () const = 0;
virtual void playlist_modified () = 0; virtual void playlist_modified () = 0;
virtual int use_playlist (boost::shared_ptr<Playlist>) = 0; // XXX DISK removed virtual int use_playlist (boost::shared_ptr<Playlist>) = 0;
virtual void set_align_style (AlignStyle, bool force=false) = 0; virtual void set_align_style (AlignStyle, bool force=false) = 0;
virtual void set_align_choice (AlignChoice, bool force=false) = 0; virtual void set_align_choice (AlignChoice, bool force=false) = 0;
virtual int use_copy_playlist () = 0; virtual int use_copy_playlist () = 0;

View file

@ -100,6 +100,13 @@ public:
virtual int init (); virtual int init ();
DataType data_type () const {
/* XXX ultimately nice to do away with this concept, but it is
quite useful for coders and for users too.
*/
return _default_type;
}
boost::shared_ptr<IO> input() const { return _input; } boost::shared_ptr<IO> input() const { return _input; }
boost::shared_ptr<IO> output() const { return _output; } boost::shared_ptr<IO> output() const { return _output; }
IOVector all_inputs () const; IOVector all_inputs () const;

View file

@ -36,15 +36,19 @@ class RouteGroup;
class Source; class Source;
class Region; class Region;
class Diskstream; class Diskstream;
class DiskReader;
class DiskWriter;
class IO; class IO;
class MonitorControl; class MonitorControl;
class RecordEnableControl; class RecordEnableControl;
class RecordSafeControl; class RecordSafeControl;
/** A track is an route (bus) with a recordable diskstream and /** A track is an route (bus) with a recordable diskstream and
* related objects relevant to tracking, playback and editing. * related objects relevant to recording, playback and editing.
* *
* Specifically a track has regions and playlist objects. * Specifically a track has a playlist object that describes material
* to be played from disk, and modifies that object during recording and
* editing.
*/ */
class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskstream class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskstream
{ {
@ -75,14 +79,8 @@ class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskst
bool needs_butler() const { return _needs_butler; } bool needs_butler() const { return _needs_butler; }
virtual DataType data_type () const = 0;
bool can_record(); bool can_record();
void use_new_diskstream ();
virtual boost::shared_ptr<Diskstream> create_diskstream() = 0;
virtual void set_diskstream (boost::shared_ptr<Diskstream>);
void set_latency_compensation (framecnt_t); void set_latency_compensation (framecnt_t);
enum FreezeState { enum FreezeState {
@ -179,18 +177,17 @@ class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskst
AlignChoice alignment_choice () const; AlignChoice alignment_choice () const;
framepos_t current_capture_start () const; framepos_t current_capture_start () const;
framepos_t current_capture_end () const; framepos_t current_capture_end () const;
void playlist_modified ();
int use_playlist (boost::shared_ptr<Playlist>);
void set_align_style (AlignStyle, bool force=false); void set_align_style (AlignStyle, bool force=false);
void set_align_choice (AlignChoice, bool force=false); void set_align_choice (AlignChoice, bool force=false);
void playlist_modified ();
int use_playlist (DataType, boost::shared_ptr<Playlist>);
int find_and_use_playlist (DataType, std::string const & name);
int use_copy_playlist (); int use_copy_playlist ();
int use_new_playlist (); int use_new_playlist ();
void adjust_playback_buffering (); void adjust_playback_buffering ();
void adjust_capture_buffering (); void adjust_capture_buffering ();
PBD::Signal0<void> DiskstreamChanged;
PBD::Signal0<void> FreezeChange; PBD::Signal0<void> FreezeChange;
/* Emitted when our diskstream is set to use a different playlist */
PBD::Signal0<void> PlaylistChanged; PBD::Signal0<void> PlaylistChanged;
PBD::Signal0<void> SpeedChanged; PBD::Signal0<void> SpeedChanged;
PBD::Signal0<void> AlignmentStyleChanged; PBD::Signal0<void> AlignmentStyleChanged;
@ -199,6 +196,11 @@ class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskst
XMLNode& state (bool full); XMLNode& state (bool full);
boost::shared_ptr<Diskstream> _diskstream; boost::shared_ptr<Diskstream> _diskstream;
boost::shared_ptr<DiskReader> _disk_reader;
boost::shared_ptr<DiskWriter> _disk_writer;
boost::shared_ptr<Playlist> _playlists[DataType::num_types];
MeterPoint _saved_meter_point; MeterPoint _saved_meter_point;
TrackMode _mode; TrackMode _mode;
bool _needs_butler; bool _needs_butler;
@ -245,12 +247,6 @@ class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskst
virtual void monitoring_changed (bool, PBD::Controllable::GroupControlDisposition); virtual void monitoring_changed (bool, PBD::Controllable::GroupControlDisposition);
private: private:
virtual boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &) = 0;
void diskstream_playlist_changed ();
void diskstream_speed_changed ();
void diskstream_alignment_style_changed ();
void parameter_changed (std::string const & p); void parameter_changed (std::string const & p);
std::string _diskstream_name; std::string _diskstream_name;

View file

@ -32,6 +32,8 @@
#include "ardour/boost_debug.h" #include "ardour/boost_debug.h"
#include "ardour/buffer_set.h" #include "ardour/buffer_set.h"
#include "ardour/delivery.h" #include "ardour/delivery.h"
#include "ardour/disk_reader.h"
#include "ardour/disk_writer.h"
#include "ardour/meter.h" #include "ardour/meter.h"
#include "ardour/monitor_control.h" #include "ardour/monitor_control.h"
#include "ardour/playlist_factory.h" #include "ardour/playlist_factory.h"
@ -63,97 +65,48 @@ AudioTrack::~AudioTrack ()
} }
} }
boost::shared_ptr<Diskstream> #ifdef XXX_OLD_DESTRUCTIVE_API_XXX
AudioTrack::create_diskstream ()
{
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (AudioDiskstream::Recordable);
if (_mode == Destructive && !Profile->get_trx()) {
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
} else if (_mode == NonLayered){
dflags = AudioDiskstream::Flag(dflags | AudioDiskstream::NonLayered);
}
return boost::shared_ptr<AudioDiskstream> (new AudioDiskstream (_session, name(), dflags));
}
void
AudioTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
Track::set_diskstream (ds);
_diskstream->set_track (this);
if (audio_diskstream()->deprecated_io_node) {
if (!IO::connecting_legal) {
IO::ConnectingLegal.connect_same_thread (*this, boost::bind (&AudioTrack::deprecated_use_diskstream_connections, this));
} else {
deprecated_use_diskstream_connections ();
}
}
_diskstream->set_record_enabled (false);
_diskstream->request_input_monitoring (false);
DiskstreamChanged (); /* EMIT SIGNAL */
}
boost::shared_ptr<AudioDiskstream>
AudioTrack::audio_diskstream() const
{
return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream);
}
int int
AudioTrack::deprecated_use_diskstream_connections () AudioTrack::set_mode (TrackMode m)
{ {
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); if (m != _mode) {
if (diskstream->deprecated_io_node == 0) { if (!Profile->get_trx() && _diskstream->set_destructive (m == Destructive)) {
return 0;
}
XMLNode& node (*diskstream->deprecated_io_node);
/* don't do this more than once. */
diskstream->deprecated_io_node = 0;
float val;
if (node.get_property ("gain", val)) {
_amp->gain_control()->set_value (val, PBD::Controllable::NoGroup);
}
std::string str;
if (node.get_property ("input-connection", str)) {
boost::shared_ptr<Bundle> c = _session.bundle_by_name (str);
if (c == 0) {
error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), str, _name) << endmsg;
if ((c = _session.bundle_by_name (_("in 1"))) == 0) {
error << _("No input bundles available as a replacement")
<< endmsg;
return -1;
} else {
info << string_compose (_("Bundle %1 was not available - \"in 1\" used instead"), str)
<< endmsg;
}
}
_input->connect_ports_to_bundle (c, true, this);
} else if (node.get_property ("inputs", str)) {
if (_input->set_ports (str)) {
error << string_compose(_("improper input channel list in XML node (%1)"), str) << endmsg;
return -1; return -1;
} }
_diskstream->set_non_layered (m == NonLayered);
_mode = m;
TrackModeChanged (); /* EMIT SIGNAL */
} }
return 0; return 0;
} }
bool
AudioTrack::can_use_mode (TrackMode m, bool& bounce_required)
{
switch (m) {
case NonLayered:
case Normal:
bounce_required = false;
return true;
case Destructive:
if (Profile->get_trx()) {
return false;
} else {
return _diskstream->can_become_destructive (bounce_required);
}
break;
default:
return false;
}
}
#endif
int int
AudioTrack::set_state (const XMLNode& node, int version) AudioTrack::set_state (const XMLNode& node, int version)
{ {
@ -279,49 +232,21 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) { if (!lm.locked()) {
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
if (can_internal_playback_seek(::llabs(playback_distance))) {
/* TODO should declick */
internal_playback_seek(playback_distance);
}
return 0; return 0;
} }
framepos_t transport_frame;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
if (n_outputs().n_total() == 0 && _processors.empty()) { if (n_outputs().n_total() == 0 && _processors.empty()) {
return 0; return 0;
} }
if (!_active) { if (!_active) {
silence (nframes); silence (nframes);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) { if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
_meter->reset(); _meter->reset();
} }
return 0; return 0;
} }
transport_frame = _session.transport_frame();
int dret;
framecnt_t playback_distance;
if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
/* need to do this so that the diskstream sets its
playback distance to zero, thus causing diskstream::commit
to do nothing.
*/
BufferSet bufs; /* empty set, no matter - nothing will happen */
dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
need_butler = diskstream->commit (playback_distance);
return dret;
}
_silent = false; _silent = false;
_amp->apply_gain_automation(false); _amp->apply_gain_automation(false);
@ -333,18 +258,10 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
_meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true); _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
} }
if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) { process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!_disk_writer->record_enabled() && _session.transport_rolling()));
need_butler = diskstream->commit (playback_distance);
silence (nframes);
return dret;
}
process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && _session.transport_rolling()));
flush_processor_buffers_locked (nframes); flush_processor_buffers_locked (nframes);
need_butler = diskstream->commit (playback_distance);
return 0; return 0;
} }
@ -354,11 +271,10 @@ AudioTrack::export_stuff (BufferSet& buffers, framepos_t start, framecnt_t nfram
{ {
boost::scoped_array<gain_t> gain_buffer (new gain_t[nframes]); boost::scoped_array<gain_t> gain_buffer (new gain_t[nframes]);
boost::scoped_array<Sample> mix_buffer (new Sample[nframes]); boost::scoped_array<Sample> mix_buffer (new Sample[nframes]);
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
Glib::Threads::RWLock::ReaderLock rlock (_processor_lock); Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist()); boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(playlist());
assert(apl); assert(apl);
assert(buffers.count().n_audio() >= 1); assert(buffers.count().n_audio() >= 1);
@ -373,7 +289,7 @@ AudioTrack::export_stuff (BufferSet& buffers, framepos_t start, framecnt_t nfram
BufferSet::audio_iterator bi = buffers.audio_begin(); BufferSet::audio_iterator bi = buffers.audio_begin();
++bi; ++bi;
for ( ; bi != buffers.audio_end(); ++bi, ++n) { for ( ; bi != buffers.audio_end(); ++bi, ++n) {
if (n < diskstream->n_channels().n_audio()) { if (n < _disk_reader->output_streams().n_audio()) {
if (apl->read (bi->data(), mix_buffer.get(), gain_buffer.get(), start, nframes, n) != nframes) { if (apl->read (bi->data(), mix_buffer.get(), gain_buffer.get(), start, nframes, n) != nframes) {
return -1; return -1;
} }
@ -468,9 +384,8 @@ AudioTrack::freeze_me (InterThreadInfo& itt)
boost::shared_ptr<Playlist> new_playlist; boost::shared_ptr<Playlist> new_playlist;
string dir; string dir;
string region_name; string region_name;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) { if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(playlist())) == 0) {
return; return;
} }
@ -555,8 +470,8 @@ AudioTrack::freeze_me (InterThreadInfo& itt)
new_playlist->set_frozen (true); new_playlist->set_frozen (true);
region->set_locked (true); region->set_locked (true);
diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist)); use_playlist (DataType::AUDIO, boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
diskstream->set_record_enabled (false); _disk_writer->set_record_enabled (false);
_freeze_record.playlist->use(); // prevent deletion _freeze_record.playlist->use(); // prevent deletion
@ -576,7 +491,7 @@ AudioTrack::unfreeze ()
{ {
if (_freeze_record.playlist) { if (_freeze_record.playlist) {
_freeze_record.playlist->release(); _freeze_record.playlist->release();
audio_diskstream()->use_playlist (_freeze_record.playlist); use_playlist (DataType::AUDIO, _freeze_record.playlist);
{ {
Glib::Threads::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc Glib::Threads::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc
@ -601,13 +516,6 @@ AudioTrack::unfreeze ()
boost::shared_ptr<AudioFileSource> boost::shared_ptr<AudioFileSource>
AudioTrack::write_source (uint32_t n) AudioTrack::write_source (uint32_t n)
{ {
boost::shared_ptr<AudioDiskstream> ds = boost::dynamic_pointer_cast<AudioDiskstream> (_diskstream); assert (_disk_writer);
assert (ds); return _disk_writer->audio_write_source (n);
return ds->write_source (n);
}
boost::shared_ptr<Diskstream>
AudioTrack::diskstream_factory (XMLNode const & node)
{
return boost::shared_ptr<Diskstream> (new AudioDiskstream (_session, node));
} }

View file

@ -22,7 +22,6 @@
#include "pbd/error.h" #include "pbd/error.h"
#include "ardour/amp.h" #include "ardour/amp.h"
#include "ardour/audio_diskstream.h"
#include "ardour/audio_port.h" #include "ardour/audio_port.h"
#include "ardour/audioengine.h" #include "ardour/audioengine.h"
#include "ardour/audioplaylist.h" #include "ardour/audioplaylist.h"
@ -30,7 +29,8 @@
#include "ardour/auditioner.h" #include "ardour/auditioner.h"
#include "ardour/data_type.h" #include "ardour/data_type.h"
#include "ardour/delivery.h" #include "ardour/delivery.h"
#include "ardour/midi_diskstream.h" #include "ardour/disk_reader.h"
#include "ardour/midi_playlist.h"
#include "ardour/midi_region.h" #include "ardour/midi_region.h"
#include "ardour/plugin.h" #include "ardour/plugin.h"
#include "ardour/plugin_insert.h" #include "ardour/plugin_insert.h"
@ -215,37 +215,8 @@ Auditioner::data_type () const {
} }
} }
boost::shared_ptr<Diskstream>
Auditioner::create_diskstream () {
{
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
_diskstream_audio = boost::shared_ptr<AudioDiskstream> (new AudioDiskstream (_session, name(), dflags));
}
{
MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
_diskstream_midi = boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
_diskstream_midi->do_refill_with_alloc ();
_diskstream_midi->playlist()->set_orig_track_id (id());
}
return _diskstream_audio;
}
int int
Auditioner::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) { Auditioner::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
if (_midi_audition) {
return roll_midi(nframes, start_frame, end_frame, declick, need_butler);
} else {
return roll_audio(nframes, start_frame, end_frame, declick, need_butler);
}
}
int
Auditioner::roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
{ {
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) { if (!lm.locked()) {
@ -254,17 +225,13 @@ Auditioner::roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end
assert(_active); assert(_active);
framecnt_t playback_distance = nframes;
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
MidiBuffer& mbuf (bufs.get_midi (0));
_silent = false;
ChanCount cnt (DataType::MIDI, 1); _silent = false;
cnt.set (DataType::AUDIO, bufs.count().n_audio()); _amp->apply_gain_automation(false);
bufs.set_count (cnt);
if (_queue_panic) { if (_queue_panic) {
MidiBuffer& mbuf (bufs.get_midi (0));
_queue_panic = false; _queue_panic = false;
for (uint8_t chn = 0; chn < 0xf; ++chn) { for (uint8_t chn = 0; chn < 0xf; ++chn) {
uint8_t buf[3] = { ((uint8_t) (MIDI_CMD_CONTROL | chn)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 }; uint8_t buf[3] = { ((uint8_t) (MIDI_CMD_CONTROL | chn)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
@ -274,20 +241,9 @@ Auditioner::roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end
buf[1] = MIDI_CTL_RESET_CONTROLLERS; buf[1] = MIDI_CTL_RESET_CONTROLLERS;
mbuf.push_back(0, 3, buf); mbuf.push_back(0, 3, buf);
} }
process_output_buffers (bufs, start_frame, start_frame+1, 1, false, false);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
if (d) {
d->flush_buffers (nframes);
}
}
} }
diskstream->get_playback (mbuf, nframes); process_output_buffers (bufs, start_frame, end_frame, nframes, declick, !_session.transport_stopped());
process_output_buffers (bufs, start_frame, end_frame, nframes,
declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i); boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
@ -296,67 +252,23 @@ Auditioner::roll_midi (pframes_t nframes, framepos_t start_frame, framepos_t end
} }
} }
need_butler = diskstream->commit (playback_distance);
return 0; return 0;
} }
int
Auditioner::roll_audio (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) {
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
return 0;
}
assert(n_outputs().n_total() > 0);
assert(_active);
int dret;
framecnt_t playback_distance;
framepos_t transport_frame = _session.transport_frame();
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
_silent = false;
_amp->apply_gain_automation(false);
if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
need_butler = diskstream->commit (playback_distance);
silence (nframes);
return dret;
}
process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && _session.transport_rolling()));
need_butler = diskstream->commit (playback_distance);
return 0;
}
void
Auditioner::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
Track::set_diskstream (ds);
_diskstream->set_track (this);
_diskstream->set_record_enabled (false);
_diskstream->request_input_monitoring (false);
DiskstreamChanged (); /* EMIT SIGNAL */
}
AudioPlaylist& AudioPlaylist&
Auditioner::prepare_playlist () Auditioner::prepare_playlist ()
{ {
// used by CrossfadeEditor::audition() // used by CrossfadeEditor::audition()
_midi_audition = false; _midi_audition = false;
set_diskstream(_diskstream_audio);
if (_synth_added) { if (_synth_added) {
remove_processor(asynth); remove_processor(asynth);
_synth_added = false; _synth_added = false;
} }
// FIXME auditioner is still audio-only // FIXME auditioner is still audio-only
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist()); boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(playlist());
assert(apl); assert(apl);
apl->clear (); apl->clear ();
@ -378,7 +290,7 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
if (boost::dynamic_pointer_cast<AudioRegion>(region) != 0) { if (boost::dynamic_pointer_cast<AudioRegion>(region) != 0) {
_midi_audition = false; _midi_audition = false;
set_diskstream(_diskstream_audio);
if (_synth_added) { if (_synth_added) {
remove_processor(asynth); remove_processor(asynth);
_synth_added = false; _synth_added = false;
@ -390,14 +302,8 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
the_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)); the_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region));
the_region->set_position (0); the_region->set_position (0);
_diskstream->playlist()->drop_regions (); _disk_reader->audio_playlist()->drop_regions ();
_diskstream->playlist()->add_region (the_region, 0, 1); _disk_reader->audio_playlist()->add_region (the_region, 0, 1);
if (_diskstream->n_channels().n_audio() < the_region->n_channels()) {
audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels().n_audio());
} else if (_diskstream->n_channels().n_audio() > the_region->n_channels()) {
audio_diskstream()->remove_channel (_diskstream->n_channels().n_audio() - the_region->n_channels());
}
ProcessorStreams ps; ProcessorStreams ps;
{ {
@ -405,14 +311,14 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
if (configure_processors (&ps)) { if (configure_processors (&ps)) {
error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"), error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
_diskstream->n_channels()) << endmsg; region->n_channels()) << endmsg;
return; return;
} }
} }
} else if (boost::dynamic_pointer_cast<MidiRegion>(region)) { } else if (boost::dynamic_pointer_cast<MidiRegion>(region)) {
_midi_audition = true; _midi_audition = true;
set_diskstream(_diskstream_midi);
the_region.reset(); the_region.reset();
_import_position = region->position(); _import_position = region->position();
@ -420,9 +326,9 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
midi_region = (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (region))); midi_region = (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (region)));
midi_region->set_position (_import_position); midi_region->set_position (_import_position);
_diskstream->playlist()->drop_regions (); _disk_reader->midi_playlist()->drop_regions ();
_diskstream->playlist()->add_region (midi_region, _import_position, 1); _disk_reader->midi_playlist()->add_region (midi_region, _import_position, 1);
midi_diskstream()->reset_tracker(); _disk_reader->reset_tracker();
ProcessorStreams ps; ProcessorStreams ps;
@ -435,7 +341,6 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
lookup_synth(); lookup_synth();
} }
if (!_synth_added && asynth) { if (!_synth_added && asynth) {
int rv = add_processor (asynth, PreFader, &ps, true); int rv = add_processor (asynth, PreFader, &ps, true);
if (rv) { if (rv) {
@ -452,7 +357,7 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
if (configure_processors (&ps)) { if (configure_processors (&ps)) {
error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"), error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
_diskstream->n_channels()) << endmsg; region->n_channels()) << endmsg;
return; return;
} }
} }
@ -485,7 +390,7 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
offset = 0; offset = 0;
} }
_diskstream->seek (offset, true); _disk_reader->seek (offset, true);
current_frame = offset; current_frame = offset;
g_atomic_int_set (&_auditioning, 1); g_atomic_int_set (&_auditioning, 1);
@ -515,9 +420,7 @@ Auditioner::play_audition (framecnt_t nframes)
_seek_complete = false; _seek_complete = false;
_seeking = false; _seeking = false;
_seek_frame = -1; _seek_frame = -1;
if (_midi_audition && midi_diskstream()) { _disk_reader->reset_tracker();
midi_diskstream()->reset_tracker();
}
} }
if(!_seeking) { if(!_seeking) {
@ -604,18 +507,10 @@ ChanCount
Auditioner::input_streams () const Auditioner::input_streams () const
{ {
/* auditioner never has any inputs - its channel configuration /* auditioner never has any inputs - its channel configuration
depends solely on the region we are auditioning. depends solely on the region we are auditioning.
*/ */
if (!_midi_audition && audio_diskstream()) { return _disk_reader->input_streams ();
return audio_diskstream()->n_channels();
}
if (_midi_audition && midi_diskstream()) {
ChanCount cnt (DataType::MIDI, 1);
return cnt;
}
return ChanCount ();
} }
MonitorState MonitorState
@ -624,14 +519,3 @@ Auditioner::monitoring_state () const
return MonitoringDisk; return MonitoringDisk;
} }
boost::shared_ptr<AudioDiskstream>
Auditioner::audio_diskstream() const
{
return boost::dynamic_pointer_cast<AudioDiskstream> (_diskstream);
}
boost::shared_ptr<MidiDiskstream>
Auditioner::midi_diskstream() const
{
return boost::dynamic_pointer_cast<MidiDiskstream> (_diskstream);
}

View file

@ -56,6 +56,8 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
, _slaved (false) , _slaved (false)
, loop_location (0) , loop_location (0)
, in_set_state (false) , in_set_state (false)
, file_frame (0)
, playback_sample (0)
, wrap_buffer_size (0) , wrap_buffer_size (0)
, speed_buffer_size (0) , speed_buffer_size (0)
, _need_butler (false) , _need_butler (false)
@ -394,68 +396,6 @@ DiskIOProcessor::use_playlist (DataType dt, boost::shared_ptr<Playlist> playlist
return 0; return 0;
} }
int
DiskIOProcessor::find_and_use_playlist (DataType dt, const string& name)
{
boost::shared_ptr<Playlist> playlist;
if ((playlist = _session.playlists->by_name (name)) == 0) {
playlist = PlaylistFactory::create (dt, _session, name);
}
if (!playlist) {
error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), name) << endmsg;
return -1;
}
return use_playlist (dt, playlist);
}
int
DiskIOProcessor::use_new_playlist (DataType dt)
{
string newname;
boost::shared_ptr<Playlist> playlist = _playlists[dt];
if (playlist) {
newname = Playlist::bump_name (playlist->name(), _session);
} else {
newname = Playlist::bump_name (_name, _session);
}
playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (dt, _session, newname, hidden()));
if (!playlist) {
return -1;
}
return use_playlist (dt, playlist);
}
int
DiskIOProcessor::use_copy_playlist (DataType dt)
{
assert (_playlists[dt]);
if (_playlists[dt] == 0) {
error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
return -1;
}
string newname;
boost::shared_ptr<Playlist> playlist;
newname = Playlist::bump_name (_playlists[dt]->name(), _session);
if ((playlist = PlaylistFactory::create (_playlists[dt], newname)) == 0) {
return -1;
}
playlist->reset_shares();
return use_playlist (dt, playlist);
}
DiskIOProcessor::ChannelInfo::ChannelInfo (framecnt_t bufsize) DiskIOProcessor::ChannelInfo::ChannelInfo (framecnt_t bufsize)
{ {
buf = new RingBufferNPT<Sample> (bufsize); buf = new RingBufferNPT<Sample> (bufsize);
@ -492,3 +432,24 @@ DiskIOProcessor::set_route (boost::shared_ptr<Route> r)
{ {
_route = r; _route = r;
} }
/** Get the start, end, and length of a location "atomically".
*
* Note: Locations don't get deleted, so all we care about when I say "atomic"
* is that we are always pointing to the same one and using start/length values
* obtained just once. Use this function to achieve this since location being
* a parameter achieves this.
*/
void
DiskIOProcessor::get_location_times(const Location* location,
framepos_t* start,
framepos_t* end,
framepos_t* length)
{
if (location) {
*start = location->start();
*end = location->end();
*length = *end - *start;
}
}

View file

@ -51,8 +51,6 @@ DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f)
, overwrite_offset (0) , overwrite_offset (0)
, _pending_overwrite (false) , _pending_overwrite (false)
, overwrite_queued (false) , overwrite_queued (false)
, file_frame (0)
, playback_sample (0)
, _monitoring_choice (MonitorDisk) , _monitoring_choice (MonitorDisk)
, _gui_feed_buffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)) , _gui_feed_buffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
{ {
@ -143,28 +141,10 @@ DiskReader::state (bool full)
int int
DiskReader::set_state (const XMLNode& node, int version) DiskReader::set_state (const XMLNode& node, int version)
{ {
XMLProperty const * prop;
if (DiskIOProcessor::set_state (node, version)) { if (DiskIOProcessor::set_state (node, version)) {
return -1; return -1;
} }
if ((prop = node.property ("audio-playlist")) == 0) {
return -1;
}
if (find_and_use_playlist (DataType::AUDIO, prop->value())) {
return -1;
}
if ((prop = node.property ("midi-playlist")) == 0) {
return -1;
}
if (find_and_use_playlist (DataType::MIDI, prop->value())) {
return -1;
}
return 0; return 0;
} }
@ -1310,26 +1290,6 @@ DiskReader::get_playback (MidiBuffer& dst, framecnt_t nframes)
//cerr << "----------------\n"; //cerr << "----------------\n";
} }
/** Get the start, end, and length of a location "atomically".
*
* Note: Locations don't get deleted, so all we care about when I say "atomic"
* is that we are always pointing to the same one and using start/length values
* obtained just once. Use this function to achieve this since location being
* a parameter achieves this.
*/
static void
get_location_times(const Location* location,
framepos_t* start,
framepos_t* end,
framepos_t* length)
{
if (location) {
*start = location->start();
*end = location->end();
*length = *end - *start;
}
}
/** @a start is set to the new frame position (TIME) read up to */ /** @a start is set to the new frame position (TIME) read up to */
int int
DiskReader::midi_read (framepos_t& start, framecnt_t dur, bool reversed) DiskReader::midi_read (framepos_t& start, framecnt_t dur, bool reversed)

File diff suppressed because it is too large Load diff

View file

@ -33,10 +33,13 @@
#include "pbd/types_convert.h" #include "pbd/types_convert.h"
#include "evoral/midi_util.h" #include "evoral/midi_util.h"
#include "ardour/amp.h"
#include "ardour/beats_frames_converter.h" #include "ardour/beats_frames_converter.h"
#include "ardour/buffer_set.h" #include "ardour/buffer_set.h"
#include "ardour/debug.h" #include "ardour/debug.h"
#include "ardour/delivery.h" #include "ardour/delivery.h"
#include "ardour/disk_reader.h"
#include "ardour/disk_writer.h"
#include "ardour/event_type_map.h" #include "ardour/event_type_map.h"
#include "ardour/meter.h" #include "ardour/meter.h"
#include "ardour/midi_diskstream.h" #include "ardour/midi_diskstream.h"
@ -72,11 +75,15 @@ MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
: Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI) : Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
, _immediate_events(6096) // FIXME: size? , _immediate_events(6096) // FIXME: size?
, _step_edit_ring_buffer(64) // FIXME: size? , _step_edit_ring_buffer(64) // FIXME: size?
, _note_mode(Sustained) , _note_mode (Sustained)
, _step_editing (false) , _step_editing (false)
, _input_active (true) , _input_active (true)
{ {
_session.SessionLoaded.connect_same_thread (*this, boost::bind (&MidiTrack::restore_controls, this)); _session.SessionLoaded.connect_same_thread (*this, boost::bind (&MidiTrack::restore_controls, this));
_disk_writer->set_note_mode (_note_mode);
_disk_reader->reset_tracker ();
} }
MidiTrack::~MidiTrack () MidiTrack::~MidiTrack ()
@ -126,36 +133,6 @@ MidiTrack::can_be_record_enabled ()
return Track::can_be_record_enabled (); return Track::can_be_record_enabled ();
} }
void
MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
/* We have to do this here, as Track::set_diskstream will cause a buffer refill,
and the diskstream must be set up to fill its buffers using the correct _note_mode.
*/
boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
mds->set_note_mode (_note_mode);
Track::set_diskstream (ds);
mds->reset_tracker ();
_diskstream->set_track (this);
_diskstream->set_record_enabled (false);
_diskstream_data_recorded_connection.disconnect ();
mds->DataRecorded.connect_same_thread (
_diskstream_data_recorded_connection,
boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
DiskstreamChanged (); /* EMIT SIGNAL */
}
boost::shared_ptr<MidiDiskstream>
MidiTrack::midi_diskstream() const
{
return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
}
int int
MidiTrack::set_state (const XMLNode& node, int version) MidiTrack::set_state (const XMLNode& node, int version)
{ {
@ -323,10 +300,6 @@ MidiTrack::set_state_part_two ()
} }
} }
if (midi_diskstream ()) {
midi_diskstream()->set_block_size (_session.get_block_size ());
}
return; return;
} }
@ -364,18 +337,11 @@ int
MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
{ {
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) { if (!lm.locked()) {
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
if (can_internal_playback_seek(::llabs(playback_distance))) {
/* TODO should declick, and/or note-off */
internal_playback_seek(playback_distance);
}
return 0; return 0;
} }
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
if (n_outputs().n_total() == 0 && _processors.empty()) { if (n_outputs().n_total() == 0 && _processors.empty()) {
return 0; return 0;
} }
@ -388,22 +354,8 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
return 0; return 0;
} }
framepos_t transport_frame = _session.transport_frame(); _silent = false;
_amp->apply_gain_automation (false);
int dret;
framecnt_t playback_distance;
if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
/* need to do this so that the diskstream sets its
playback distance to zero, thus causing diskstream::commit
to do nothing.
*/
BufferSet bufs; /* empty set - is OK, since nothing will happen */
dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
need_butler = diskstream->commit (playback_distance);
return dret;
}
BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
@ -416,47 +368,16 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
_meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true); _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
} }
_silent = false;
if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
need_butler = diskstream->commit (playback_distance);
silence (nframes);
return dret;
}
/* note diskstream uses our filter to filter/map playback channels appropriately. */
if (monitoring_state() == MonitoringInput) {
/* not actually recording, but we want to hear the input material anyway,
at least potentially (depending on monitoring options)
*/
/* because the playback buffer is event based and not a
* continuous stream, we need to make sure that we empty
* it of events every cycle to avoid it filling up with events
* read from disk, while we are actually monitoring input
*/
diskstream->flush_playback (start_frame, end_frame);
}
/* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */ /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
write_out_of_band_data (bufs, start_frame, end_frame, nframes); write_out_of_band_data (bufs, start_frame, end_frame, nframes);
/* final argument: don't waste time with automation if we're not recording or rolling */ /* final argument: don't waste time with automation if we're not recording or rolling */
process_output_buffers (bufs, start_frame, end_frame, nframes, process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!_disk_writer->record_enabled() && !_session.transport_stopped()));
declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
flush_processor_buffers_locked (nframes); flush_processor_buffers_locked (nframes);
need_butler = diskstream->commit (playback_distance);
return 0; return 0;
} }
@ -485,7 +406,7 @@ MidiTrack::realtime_locate ()
(*i)->realtime_locate (); (*i)->realtime_locate ();
} }
midi_diskstream()->reset_tracker (); _disk_reader->reset_tracker ();
} }
void void
@ -507,7 +428,7 @@ MidiTrack::non_realtime_locate (framepos_t pos)
{ {
Track::non_realtime_locate(pos); Track::non_realtime_locate(pos);
boost::shared_ptr<MidiPlaylist> playlist = midi_diskstream()->midi_playlist(); boost::shared_ptr<MidiPlaylist> playlist = _disk_writer->midi_playlist();
if (!playlist) { if (!playlist) {
return; return;
} }
@ -612,11 +533,9 @@ MidiTrack::export_stuff (BufferSet& buffers,
return -1; return -1;
} }
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
Glib::Threads::RWLock::ReaderLock rlock (_processor_lock); Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist>(diskstream->playlist()); boost::shared_ptr<MidiPlaylist> mpl = _disk_writer->midi_playlist();
if (!mpl) { if (!mpl) {
return -2; return -2;
} }
@ -665,7 +584,7 @@ void
MidiTrack::set_note_mode (NoteMode m) MidiTrack::set_note_mode (NoteMode m)
{ {
_note_mode = m; _note_mode = m;
midi_diskstream()->set_note_mode(m); _disk_writer->set_note_mode(m);
} }
std::string std::string
@ -809,7 +728,7 @@ MidiTrack::set_step_editing (bool yn)
boost::shared_ptr<SMFSource> boost::shared_ptr<SMFSource>
MidiTrack::write_source (uint32_t) MidiTrack::write_source (uint32_t)
{ {
return midi_diskstream()->write_source (); return _disk_writer->midi_write_source ();
} }
void void
@ -847,7 +766,7 @@ MidiTrack::set_capture_channel_mask (uint16_t mask)
boost::shared_ptr<MidiPlaylist> boost::shared_ptr<MidiPlaylist>
MidiTrack::midi_playlist () MidiTrack::midi_playlist ()
{ {
return midi_diskstream()->midi_playlist (); return boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
} }
void void
@ -906,7 +825,7 @@ MidiTrack::diskstream_factory (XMLNode const & node)
boost::shared_ptr<MidiBuffer> boost::shared_ptr<MidiBuffer>
MidiTrack::get_gui_feed_buffer () const MidiTrack::get_gui_feed_buffer () const
{ {
return midi_diskstream()->get_gui_feed_buffer (); return _disk_reader->get_gui_feed_buffer ();
} }
void void
@ -922,7 +841,7 @@ MidiTrack::act_on_mute ()
/* If we haven't got a diskstream yet, there's nothing to worry about, /* If we haven't got a diskstream yet, there's nothing to worry about,
and we can't call get_channel_mask() anyway. and we can't call get_channel_mask() anyway.
*/ */
if (!midi_diskstream()) { if (!_disk_writer) {
return; return;
} }
@ -945,7 +864,7 @@ MidiTrack::act_on_mute ()
} }
/* Resolve active notes. */ /* Resolve active notes. */
midi_diskstream()->resolve_tracker(_immediate_events, Port::port_offset()); _disk_reader->resolve_tracker(_immediate_events, Port::port_offset());
} }
} }
@ -967,11 +886,7 @@ MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition
} }
} }
boost::shared_ptr<MidiDiskstream> md (midi_diskstream()); _disk_reader->reset_tracker ();
if (md) {
md->reset_tracker ();
}
} }
MonitorState MonitorState

View file

@ -1546,7 +1546,6 @@ Session::hookup_io ()
if (a->init()) { if (a->init()) {
throw failed_constructor (); throw failed_constructor ();
} }
a->use_new_diskstream ();
auditioner = a; auditioner = a;
} }
@ -2625,8 +2624,6 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, bool s
track->set_strict_io (true); track->set_strict_io (true);
} }
track->use_new_diskstream();
BOOST_MARK_TRACK (track); BOOST_MARK_TRACK (track);
{ {
@ -2648,8 +2645,6 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, bool s
route_group->add (track); route_group->add (track);
} }
track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
new_routes.push_back (track); new_routes.push_back (track);
ret.push_back (track); ret.push_back (track);
} }
@ -3223,8 +3218,6 @@ Session::new_audio_track (int input_channels, int output_channels, RouteGroup* r
} }
} }
track->use_new_diskstream();
BOOST_MARK_TRACK (track); BOOST_MARK_TRACK (track);
{ {
@ -3253,8 +3246,6 @@ Session::new_audio_track (int input_channels, int output_channels, RouteGroup* r
track->non_realtime_input_change(); track->non_realtime_input_change();
track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
new_routes.push_back (track); new_routes.push_back (track);
ret.push_back (track); ret.push_back (track);
} }

View file

@ -1845,7 +1845,7 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version)
return ret; return ret;
} }
track->set_diskstream (*i); // XXX DISK NEED TO SET UP DISKSTREAM ???
BOOST_MARK_TRACK (track); BOOST_MARK_TRACK (track);
ret = track; ret = track;

View file

@ -21,11 +21,14 @@
#include "ardour/debug.h" #include "ardour/debug.h"
#include "ardour/delivery.h" #include "ardour/delivery.h"
#include "ardour/diskstream.h" #include "ardour/diskstream.h"
#include "ardour/disk_reader.h"
#include "ardour/disk_writer.h"
#include "ardour/event_type_map.h" #include "ardour/event_type_map.h"
#include "ardour/io_processor.h" #include "ardour/io_processor.h"
#include "ardour/meter.h" #include "ardour/meter.h"
#include "ardour/monitor_control.h" #include "ardour/monitor_control.h"
#include "ardour/playlist.h" #include "ardour/playlist.h"
#include "ardour/playlist_factory.h"
#include "ardour/port.h" #include "ardour/port.h"
#include "ardour/processor.h" #include "ardour/processor.h"
#include "ardour/profile.h" #include "ardour/profile.h"
@ -51,6 +54,25 @@ Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode
{ {
_freeze_record.state = NoFreeze; _freeze_record.state = NoFreeze;
_declickable = true; _declickable = true;
DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
if (_mode == Destructive && !Profile->get_trx()) {
dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive);
} else if (_mode == NonLayered){
dflags = DiskIOProcessor::Flag(dflags | DiskIOProcessor::NonLayered);
}
_disk_reader.reset (new DiskReader (sess, name, dflags));
_disk_reader->set_block_size (_session.get_block_size ());
_disk_reader->set_route (shared_from_this());
_disk_reader->do_refill_with_alloc ();
_disk_writer.reset (new DiskWriter (sess, name, dflags));
_disk_writer->set_block_size (_session.get_block_size ());
_disk_writer->set_route (shared_from_this());
} }
Track::~Track () Track::~Track ()
@ -86,18 +108,6 @@ Track::init ()
return 0; return 0;
} }
void
Track::use_new_diskstream ()
{
boost::shared_ptr<Diskstream> ds = create_diskstream ();
ds->do_refill_with_alloc ();
ds->set_block_size (_session.get_block_size ());
ds->playlist()->set_orig_track_id (id());
set_diskstream (ds);
}
XMLNode& XMLNode&
Track::get_state () Track::get_state ()
{ {
@ -128,18 +138,12 @@ Track::set_state (const XMLNode& node, int version)
XMLNode* child; XMLNode* child;
if (version >= 3000) { if (version >= 3000 && version < 4000) {
if ((child = find_named_node (node, X_("Diskstream"))) != 0) { if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
boost::shared_ptr<Diskstream> ds = diskstream_factory (*child); /* XXX DISK ... setup reader/writer from XML */
ds->do_refill_with_alloc ();
set_diskstream (ds);
} }
} }
if (_diskstream) {
_diskstream->playlist()->set_orig_track_id (id());
}
/* set rec-enable control *AFTER* setting up diskstream, because it may /* set rec-enable control *AFTER* setting up diskstream, because it may
want to operate on the diskstream as it sets its own state want to operate on the diskstream as it sets its own state
*/ */
@ -406,7 +410,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
*/ */
} }
_diskstream->check_record_status (start_frame, can_record); _disk_writer->check_record_status (start_frame, can_record);
bool be_silent; bool be_silent;
@ -443,7 +447,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
if (_meter_point == MeterInput) { if (_meter_point == MeterInput) {
/* still need input monitoring and metering */ /* still need input monitoring and metering */
bool const track_rec = _diskstream->record_enabled (); bool const track_rec = _disk_writer->record_enabled ();
bool const auto_input = _session.config.get_auto_input (); bool const auto_input = _session.config.get_auto_input ();
bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring; bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
bool const tape_machine_mode = Config->get_tape_machine_mode (); bool const tape_machine_mode = Config->get_tape_machine_mode ();
@ -502,10 +506,11 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*
{ {
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
if (!lm.locked()) { if (!lm.locked()) {
framecnt_t playback_distance = _diskstream->calculate_playback_distance(nframes); // XXX DISK reader needs to seek ahead the correct distance ?? OR DOES IT ?
if (can_internal_playback_seek(playback_distance)) { //framecnt_t playback_distance = _disk_reader->calculate_playback_distance(nframes);
internal_playback_seek(playback_distance); //if (can_internal_playback_seek(playback_distance)) {
} // internal_playback_seek(playback_distance);
//}
return 0; return 0;
} }
@ -524,42 +529,9 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*
silence (nframes); silence (nframes);
flush_processor_buffers_locked (nframes); flush_processor_buffers_locked (nframes);
framecnt_t playback_distance; //BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true));
// XXXX DISKWRITER/READER ADVANCE, SET need_butler
BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true)); return 0;
int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false);
need_butler = _diskstream->commit (playback_distance);
return dret;
}
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->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_speed_changed ()
{
SpeedChanged (); /* EMIT SIGNAL */
}
void
Track::diskstream_alignment_style_changed ()
{
AlignmentStyleChanged (); /* EMIT SIGNAL */
} }
boost::shared_ptr<Playlist> boost::shared_ptr<Playlist>
@ -571,103 +543,100 @@ Track::playlist ()
void void
Track::request_input_monitoring (bool m) Track::request_input_monitoring (bool m)
{ {
_diskstream->request_input_monitoring (m); // XXX DISK
} }
void void
Track::ensure_input_monitoring (bool m) Track::ensure_input_monitoring (bool m)
{ {
_diskstream->ensure_input_monitoring (m); // XXX DISK
} }
bool bool
Track::destructive () const Track::destructive () const
{ {
return _diskstream->destructive (); return _disk_writer->destructive ();
} }
list<boost::shared_ptr<Source> > & list<boost::shared_ptr<Source> > &
Track::last_capture_sources () Track::last_capture_sources ()
{ {
return _diskstream->last_capture_sources (); return _disk_writer->last_capture_sources ();
} }
void void
Track::set_capture_offset () Track::set_capture_offset ()
{ {
_diskstream->set_capture_offset (); _disk_writer->set_capture_offset ();
} }
std::string std::string
Track::steal_write_source_name() Track::steal_write_source_name()
{ {
return _diskstream->steal_write_source_name (); return _disk_writer->steal_write_source_name ();
} }
void void
Track::reset_write_sources (bool r, bool force) Track::reset_write_sources (bool r, bool force)
{ {
_diskstream->reset_write_sources (r, force); _disk_writer->reset_write_sources (r, force);
} }
float float
Track::playback_buffer_load () const Track::playback_buffer_load () const
{ {
return _diskstream->playback_buffer_load (); return _disk_reader->buffer_load ();
} }
float float
Track::capture_buffer_load () const Track::capture_buffer_load () const
{ {
return _diskstream->capture_buffer_load (); return _disk_writer->buffer_load ();
} }
int int
Track::do_refill () Track::do_refill ()
{ {
return _diskstream->do_refill (); return _disk_reader->do_refill ();
} }
int int
Track::do_flush (RunContext c, bool force) Track::do_flush (RunContext c, bool force)
{ {
return _diskstream->do_flush (c, force); return _disk_writer->do_flush (c, force);
} }
void void
Track::set_pending_overwrite (bool o) Track::set_pending_overwrite (bool o)
{ {
_diskstream->set_pending_overwrite (o); _disk_reader->set_pending_overwrite (o);
} }
int int
Track::seek (framepos_t p, bool complete_refill) Track::seek (framepos_t p, bool complete_refill)
{ {
return _diskstream->seek (p, complete_refill); if (_disk_reader->seek (p, complete_refill)) {
return -1;
}
return _disk_writer->seek (p, complete_refill);
} }
bool bool
Track::hidden () const Track::hidden () const
{ {
return _diskstream->hidden (); return _disk_writer->hidden () || _disk_reader->hidden();
} }
int int
Track::can_internal_playback_seek (framecnt_t p) Track::can_internal_playback_seek (framecnt_t p)
{ {
return _diskstream->can_internal_playback_seek (p); return _disk_reader->can_internal_playback_seek (p);
} }
int int
Track::internal_playback_seek (framecnt_t p) Track::internal_playback_seek (framecnt_t p)
{ {
return _diskstream->internal_playback_seek (p); return _disk_reader->internal_playback_seek (p);
}
void
Track::non_realtime_input_change ()
{
_diskstream->non_realtime_input_change ();
} }
void void
@ -679,74 +648,82 @@ Track::non_realtime_locate (framepos_t p)
/* don't waste i/o cycles and butler calls /* don't waste i/o cycles and butler calls
for hidden (secret) tracks for hidden (secret) tracks
*/ */
_diskstream->non_realtime_locate (p); _disk_reader->non_realtime_locate (p);
_disk_writer->non_realtime_locate (p);
} }
} }
void void
Track::non_realtime_set_speed () Track::non_realtime_set_speed ()
{ {
_diskstream->non_realtime_set_speed (); _disk_reader->non_realtime_set_speed ();
} }
int int
Track::overwrite_existing_buffers () Track::overwrite_existing_buffers ()
{ {
return _diskstream->overwrite_existing_buffers (); return _disk_reader->overwrite_existing_buffers ();
} }
framecnt_t framecnt_t
Track::get_captured_frames (uint32_t n) const Track::get_captured_frames (uint32_t n) const
{ {
return _diskstream->get_captured_frames (n); return _disk_writer->get_captured_frames (n);
} }
int int
Track::set_loop (Location* l) Track::set_loop (Location* l)
{ {
return _diskstream->set_loop (l); if (_disk_reader->set_loop (l)) {
return -1;
}
return _disk_writer->set_loop (l);
} }
void void
Track::transport_looped (framepos_t p) Track::transport_looped (framepos_t p)
{ {
_diskstream->transport_looped (p); return _disk_writer->transport_looped (p);
} }
bool bool
Track::realtime_set_speed (double s, bool g) Track::realtime_set_speed (double s, bool g)
{ {
return _diskstream->realtime_set_speed (s, g); if (_disk_reader->realtime_set_speed (s, g)) {
return -1;
}
return _disk_writer->realtime_set_speed (s, g);
} }
void void
Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g) Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
{ {
_diskstream->transport_stopped_wallclock (n, t, g); _disk_writer->transport_stopped_wallclock (n, t, g);
} }
bool bool
Track::pending_overwrite () const Track::pending_overwrite () const
{ {
return _diskstream->pending_overwrite (); return _disk_reader->pending_overwrite ();
} }
double double
Track::speed () const Track::speed () const
{ {
return _diskstream->speed (); return _disk_reader->speed ();
} }
void void
Track::prepare_to_stop (framepos_t t, framepos_t a) Track::prepare_to_stop (framepos_t t, framepos_t a)
{ {
_diskstream->prepare_to_stop (t, a); _disk_writer->prepare_to_stop (t, a);
} }
void void
Track::set_slaved (bool s) Track::set_slaved (bool s)
{ {
_diskstream->set_slaved (s); _disk_reader->set_slaved (s);
_disk_writer->set_slaved (s);
} }
ChanCount ChanCount
@ -758,71 +735,113 @@ Track::n_channels ()
framepos_t framepos_t
Track::get_capture_start_frame (uint32_t n) const Track::get_capture_start_frame (uint32_t n) const
{ {
return _diskstream->get_capture_start_frame (n); return _disk_writer->get_capture_start_frame (n);
} }
AlignStyle AlignStyle
Track::alignment_style () const Track::alignment_style () const
{ {
return _diskstream->alignment_style (); return _disk_writer->alignment_style ();
} }
AlignChoice AlignChoice
Track::alignment_choice () const Track::alignment_choice () const
{ {
return _diskstream->alignment_choice (); return _disk_writer->alignment_choice ();
} }
framepos_t framepos_t
Track::current_capture_start () const Track::current_capture_start () const
{ {
return _diskstream->current_capture_start (); return _disk_writer->current_capture_start ();
} }
framepos_t framepos_t
Track::current_capture_end () const Track::current_capture_end () const
{ {
return _diskstream->current_capture_end (); return _disk_writer->current_capture_end ();
} }
void void
Track::playlist_modified () Track::playlist_modified ()
{ {
_diskstream->playlist_modified (); _disk_reader->playlist_modified ();
} }
int int
Track::use_playlist (boost::shared_ptr<Playlist> p) Track::find_and_use_playlist (DataType dt, const string& name)
{ {
int ret = _diskstream->use_playlist (p); boost::shared_ptr<Playlist> playlist;
if (ret == 0) {
p->set_orig_track_id (id()); if ((playlist = _session.playlists->by_name (name)) == 0) {
playlist = PlaylistFactory::create (dt, _session, name);
} }
if (!playlist) {
error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), name) << endmsg;
return -1;
}
return use_playlist (dt, playlist);
}
int
Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
{
int ret;
if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
p->set_orig_track_id (id());
}
}
return ret; return ret;
} }
int int
Track::use_copy_playlist () Track::use_copy_playlist ()
{ {
int ret = _diskstream->use_copy_playlist (); assert (_playlists[data_type()]);
if (ret == 0) { if (_playlists[data_type()] == 0) {
_diskstream->playlist()->set_orig_track_id (id()); error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
return -1;
} }
return ret; string newname;
boost::shared_ptr<Playlist> playlist;
newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
return -1;
}
playlist->reset_shares();
return use_playlist (data_type(), playlist);
} }
int int
Track::use_new_playlist () Track::use_new_playlist ()
{ {
int ret = _diskstream->use_new_playlist (); string newname;
boost::shared_ptr<Playlist> playlist = _playlists[data_type()];
if (ret == 0) { if (playlist) {
_diskstream->playlist()->set_orig_track_id (id()); newname = Playlist::bump_name (playlist->name(), _session);
} else {
newname = Playlist::bump_name (_name, _session);
} }
return ret; playlist = PlaylistFactory::create (data_type(), _session, newname, hidden());
if (!playlist) {
return -1;
}
return use_playlist (data_type(), playlist);
} }
void void
@ -955,7 +974,7 @@ Track::monitoring_state () const
*/ */
bool const roll = _session.transport_rolling (); bool const roll = _session.transport_rolling ();
bool const track_rec = _diskstream->record_enabled (); bool const track_rec = _disk_writer->record_enabled ();
bool const auto_input = _session.config.get_auto_input (); bool const auto_input = _session.config.get_auto_input ();
bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring; bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
bool const tape_machine_mode = Config->get_tape_machine_mode (); bool const tape_machine_mode = Config->get_tape_machine_mode ();
@ -1078,10 +1097,16 @@ Track::metering_state () const
bool rv; bool rv;
if (_session.transport_rolling ()) { if (_session.transport_rolling ()) {
// audio_track.cc || midi_track.cc roll() runs meter IFF: // audio_track.cc || midi_track.cc roll() runs meter IFF:
rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled()); rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
} else { } else {
// track no_roll() always metering if // track no_roll() always metering if
rv = _meter_point == MeterInput; rv = _meter_point == MeterInput;
} }
return rv ? MeteringInput : MeteringRoute; return rv ? MeteringInput : MeteringRoute;
} }
void
Track::non_realtime_input_change ()
{
// XXX DISK do we need to do anything here anymore ?
}