mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
get diskreader working, and remove per-track varispeed API and mechanism
This commit is contained in:
parent
fe8c70e6fc
commit
2a1dccabc9
12 changed files with 182 additions and 177 deletions
|
|
@ -78,7 +78,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
|
||||||
bool recordable() const { return _flags & Recordable; }
|
bool recordable() const { return _flags & Recordable; }
|
||||||
bool non_layered() const { return _flags & NonLayered; }
|
bool non_layered() const { return _flags & NonLayered; }
|
||||||
bool reversed() const { return _actual_speed < 0.0f; }
|
bool reversed() const { return _actual_speed < 0.0f; }
|
||||||
double speed() const { return _visible_speed; }
|
|
||||||
|
|
||||||
virtual void non_realtime_locate (framepos_t);
|
virtual void non_realtime_locate (framepos_t);
|
||||||
|
|
||||||
|
|
@ -122,9 +121,7 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
|
||||||
protected:
|
protected:
|
||||||
Flag _flags;
|
Flag _flags;
|
||||||
uint32_t i_am_the_modifier;
|
uint32_t i_am_the_modifier;
|
||||||
double _visible_speed;
|
|
||||||
double _actual_speed;
|
double _actual_speed;
|
||||||
double _speed;
|
|
||||||
double _target_speed;
|
double _target_speed;
|
||||||
/* items needed for speed change logic */
|
/* items needed for speed change logic */
|
||||||
bool _buffer_reallocation_required;
|
bool _buffer_reallocation_required;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
|
||||||
|
|
||||||
void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double speed, pframes_t /*nframes*/, bool /*result_required*/);
|
void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double speed, pframes_t /*nframes*/, bool /*result_required*/);
|
||||||
void non_realtime_locate (framepos_t);
|
void non_realtime_locate (framepos_t);
|
||||||
|
void realtime_handle_transport_stopped ();
|
||||||
|
|
||||||
virtual XMLNode& state (bool full);
|
virtual XMLNode& state (bool full);
|
||||||
int set_state (const XMLNode&, int version);
|
int set_state (const XMLNode&, int version);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ public:
|
||||||
|
|
||||||
int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
|
int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
|
||||||
|
|
||||||
void realtime_handle_transport_stopped ();
|
|
||||||
void realtime_locate ();
|
void realtime_locate ();
|
||||||
void non_realtime_locate (framepos_t);
|
void non_realtime_locate (framepos_t);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -388,7 +388,8 @@ public:
|
||||||
virtual XMLNode& get_template();
|
virtual XMLNode& get_template();
|
||||||
|
|
||||||
XMLNode& get_processor_state ();
|
XMLNode& get_processor_state ();
|
||||||
virtual void set_processor_state (const XMLNode&);
|
void set_processor_state (const XMLNode&);
|
||||||
|
virtual bool set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure);
|
||||||
|
|
||||||
boost::weak_ptr<Route> weakroute ();
|
boost::weak_ptr<Route> weakroute ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ class LIBARDOUR_API Track : public Route, public Recordable
|
||||||
MonitorState monitoring_state () const;
|
MonitorState monitoring_state () const;
|
||||||
MeterState metering_state () const;
|
MeterState metering_state () const;
|
||||||
|
|
||||||
|
bool set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure);
|
||||||
|
|
||||||
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
|
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
|
||||||
bool state_changing);
|
bool state_changing);
|
||||||
|
|
||||||
|
|
@ -155,6 +157,7 @@ class LIBARDOUR_API Track : public Route, public Recordable
|
||||||
int can_internal_playback_seek (framecnt_t);
|
int can_internal_playback_seek (framecnt_t);
|
||||||
int internal_playback_seek (framecnt_t);
|
int internal_playback_seek (framecnt_t);
|
||||||
void non_realtime_locate (framepos_t);
|
void non_realtime_locate (framepos_t);
|
||||||
|
void realtime_handle_transport_stopped ();
|
||||||
void non_realtime_set_speed ();
|
void non_realtime_set_speed ();
|
||||||
int overwrite_existing_buffers ();
|
int overwrite_existing_buffers ();
|
||||||
framecnt_t get_captured_frames (uint32_t n = 0) const;
|
framecnt_t get_captured_frames (uint32_t n = 0) const;
|
||||||
|
|
@ -163,7 +166,6 @@ class LIBARDOUR_API Track : public Route, public Recordable
|
||||||
bool realtime_set_speed (double, bool);
|
bool realtime_set_speed (double, bool);
|
||||||
void transport_stopped_wallclock (struct tm &, time_t, bool);
|
void transport_stopped_wallclock (struct tm &, time_t, bool);
|
||||||
bool pending_overwrite () const;
|
bool pending_overwrite () const;
|
||||||
double speed () const;
|
|
||||||
void prepare_to_stop (framepos_t, framepos_t);
|
void prepare_to_stop (framepos_t, framepos_t);
|
||||||
void set_slaved (bool);
|
void set_slaved (bool);
|
||||||
ChanCount n_channels ();
|
ChanCount n_channels ();
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,7 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
|
||||||
: Processor (s, str)
|
: Processor (s, str)
|
||||||
, _flags (f)
|
, _flags (f)
|
||||||
, i_am_the_modifier (false)
|
, i_am_the_modifier (false)
|
||||||
, _visible_speed (0.0)
|
|
||||||
, _actual_speed (0.0)
|
, _actual_speed (0.0)
|
||||||
, _speed (0.0)
|
|
||||||
, _target_speed (0.0)
|
, _target_speed (0.0)
|
||||||
, _buffer_reallocation_required (false)
|
, _buffer_reallocation_required (false)
|
||||||
, _seek_required (false)
|
, _seek_required (false)
|
||||||
|
|
@ -170,11 +168,7 @@ DiskIOProcessor::configure_io (ChanCount in, ChanCount out)
|
||||||
midi_interpolation.add_channel_to (0,0);
|
midi_interpolation.add_channel_to (0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (speed() != 1.0f || speed() != -1.0f) {
|
seek (_session.transport_frame());
|
||||||
seek ((framepos_t) (_session.transport_frame() * (double) speed()));
|
|
||||||
} else {
|
|
||||||
seek (_session.transport_frame());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Processor::configure_io (in, out);
|
return Processor::configure_io (in, out);
|
||||||
}
|
}
|
||||||
|
|
@ -206,11 +200,7 @@ DiskIOProcessor::non_realtime_locate (framepos_t location)
|
||||||
{
|
{
|
||||||
/* now refill channel buffers */
|
/* now refill channel buffers */
|
||||||
|
|
||||||
if (speed() != 1.0f || speed() != -1.0f) {
|
seek (location, true);
|
||||||
seek ((framepos_t) (location * (double) speed()), true);
|
|
||||||
} else {
|
|
||||||
seek (location, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -221,39 +211,27 @@ DiskIOProcessor::non_realtime_set_speed ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_seek_required) {
|
if (_seek_required) {
|
||||||
if (speed() != 1.0f || speed() != -1.0f) {
|
seek (_session.transport_frame(), true);
|
||||||
seek ((framepos_t) (_session.transport_frame() * (double) speed()), true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
seek (_session.transport_frame(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
_seek_required = false;
|
_seek_required = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DiskIOProcessor::realtime_set_speed (double sp, bool global)
|
DiskIOProcessor::realtime_set_speed (double new_speed, bool global)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
double new_speed = sp * _session.transport_speed();
|
|
||||||
|
|
||||||
if (_visible_speed != sp) {
|
DEBUG_TRACE (DEBUG::Transport, string_compose ("%1 will run at %2\n", name(), new_speed));
|
||||||
_visible_speed = sp;
|
|
||||||
|
if (_target_speed != new_speed) {
|
||||||
|
_target_speed = new_speed;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (new_speed != _actual_speed) {
|
framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() * fabs (new_speed)) + 2;
|
||||||
|
|
||||||
framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() *
|
|
||||||
fabs (new_speed)) + 2;
|
|
||||||
|
|
||||||
if (required_wrap_size > wrap_buffer_size) {
|
if (required_wrap_size > wrap_buffer_size) {
|
||||||
_buffer_reallocation_required = true;
|
_buffer_reallocation_required = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_actual_speed = new_speed;
|
|
||||||
_target_speed = fabs(_actual_speed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
|
|
||||||
|
|
@ -112,13 +112,11 @@ DiskReader::default_chunk_frames()
|
||||||
bool
|
bool
|
||||||
DiskReader::set_name (string const & str)
|
DiskReader::set_name (string const & str)
|
||||||
{
|
{
|
||||||
if (_name != str) {
|
string my_name = X_("reader:");
|
||||||
for (uint32_t n = 0; n < DataType::num_types; ++n) {
|
my_name += str;
|
||||||
if (_playlists[n]) {
|
|
||||||
_playlists[n]->set_name (str);
|
if (_name != my_name) {
|
||||||
}
|
SessionObject::set_name (my_name);
|
||||||
}
|
|
||||||
SessionObject::set_name(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -151,6 +149,7 @@ DiskReader::set_state (const XMLNode& node, int version)
|
||||||
void
|
void
|
||||||
DiskReader::realtime_handle_transport_stopped ()
|
DiskReader::realtime_handle_transport_stopped ()
|
||||||
{
|
{
|
||||||
|
realtime_set_speed (0.0f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -244,14 +243,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
|
||||||
const bool need_disk_signal = result_required || _monitoring_choice == MonitorDisk || _monitoring_choice == MonitorCue;
|
const bool need_disk_signal = result_required || _monitoring_choice == MonitorDisk || _monitoring_choice == MonitorCue;
|
||||||
|
|
||||||
_need_butler = false;
|
_need_butler = false;
|
||||||
|
playback_distance = calculate_playback_distance (nframes);
|
||||||
if (fabsf (_actual_speed) != 1.0f) {
|
|
||||||
midi_interpolation.set_speed (_target_speed);
|
|
||||||
interpolation.set_speed (_target_speed);
|
|
||||||
playback_distance = midi_interpolation.distance (nframes);
|
|
||||||
} else {
|
|
||||||
playback_distance = nframes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!need_disk_signal) {
|
if (!need_disk_signal) {
|
||||||
|
|
||||||
|
|
@ -339,7 +331,6 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
|
||||||
}
|
}
|
||||||
|
|
||||||
chaninfo->buf->increment_read_ptr (playback_distance);
|
chaninfo->buf->increment_read_ptr (playback_distance);
|
||||||
_speed = _target_speed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MIDI data handling */
|
/* MIDI data handling */
|
||||||
|
|
@ -352,7 +343,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
|
||||||
get_playback (mbuf, playback_distance);
|
get_playback (mbuf, playback_distance);
|
||||||
|
|
||||||
/* vari-speed */
|
/* vari-speed */
|
||||||
if (_target_speed > 0 && _actual_speed != 1.0f) {
|
if (_actual_speed != 0.0 && fabsf (_actual_speed) != 1.0f) {
|
||||||
MidiBuffer& mbuf (bufs.get_midi (0));
|
MidiBuffer& mbuf (bufs.get_midi (0));
|
||||||
for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
|
for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
|
||||||
MidiBuffer::TimeType *tme = i.timeptr();
|
MidiBuffer::TimeType *tme = i.timeptr();
|
||||||
|
|
@ -428,6 +419,8 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
|
||||||
if (frames_read <= frames_written) {
|
if (frames_read <= frames_written) {
|
||||||
if ((frames_written - frames_read) + playback_distance < midi_readahead) {
|
if ((frames_written - frames_read) + playback_distance < midi_readahead) {
|
||||||
_need_butler = true;
|
_need_butler = true;
|
||||||
|
} else {
|
||||||
|
cerr << name() << " fr " << frames_read << " > " << frames_written << endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_need_butler = true;
|
_need_butler = true;
|
||||||
|
|
@ -448,17 +441,14 @@ DiskReader::calculate_playback_distance (pframes_t nframes)
|
||||||
{
|
{
|
||||||
frameoffset_t playback_distance = nframes;
|
frameoffset_t playback_distance = nframes;
|
||||||
|
|
||||||
if (_actual_speed != 1.0f && _actual_speed != -1.0f) {
|
if (_target_speed != 1.0f && _target_speed != -1.0f) {
|
||||||
interpolation.set_speed (_target_speed);
|
interpolation.set_speed (_target_speed);
|
||||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
midi_interpolation.set_speed (_target_speed);
|
||||||
int channel = 0;
|
playback_distance = midi_interpolation.distance (nframes);
|
||||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++channel) {
|
|
||||||
playback_distance = interpolation.interpolate (channel, nframes, NULL, NULL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
playback_distance = nframes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_actual_speed = _target_speed;
|
||||||
|
|
||||||
if (_actual_speed < 0.0) {
|
if (_actual_speed < 0.0) {
|
||||||
return -playback_distance;
|
return -playback_distance;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -496,7 +486,7 @@ DiskReader::overwrite_existing_buffers ()
|
||||||
|
|
||||||
/* AUDIO */
|
/* AUDIO */
|
||||||
|
|
||||||
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
|
bool reversed = (_target_speed * _session.transport_speed()) < 0.0f;
|
||||||
|
|
||||||
/* assume all are the same size */
|
/* assume all are the same size */
|
||||||
framecnt_t size = c->front()->buf->bufsize();
|
framecnt_t size = c->front()->buf->bufsize();
|
||||||
|
|
@ -839,7 +829,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, framecnt_t
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
framecnt_t to_read;
|
framecnt_t to_read;
|
||||||
RingBufferNPT<Sample>::rw_vector vector;
|
RingBufferNPT<Sample>::rw_vector vector;
|
||||||
bool const reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
|
bool const reversed = (_target_speed * _session.transport_speed()) < 0.0f;
|
||||||
framecnt_t total_space;
|
framecnt_t total_space;
|
||||||
framecnt_t zero_fill;
|
framecnt_t zero_fill;
|
||||||
uint32_t chan_n;
|
uint32_t chan_n;
|
||||||
|
|
@ -1401,10 +1391,9 @@ DiskReader::refill_midi ()
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t write_space = _midi_buf->write_space();
|
size_t write_space = _midi_buf->write_space();
|
||||||
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
|
bool reversed = (_target_speed * _session.transport_speed()) < 0.0f;
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::DiskIO, string_compose ("MIDI refill, write space = %1 file frame = %2\n", write_space, file_frame));
|
DEBUG_TRACE (DEBUG::DiskIO, string_compose ("MIDI refill, write space = %1 file frame = %2\n", write_space, file_frame));
|
||||||
//PBD::stacktrace (cerr, 20);
|
|
||||||
|
|
||||||
/* no space to write */
|
/* no space to write */
|
||||||
if (write_space == 0) {
|
if (write_space == 0) {
|
||||||
|
|
|
||||||
|
|
@ -417,13 +417,13 @@ DiskWriter::set_state (const XMLNode& node, int version)
|
||||||
if (DiskIOProcessor::set_state (node, version)) {
|
if (DiskIOProcessor::set_state (node, version)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#if 0 // XXX DISK
|
||||||
if ((prop = node.property (X_("capture-alignment"))) != 0) {
|
if ((prop = node.property (X_("capture-alignment"))) != 0) {
|
||||||
set_align_choice (AlignChoice (string_2_enum (prop->value(), _alignment_choice)), true);
|
set_align_choice (AlignChoice (string_2_enum (prop->value(), _alignment_choice)), true);
|
||||||
} else {
|
} else {
|
||||||
set_align_choice (Automatic, true);
|
set_align_choice (Automatic, true);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((prop = node.property ("record-safe")) != 0) {
|
if ((prop = node.property ("record-safe")) != 0) {
|
||||||
_record_safe = PBD::string_is_affirmative (prop->value()) ? 1 : 0;
|
_record_safe = PBD::string_is_affirmative (prop->value()) ? 1 : 0;
|
||||||
|
|
@ -1702,3 +1702,9 @@ DiskWriter::adjust_buffering ()
|
||||||
(*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
|
(*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DiskWriter::realtime_handle_transport_stopped ()
|
||||||
|
{
|
||||||
|
realtime_set_speed (0.0f, true);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -397,20 +397,6 @@ MidiTrack::realtime_locate ()
|
||||||
_disk_reader->reset_tracker ();
|
_disk_reader->reset_tracker ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
MidiTrack::realtime_handle_transport_stopped ()
|
|
||||||
{
|
|
||||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
|
|
||||||
|
|
||||||
if (!lm.locked ()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
|
||||||
(*i)->realtime_handle_transport_stopped ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTrack::non_realtime_locate (framepos_t pos)
|
MidiTrack::non_realtime_locate (framepos_t pos)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -457,6 +457,7 @@ Route::process_output_buffers (BufferSet& bufs,
|
||||||
_initial_delay + latency, longest_session_latency - latency);
|
_initial_delay + latency, longest_session_latency - latency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//cerr << name() << " run " << (*i)->name() << endl;
|
||||||
(*i)->run (bufs, start_frame - latency, end_frame - latency, speed, nframes, *i != _processors.back());
|
(*i)->run (bufs, start_frame - latency, end_frame - latency, speed, nframes, *i != _processors.back());
|
||||||
bufs.set_count ((*i)->output_streams());
|
bufs.set_count ((*i)->output_streams());
|
||||||
|
|
||||||
|
|
@ -2825,88 +2826,7 @@ Route::set_processor_state (const XMLNode& node)
|
||||||
/* CapturingProcessor should never be restored, it's always
|
/* CapturingProcessor should never be restored, it's always
|
||||||
added explicitly when needed */
|
added explicitly when needed */
|
||||||
} else {
|
} else {
|
||||||
ProcessorList::iterator o;
|
set_processor_state (**niter, prop, new_order, must_configure);
|
||||||
|
|
||||||
for (o = _processors.begin(); o != _processors.end(); ++o) {
|
|
||||||
XMLProperty const * id_prop = (*niter)->property(X_("id"));
|
|
||||||
if (id_prop && (*o)->id() == id_prop->value()) {
|
|
||||||
(*o)->set_state (**niter, Stateful::current_state_version);
|
|
||||||
new_order.push_back (*o);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the processor (*niter) is not on the route then create it
|
|
||||||
|
|
||||||
if (o == _processors.end()) {
|
|
||||||
|
|
||||||
boost::shared_ptr<Processor> processor;
|
|
||||||
|
|
||||||
if (prop->value() == "intsend") {
|
|
||||||
|
|
||||||
processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::dynamic_pointer_cast<ARDOUR::Route>(shared_from_this()), boost::shared_ptr<Route>(), Delivery::Aux, true));
|
|
||||||
|
|
||||||
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
|
|
||||||
prop->value() == "lv2" ||
|
|
||||||
prop->value() == "windows-vst" ||
|
|
||||||
prop->value() == "mac-vst" ||
|
|
||||||
prop->value() == "lxvst" ||
|
|
||||||
prop->value() == "luaproc" ||
|
|
||||||
prop->value() == "audiounit") {
|
|
||||||
|
|
||||||
if (_session.get_disable_all_loaded_plugins ()) {
|
|
||||||
processor.reset (new UnknownProcessor (_session, **niter));
|
|
||||||
} else {
|
|
||||||
processor.reset (new PluginInsert (_session));
|
|
||||||
processor->set_owner (this);
|
|
||||||
if (_strict_io) {
|
|
||||||
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert>(processor);
|
|
||||||
pi->set_strict_io (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (prop->value() == "port") {
|
|
||||||
|
|
||||||
processor.reset (new PortInsert (_session, _pannable, _mute_master));
|
|
||||||
|
|
||||||
} else if (prop->value() == "send") {
|
|
||||||
|
|
||||||
processor.reset (new Send (_session, _pannable, _mute_master, Delivery::Send, true));
|
|
||||||
boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
|
|
||||||
send->SelfDestruct.connect_same_thread (*this,
|
|
||||||
boost::bind (&Route::processor_selfdestruct, this, boost::weak_ptr<Processor> (processor)));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (processor->set_state (**niter, Stateful::current_state_version) != 0) {
|
|
||||||
/* This processor could not be configured. Turn it into a UnknownProcessor */
|
|
||||||
processor.reset (new UnknownProcessor (_session, **niter));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* subscribe to Sidechain IO changes */
|
|
||||||
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (processor);
|
|
||||||
if (pi && pi->has_sidechain ()) {
|
|
||||||
pi->sidechain_input ()->changed.connect_same_thread (*this, boost::bind (&Route::sidechain_change_handler, this, _1, _2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we have to note the monitor send here, otherwise a new one will be created
|
|
||||||
and the state of this one will be lost.
|
|
||||||
*/
|
|
||||||
boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (processor);
|
|
||||||
if (isend && isend->role() == Delivery::Listen) {
|
|
||||||
_monitor_send = isend;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* it doesn't matter if invisible processors are added here, as they
|
|
||||||
will be sorted out by setup_invisible_processors () shortly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
new_order.push_back (processor);
|
|
||||||
must_configure = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2948,6 +2868,93 @@ Route::set_processor_state (const XMLNode& node)
|
||||||
set_processor_positions ();
|
set_processor_positions ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Route::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
|
||||||
|
{
|
||||||
|
ProcessorList::iterator o;
|
||||||
|
|
||||||
|
for (o = _processors.begin(); o != _processors.end(); ++o) {
|
||||||
|
XMLProperty const * id_prop = node.property(X_("id"));
|
||||||
|
if (id_prop && (*o)->id() == id_prop->value()) {
|
||||||
|
(*o)->set_state (node, Stateful::current_state_version);
|
||||||
|
new_order.push_back (*o);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the processor (node) is not on the route then create it
|
||||||
|
|
||||||
|
if (o == _processors.end()) {
|
||||||
|
|
||||||
|
boost::shared_ptr<Processor> processor;
|
||||||
|
|
||||||
|
if (prop->value() == "intsend") {
|
||||||
|
|
||||||
|
processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::dynamic_pointer_cast<ARDOUR::Route>(shared_from_this()), boost::shared_ptr<Route>(), Delivery::Aux, true));
|
||||||
|
|
||||||
|
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
|
||||||
|
prop->value() == "lv2" ||
|
||||||
|
prop->value() == "windows-vst" ||
|
||||||
|
prop->value() == "mac-vst" ||
|
||||||
|
prop->value() == "lxvst" ||
|
||||||
|
prop->value() == "luaproc" ||
|
||||||
|
prop->value() == "audiounit") {
|
||||||
|
|
||||||
|
if (_session.get_disable_all_loaded_plugins ()) {
|
||||||
|
processor.reset (new UnknownProcessor (_session, node));
|
||||||
|
} else {
|
||||||
|
processor.reset (new PluginInsert (_session));
|
||||||
|
processor->set_owner (this);
|
||||||
|
if (_strict_io) {
|
||||||
|
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert>(processor);
|
||||||
|
pi->set_strict_io (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (prop->value() == "port") {
|
||||||
|
|
||||||
|
processor.reset (new PortInsert (_session, _pannable, _mute_master));
|
||||||
|
|
||||||
|
} else if (prop->value() == "send") {
|
||||||
|
|
||||||
|
processor.reset (new Send (_session, _pannable, _mute_master, Delivery::Send, true));
|
||||||
|
boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
|
||||||
|
send->SelfDestruct.connect_same_thread (*this,
|
||||||
|
boost::bind (&Route::processor_selfdestruct, this, boost::weak_ptr<Processor> (processor)));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processor->set_state (node, Stateful::current_state_version) != 0) {
|
||||||
|
/* This processor could not be configured. Turn it into a UnknownProcessor */
|
||||||
|
processor.reset (new UnknownProcessor (_session, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subscribe to Sidechain IO changes */
|
||||||
|
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (processor);
|
||||||
|
if (pi && pi->has_sidechain ()) {
|
||||||
|
pi->sidechain_input ()->changed.connect_same_thread (*this, boost::bind (&Route::sidechain_change_handler, this, _1, _2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we have to note the monitor send here, otherwise a new one will be created
|
||||||
|
and the state of this one will be lost.
|
||||||
|
*/
|
||||||
|
boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (processor);
|
||||||
|
if (isend && isend->role() == Delivery::Listen) {
|
||||||
|
_monitor_send = isend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it doesn't matter if invisible processors are added here, as they
|
||||||
|
will be sorted out by setup_invisible_processors () shortly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
new_order.push_back (processor);
|
||||||
|
must_configure = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Route::curve_reallocate ()
|
Route::curve_reallocate ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1530,7 +1530,7 @@ Session::set_transport_speed (double speed, framepos_t destination_frame, bool a
|
||||||
boost::shared_ptr<RouteList> rl = routes.reader();
|
boost::shared_ptr<RouteList> rl = routes.reader();
|
||||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||||
if (tr && tr->realtime_set_speed (tr->speed(), true)) {
|
if (tr && tr->realtime_set_speed (_transport_speed, true)) {
|
||||||
todo = PostTransportWork (todo | PostTransportSpeed);
|
todo = PostTransportWork (todo | PostTransportSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1694,7 +1694,7 @@ Session::start_transport ()
|
||||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||||
if (tr) {
|
if (tr) {
|
||||||
tr->realtime_set_speed (tr->speed(), true);
|
tr->realtime_set_speed (_transport_speed, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1861,7 +1861,7 @@ Session::use_sync_source (Slave* new_slave)
|
||||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||||
if (tr && !tr->hidden()) {
|
if (tr && !tr->hidden()) {
|
||||||
if (tr->realtime_set_speed (tr->speed(), true)) {
|
if (tr->realtime_set_speed (_transport_speed, true)) {
|
||||||
non_rt_required = true;
|
non_rt_required = true;
|
||||||
}
|
}
|
||||||
tr->set_slaved (_slave != 0);
|
tr->set_slaved (_slave != 0);
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ Track::init ()
|
||||||
}
|
}
|
||||||
|
|
||||||
_disk_reader.reset (new DiskReader (_session, name(), dflags));
|
_disk_reader.reset (new DiskReader (_session, name(), dflags));
|
||||||
|
|
||||||
_disk_reader->set_block_size (_session.get_block_size ());
|
_disk_reader->set_block_size (_session.get_block_size ());
|
||||||
_disk_reader->set_route (shared_from_this());
|
_disk_reader->set_route (shared_from_this());
|
||||||
|
|
||||||
|
|
@ -342,6 +341,7 @@ Track::set_name (const string& str)
|
||||||
_disk_writer->set_write_source_name (diskstream_name);
|
_disk_writer->set_write_source_name (diskstream_name);
|
||||||
|
|
||||||
boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
|
boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
|
||||||
|
|
||||||
if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
|
if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
|
||||||
/* Only rename the diskstream (and therefore the playlist) if
|
/* Only rename the diskstream (and therefore the playlist) if
|
||||||
a) the playlist has never had a region added to it and
|
a) the playlist has never had a region added to it and
|
||||||
|
|
@ -358,6 +358,12 @@ Track::set_name (const string& str)
|
||||||
_disk_writer->set_name (str);
|
_disk_writer->set_name (str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t n = 0; n < DataType::num_types; ++n) {
|
||||||
|
if (_playlists[n]) {
|
||||||
|
_playlists[n]->set_name (str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* save state so that the statefile fully reflects any filename changes */
|
/* save state so that the statefile fully reflects any filename changes */
|
||||||
|
|
||||||
if ((ret = Route::set_name (str)) == 0) {
|
if ((ret = Route::set_name (str)) == 0) {
|
||||||
|
|
@ -483,9 +489,9 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
|
||||||
if (no_meter) {
|
if (no_meter) {
|
||||||
BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
|
BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
|
||||||
_meter->run (bufs, start_frame, end_frame, 1.0, nframes, true);
|
_meter->run (bufs, start_frame, end_frame, 1.0, nframes, true);
|
||||||
_input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, speed(), nframes);
|
_input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, _session.transport_speed(), nframes);
|
||||||
} else {
|
} else {
|
||||||
_input->process_input (_meter, start_frame, end_frame, speed(), nframes);
|
_input->process_input (_meter, start_frame, end_frame, _session.transport_speed(), nframes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -498,7 +504,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
|
||||||
fill_buffers_with_input (bufs, _input, nframes);
|
fill_buffers_with_input (bufs, _input, nframes);
|
||||||
|
|
||||||
if (_meter_point == MeterInput) {
|
if (_meter_point == MeterInput) {
|
||||||
_meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
|
_meter->run (bufs, start_frame, end_frame, _session.transport_speed(), nframes, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
passthru (bufs, start_frame, end_frame, nframes, false);
|
passthru (bufs, start_frame, end_frame, nframes, false);
|
||||||
|
|
@ -707,6 +713,20 @@ Track::realtime_set_speed (double s, bool g)
|
||||||
return _disk_writer->realtime_set_speed (s, g);
|
return _disk_writer->realtime_set_speed (s, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Track::realtime_handle_transport_stopped ()
|
||||||
|
{
|
||||||
|
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
|
||||||
|
|
||||||
|
if (!lm.locked ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||||
|
(*i)->realtime_handle_transport_stopped ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -719,12 +739,6 @@ Track::pending_overwrite () const
|
||||||
return _disk_reader->pending_overwrite ();
|
return _disk_reader->pending_overwrite ();
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
|
||||||
Track::speed () const
|
|
||||||
{
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -1115,3 +1129,28 @@ Track::metering_state () const
|
||||||
}
|
}
|
||||||
return rv ? MeteringInput : MeteringRoute;
|
return rv ? MeteringInput : MeteringRoute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
|
||||||
|
{
|
||||||
|
if (Route::set_processor_state (node, prop, new_order, must_configure)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop->value() == "diskreader") {
|
||||||
|
if (_disk_reader) {
|
||||||
|
_disk_reader->set_state (node, Stateful::current_state_version);
|
||||||
|
new_order.push_back (_disk_reader);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (prop->value() == "diskwriter") {
|
||||||
|
if (_disk_writer) {
|
||||||
|
_disk_writer->set_state (node, Stateful::current_state_version);
|
||||||
|
new_order.push_back (_disk_writer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue