X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=blobdiff_plain;f=libs%2Fardour%2Faudio_track.cc;h=3a653a0efe675096b4d9d8e225c84451975f2061;hp=7f77f637a36bfe413bf370b703e1521283f33915;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hpb=4729bbde5f5f6833b878155da5a395d5ecd9e565 diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 7f77f637a3..3a653a0efe 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -19,7 +19,6 @@ #include -#include "pbd/boost_debug.h" #include "pbd/enumwriter.h" #include "pbd/error.h" @@ -30,11 +29,14 @@ #include "ardour/audio_diskstream.h" #include "ardour/audio_track.h" #include "ardour/audioplaylist.h" +#include "ardour/boost_debug.h" #include "ardour/buffer_set.h" #include "ardour/delivery.h" #include "ardour/meter.h" +#include "ardour/monitor_control.h" #include "ardour/playlist_factory.h" #include "ardour/processor.h" +#include "ardour/profile.h" #include "ardour/region.h" #include "ardour/region_factory.h" #include "ardour/session.h" @@ -42,33 +44,30 @@ #include "ardour/source.h" #include "ardour/utils.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; using namespace PBD; -AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) - : Track (sess, name, flag, mode) +AudioTrack::AudioTrack (Session& sess, string name, TrackMode mode) + : Track (sess, name, PresentationInfo::AudioTrack, mode) { } AudioTrack::~AudioTrack () { + if (_freeze_record.playlist && !_session.deletion_in_progress()) { + _freeze_record.playlist->release(); + } } boost::shared_ptr AudioTrack::create_diskstream () { - AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0); - - if (_flags & Auditioner) { - dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden); - } else { - dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable); - } + AudioDiskstream::Flag dflags = AudioDiskstream::Flag (AudioDiskstream::Recordable); - if (_mode == Destructive) { + if (_mode == Destructive && !Profile->get_trx()) { dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive); } else if (_mode == NonLayered){ dflags = AudioDiskstream::Flag(dflags | AudioDiskstream::NonLayered); @@ -83,7 +82,11 @@ AudioTrack::set_diskstream (boost::shared_ptr ds) Track::set_diskstream (ds); _diskstream->set_track (this); - _diskstream->set_destructive (_mode == Destructive); + if (Profile->get_trx()) { + _diskstream->set_destructive (false); + } else { + _diskstream->set_destructive (_mode == Destructive); + } _diskstream->set_non_layered (_mode == NonLayered); if (audio_diskstream()->deprecated_io_node) { @@ -112,7 +115,7 @@ AudioTrack::set_mode (TrackMode m) { if (m != _mode) { - if (_diskstream->set_destructive (m == Destructive)) { + if (!Profile->get_trx() && _diskstream->set_destructive (m == Destructive)) { return -1; } @@ -135,8 +138,15 @@ AudioTrack::can_use_mode (TrackMode m, bool& bounce_required) return true; case Destructive: + if (Profile->get_trx()) { + return false; + } else { + return _diskstream->can_become_destructive (bounce_required); + } + break; + default: - return _diskstream->can_become_destructive (bounce_required); + return false; } } @@ -149,7 +159,7 @@ AudioTrack::deprecated_use_diskstream_connections () return 0; } - const XMLProperty* prop; + XMLProperty const * prop; XMLNode& node (*diskstream->deprecated_io_node); /* don't do this more than once. */ @@ -157,7 +167,7 @@ AudioTrack::deprecated_use_diskstream_connections () diskstream->deprecated_io_node = 0; if ((prop = node.property ("gain")) != 0) { - _amp->set_gain (atof (prop->value().c_str()), this); + _amp->gain_control()->set_value (atof (prop->value().c_str()), PBD::Controllable::NoGroup); } if ((prop = node.property ("input-connection")) != 0) { @@ -191,11 +201,7 @@ AudioTrack::deprecated_use_diskstream_connections () int AudioTrack::set_state (const XMLNode& node, int version) { - const XMLProperty *prop; - - if (Track::set_state (node, version)) { - return -1; - } + XMLProperty const * prop; if ((prop = node.property (X_("mode"))) != 0) { _mode = TrackMode (string_2_enum (prop->value(), _mode)); @@ -203,6 +209,18 @@ AudioTrack::set_state (const XMLNode& node, int version) _mode = Normal; } + if (Profile->get_trx() && _mode == Destructive) { + /* Tracks does not support destructive tracks and trying to + handle it as a normal track would be wrong. + */ + error << string_compose (_("%1: this session uses destructive tracks, which are not supported"), PROGRAM_NAME) << endmsg; + return -1; + } + + if (Track::set_state (node, version)) { + return -1; + } + pending_state = const_cast (&node); if (_session.state_of_the_state() & Session::Loading) { @@ -249,8 +267,8 @@ void AudioTrack::set_state_part_two () { XMLNode* fnode; - XMLProperty* prop; - LocaleGuard lg (X_("POSIX")); + XMLProperty const * prop; + LocaleGuard lg; /* This is called after all session state has been restored but before have been made ports and connections are established. @@ -273,6 +291,7 @@ AudioTrack::set_state_part_two () boost::shared_ptr pl = _session.playlists->by_name (prop->value()); if (pl) { _freeze_record.playlist = boost::dynamic_pointer_cast (pl); + _freeze_record.playlist->use(); } else { _freeze_record.playlist.reset (); _freeze_record.state = NoFreeze; @@ -315,7 +334,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram if (!lm.locked()) { boost::shared_ptr diskstream = audio_diskstream(); framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes); - if (can_internal_playback_seek(std::llabs(playback_distance))) { + if (can_internal_playback_seek(::llabs(playback_distance))) { /* TODO should declick */ internal_playback_seek(playback_distance); } @@ -331,7 +350,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram if (!_active) { silence (nframes); - if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) { + if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) { _meter->reset(); } return 0; @@ -341,7 +360,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram 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 @@ -362,9 +381,9 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram BufferSet& bufs = _session.get_route_buffers (n_process_buffers ()); fill_buffers_with_input (bufs, _input, nframes); - - if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) { - _meter->run (bufs, start_frame, end_frame, nframes, true); + + if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) { + _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) { @@ -375,6 +394,8 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && _session.transport_rolling())); + flush_processor_buffers_locked (nframes); + need_butler = diskstream->commit (playback_distance); return 0; @@ -382,7 +403,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram int AudioTrack::export_stuff (BufferSet& buffers, framepos_t start, framecnt_t nframes, - boost::shared_ptr endpoint, bool include_endpoint, bool for_export) + boost::shared_ptr endpoint, bool include_endpoint, bool for_export, bool for_freeze) { boost::scoped_array gain_buffer (new gain_t[nframes]); boost::scoped_array mix_buffer (new Sample[nframes]); @@ -416,38 +437,7 @@ AudioTrack::export_stuff (BufferSet& buffers, framepos_t start, framecnt_t nfram } } - // If no processing is required, there's no need to go any further. - - if (!endpoint && !include_endpoint) { - return 0; - } - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - - if (!include_endpoint && (*i) == endpoint) { - break; - } - - /* if we're not exporting, stop processing if we come across a routing processor. - */ - - if (!for_export && (*i)->does_routing()) { - break; - } - - /* even for export, don't run any processor that does routing. - - oh, and don't bother with the peak meter either. - */ - - if (!(*i)->does_routing() && !boost::dynamic_pointer_cast(*i)) { - (*i)->run (buffers, start, start+nframes, nframes, true); - } - - if ((*i) == endpoint) { - break; - } - } + bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze); return 0; } @@ -486,12 +476,12 @@ AudioTrack::bounceable (boost::shared_ptr endpoint, bool include_endp /* does the output from the last considered processor match the * input to this one? */ - + if (naudio != (*r)->input_streams().n_audio()) { return false; } - /* we're including the endpoint - if we just hit it, + /* we're including the endpoint - if we just hit it, then stop. */ @@ -499,7 +489,7 @@ AudioTrack::bounceable (boost::shared_ptr endpoint, bool include_endp return true; } - /* save outputs of this processor to test against inputs + /* save outputs of this processor to test against inputs of the next one. */ @@ -520,7 +510,7 @@ AudioTrack::bounce_range (framepos_t start, framepos_t end, InterThreadInfo& itt boost::shared_ptr endpoint, bool include_endpoint) { vector > srcs; - return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false); + return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false); } void @@ -563,8 +553,8 @@ AudioTrack::freeze_me (InterThreadInfo& itt) boost::shared_ptr res; - if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt, - main_outs(), false, false)) == 0) { + if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), + true, srcs, itt, main_outs(), false, false, true)) == 0) { return; } @@ -575,7 +565,10 @@ AudioTrack::freeze_me (InterThreadInfo& itt) for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) { - if (!(*r)->does_routing() && !boost::dynamic_pointer_cast(*r)) { + if ((*r)->does_routing() && (*r)->active()) { + break; + } + if (!boost::dynamic_pointer_cast(*r)) { FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo ((*r)->get_state(), (*r)); @@ -583,11 +576,12 @@ AudioTrack::freeze_me (InterThreadInfo& itt) _freeze_record.processor_info.push_back (frii); - /* now deactivate the processor */ - - (*r)->deactivate (); + /* now deactivate the processor, */ + if (!boost::dynamic_pointer_cast(*r)) { + (*r)->deactivate (); + } } - + _session.set_dirty (); } } @@ -617,10 +611,13 @@ AudioTrack::freeze_me (InterThreadInfo& itt) diskstream->use_playlist (boost::dynamic_pointer_cast(new_playlist)); diskstream->set_record_enabled (false); + _freeze_record.playlist->use(); // prevent deletion + /* reset stuff that has already been accounted for in the freeze process */ - set_gain (1.0, this); - _amp->gain_control()->set_automation_state (Off); + gain_control()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup); + gain_control()->set_automation_state (Off); + /* XXX need to use _main_outs _panner->set_automation_state (Off); */ _freeze_record.state = Frozen; @@ -631,6 +628,7 @@ void AudioTrack::unfreeze () { if (_freeze_record.playlist) { + _freeze_record.playlist->release(); audio_diskstream()->use_playlist (_freeze_record.playlist); {