2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <glibmm/thread.h>
33 #include <glibmm/miscutils.h>
34 #include <glibmm/fileutils.h>
36 #include "pbd/error.h"
37 #include <glibmm/thread.h>
38 #include "pbd/boost_debug.h"
39 #include "pbd/pathscanner.h"
40 #include "pbd/stl_delete.h"
41 #include "pbd/basename.h"
42 #include "pbd/stacktrace.h"
43 #include "pbd/file_utils.h"
45 #include "ardour/amp.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_port.h"
50 #include "ardour/audio_track.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/audiofilesource.h"
53 #include "ardour/audioplaylist.h"
54 #include "ardour/audioregion.h"
55 #include "ardour/auditioner.h"
56 #include "ardour/buffer_set.h"
57 #include "ardour/bundle.h"
58 #include "ardour/butler.h"
59 #include "ardour/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/debug.h"
65 #include "ardour/filename_extensions.h"
66 #include "ardour/internal_send.h"
67 #include "ardour/io_processor.h"
68 #include "ardour/midi_diskstream.h"
69 #include "ardour/midi_playlist.h"
70 #include "ardour/midi_region.h"
71 #include "ardour/midi_track.h"
72 #include "ardour/midi_ui.h"
73 #include "ardour/named_selection.h"
74 #include "ardour/playlist.h"
75 #include "ardour/plugin_insert.h"
76 #include "ardour/port_insert.h"
77 #include "ardour/processor.h"
78 #include "ardour/rc_configuration.h"
79 #include "ardour/recent_sessions.h"
80 #include "ardour/region_factory.h"
81 #include "ardour/return.h"
82 #include "ardour/route_group.h"
83 #include "ardour/send.h"
84 #include "ardour/session.h"
85 #include "ardour/session_directory.h"
86 #include "ardour/session_directory.h"
87 #include "ardour/session_metadata.h"
88 #include "ardour/session_playlists.h"
89 #include "ardour/slave.h"
90 #include "ardour/smf_source.h"
91 #include "ardour/source_factory.h"
92 #include "ardour/tape_file_matcher.h"
93 #include "ardour/tempo.h"
94 #include "ardour/utils.h"
99 using namespace ARDOUR;
101 using boost::shared_ptr;
102 using boost::weak_ptr;
104 bool Session::_disable_all_loaded_plugins = false;
106 PBD::Signal1<void,std::string> Session::Dialog;
107 PBD::Signal0<int> Session::AskAboutPendingState;
108 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
109 PBD::Signal0<void> Session::SendFeedback;
111 PBD::Signal0<void> Session::TimecodeOffsetChanged;
112 PBD::Signal0<void> Session::StartTimeChanged;
113 PBD::Signal0<void> Session::EndTimeChanged;
114 PBD::Signal0<void> Session::AutoBindingOn;
115 PBD::Signal0<void> Session::AutoBindingOff;
116 PBD::Signal2<void,std::string, std::string> Session::Exported;
117 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
119 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
120 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
122 Session::Session (AudioEngine &eng,
123 const string& fullpath,
124 const string& snapshot_name,
128 _target_transport_speed (0.0),
129 _requested_return_frame (-1),
130 _scratch_buffers(new BufferSet()),
131 _silent_buffers(new BufferSet()),
132 _mix_buffers(new BufferSet()),
134 _mmc_port (default_mmc_port),
135 _mtc_port (default_mtc_port),
136 _midi_port (default_midi_port),
137 _midi_clock_port (default_midi_clock_port),
138 _session_dir (new SessionDirectory(fullpath)),
140 _butler (new Butler (*this)),
141 _post_transport_work (0),
142 _send_timecode_update (false),
143 diskstreams (new DiskstreamList),
144 routes (new RouteList),
145 _total_free_4k_blocks (0),
146 _bundles (new BundleList),
147 _bundle_xml_node (0),
150 click_emphasis_data (0),
152 _metadata (new SessionMetadata()),
153 _have_rec_enabled_diskstream (false)
156 playlists.reset (new SessionPlaylists);
160 interpolation.add_channel_to (0, 0);
162 if (!eng.connected()) {
163 throw failed_constructor();
166 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
168 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
169 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
171 first_stage_init (fullpath, snapshot_name);
173 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
176 if (create (new_session, mix_template, compute_initial_length())) {
178 throw failed_constructor ();
182 if (second_stage_init (new_session)) {
184 throw failed_constructor ();
187 store_recent_sessions(_name, _path);
189 bool was_dirty = dirty();
191 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
193 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
194 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
197 DirtyChanged (); /* EMIT SIGNAL */
201 Session::Session (AudioEngine &eng,
203 string snapshot_name,
204 AutoConnectOption input_ac,
205 AutoConnectOption output_ac,
206 uint32_t control_out_channels,
207 uint32_t master_out_channels,
208 uint32_t requested_physical_in,
209 uint32_t requested_physical_out,
210 nframes_t initial_length)
213 _target_transport_speed (0.0),
214 _requested_return_frame (-1),
215 _scratch_buffers(new BufferSet()),
216 _silent_buffers(new BufferSet()),
217 _mix_buffers(new BufferSet()),
219 _mmc_port (default_mmc_port),
220 _mtc_port (default_mtc_port),
221 _midi_port (default_midi_port),
222 _midi_clock_port (default_midi_clock_port),
223 _session_dir ( new SessionDirectory(fullpath)),
225 _butler (new Butler (*this)),
226 _post_transport_work (0),
227 _send_timecode_update (false),
228 diskstreams (new DiskstreamList),
229 routes (new RouteList),
230 _total_free_4k_blocks (0),
231 _bundles (new BundleList),
232 _bundle_xml_node (0),
233 _click_io ((IO *) 0),
235 click_emphasis_data (0),
237 _metadata (new SessionMetadata()),
238 _have_rec_enabled_diskstream (false)
240 playlists.reset (new SessionPlaylists);
244 interpolation.add_channel_to (0, 0);
246 if (!eng.connected()) {
247 throw failed_constructor();
250 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
252 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
253 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
255 if (n_physical_inputs) {
256 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
259 if (n_physical_outputs) {
260 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
263 first_stage_init (fullpath, snapshot_name);
265 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
268 if (create (new_session, string(), initial_length)) {
270 throw failed_constructor ();
275 /* set up Master Out and Control Out if necessary */
280 if (master_out_channels) {
281 ChanCount count(DataType::AUDIO, master_out_channels);
282 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
283 boost_debug_shared_ptr_mark_interesting (rt, "Route");
284 boost::shared_ptr<Route> r (rt);
285 r->input()->ensure_io (count, false, this);
286 r->output()->ensure_io (count, false, this);
287 r->set_remote_control_id (control_id);
291 /* prohibit auto-connect to master, because there isn't one */
292 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
295 if (control_out_channels) {
296 ChanCount count(DataType::AUDIO, control_out_channels);
297 Route* rt = new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO);
298 boost_debug_shared_ptr_mark_interesting (rt, "Route");
299 shared_ptr<Route> r (rt);
300 r->input()->ensure_io (count, false, this);
301 r->output()->ensure_io (count, false, this);
302 r->set_remote_control_id (control_id++);
308 add_routes (rl, false);
313 if (no_auto_connect()) {
314 input_ac = AutoConnectOption (0);
315 output_ac = AutoConnectOption (0);
318 Config->set_input_auto_connect (input_ac);
319 Config->set_output_auto_connect (output_ac);
321 if (second_stage_init (new_session)) {
323 throw failed_constructor ();
326 store_recent_sessions (_name, _path);
328 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
330 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
341 vector<void*> debug_pointers;
343 /* if we got to here, leaving pending capture state around
347 remove_pending_capture_state ();
349 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
351 _engine.remove_session ();
353 /* clear history so that no references to objects are held any more */
357 /* clear state tree so that no references to objects are held any more */
361 /* reset dynamic state version back to default */
363 Stateful::loading_state_version = 0;
366 delete midi_control_ui;
368 if (click_data != default_click) {
369 delete [] click_data;
372 if (click_emphasis_data != default_click_emphasis) {
373 delete [] click_emphasis_data;
378 delete _scratch_buffers;
379 delete _silent_buffers;
382 /* clear out any pending dead wood from RCU managed objects */
385 diskstreams.flush ();
388 AudioDiskstream::free_working_buffers();
390 /* tell everyone who is still standing that we're about to die */
393 /* tell everyone to drop references and delete objects as we go */
395 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
396 named_selections.clear ();
398 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
399 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
400 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
401 i->second->drop_references ();
405 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
407 /* reset these three references to special routes before we do the usual route delete thing */
410 _master_out.reset ();
411 _control_out.reset ();
414 RCUWriter<RouteList> writer (routes);
415 boost::shared_ptr<RouteList> r = writer.get_copy ();
417 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
418 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
419 (*i)->drop_references ();
423 /* writer goes out of scope and updates master */
427 boost::shared_ptr<RouteList> r = routes.reader ();
429 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
431 RCUWriter<DiskstreamList> dwriter (diskstreams);
432 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
433 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
434 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
435 (*i)->drop_references ();
440 diskstreams.flush ();
442 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
443 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
444 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
445 i->second->drop_references ();
450 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
451 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
456 Crossfade::set_buffer_size (0);
460 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
463 boost_debug_list_ptrs ();
465 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
469 Session::set_worst_io_latencies ()
471 _worst_output_latency = 0;
472 _worst_input_latency = 0;
474 if (!_engine.connected()) {
478 boost::shared_ptr<RouteList> r = routes.reader ();
480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
481 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
482 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
487 Session::when_engine_running ()
489 string first_physical_output;
491 BootMessage (_("Set block size and sample rate"));
493 set_block_size (_engine.frames_per_cycle());
494 set_frame_rate (_engine.frame_rate());
496 BootMessage (_("Using configuration"));
498 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
499 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
501 Config->map_parameters (ff);
502 config.map_parameters (ft);
504 /* every time we reconnect, recompute worst case output latencies */
506 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
508 if (synced_to_jack()) {
509 _engine.transport_stop ();
512 if (config.get_jack_time_master()) {
513 _engine.transport_locate (_transport_frame);
521 _click_io.reset (new ClickIO (*this, "click"));
523 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
525 /* existing state for Click */
528 if (Stateful::loading_state_version < 3000) {
529 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
531 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
536 _clicking = Config->get_clicking ();
540 error << _("could not setup Click I/O") << endmsg;
547 /* default state for Click: dual-mono to first 2 physical outputs */
549 for (int physport = 0; physport < 2; ++physport) {
550 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
552 if (physical_output.length()) {
553 if (_click_io->add_port (physical_output, this)) {
554 // relax, even though its an error
559 if (_click_io->n_ports () > ChanCount::ZERO) {
560 _clicking = Config->get_clicking ();
565 catch (failed_constructor& err) {
566 error << _("cannot setup Click I/O") << endmsg;
569 BootMessage (_("Compute I/O Latencies"));
571 set_worst_io_latencies ();
574 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
577 BootMessage (_("Set up standard connections"));
579 /* Create a set of Bundle objects that map
580 to the physical I/O currently available. We create both
581 mono and stereo bundles, so that the common cases of mono
582 and stereo tracks get bundles to put in their mixer strip
583 in / out menus. There may be a nicer way of achieving that;
584 it doesn't really scale that well to higher channel counts
587 /* mono output bundles */
589 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
591 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
593 shared_ptr<Bundle> c (new Bundle (buf, true));
594 c->add_channel (_("mono"));
595 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
600 /* stereo output bundles */
602 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
603 if (np + 1 < n_physical_outputs) {
605 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
606 shared_ptr<Bundle> c (new Bundle (buf, true));
607 c->add_channel (_("L"));
608 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
609 c->add_channel (_("R"));
610 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
616 /* mono input bundles */
618 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
620 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
622 shared_ptr<Bundle> c (new Bundle (buf, false));
623 c->add_channel (_("mono"));
624 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
629 /* stereo input bundles */
631 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
632 if (np + 1 < n_physical_inputs) {
634 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
636 shared_ptr<Bundle> c (new Bundle (buf, false));
637 c->add_channel (_("L"));
638 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
639 c->add_channel (_("R"));
640 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
646 BootMessage (_("Setup signal flow and plugins"));
650 if (!no_auto_connect()) {
652 if (_master_out && Config->get_auto_connect_standard_busses()) {
654 /* if requested auto-connect the outputs to the first N physical ports.
657 uint32_t limit = _master_out->n_outputs().n_total();
659 for (uint32_t n = 0; n < limit; ++n) {
660 Port* p = _master_out->output()->nth (n);
661 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
663 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
664 if (_master_out->output()->connect (p, connect_to, this)) {
665 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
675 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
676 are undefined, at best.
679 /* control out listens to master bus (but ignores it
680 under some conditions)
683 uint32_t limit = _control_out->n_inputs().n_audio();
686 for (uint32_t n = 0; n < limit; ++n) {
687 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
688 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
691 string connect_to = o->name();
692 if (_control_out->input()->connect (p, connect_to, this)) {
693 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
701 /* if control out is not connected,
702 connect control out to physical outs, but use ones after the master if possible
705 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
707 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
709 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
712 _control_out->output()->connect_ports_to_bundle (b, this);
714 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
715 Config->get_monitor_bus_preferred_bundle())
721 /* XXX this logic is wrong for mixed port types */
723 uint32_t shift = _master_out->n_outputs().n_audio();
724 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
725 limit = _control_out->n_outputs().n_audio();
727 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
729 for (uint32_t n = 0; n < limit; ++n) {
731 Port* p = _control_out->output()->nth (n);
732 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
734 if (!connect_to.empty()) {
735 if (_control_out->output()->connect (p, connect_to, this)) {
736 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
747 /* catch up on send+insert cnts */
749 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
751 /* hook us up to the engine */
753 BootMessage (_("Connect to engine"));
755 _engine.set_session (this);
759 Session::hookup_io ()
761 /* stop graph reordering notifications from
762 causing resorts, etc.
765 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
770 /* we delay creating the auditioner till now because
771 it makes its own connections to ports.
772 the engine has to be running for this to work.
776 auditioner.reset (new Auditioner (*this));
779 catch (failed_constructor& err) {
780 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
784 /* load bundles, which we may have postponed earlier on */
785 if (_bundle_xml_node) {
786 load_bundles (*_bundle_xml_node);
787 delete _bundle_xml_node;
790 /* Tell all IO objects to connect themselves together */
792 IO::enable_connecting ();
794 /* Now reset all panners */
796 Delivery::reset_panners ();
798 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
802 boost::shared_ptr<RouteList> r = routes.reader ();
804 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
806 if ((*x)->is_control() || (*x)->is_master()) {
810 (*x)->listen_via (_control_out,
811 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
816 /* Anyone who cares about input state, wake up and do something */
818 IOConnectionsComplete (); /* EMIT SIGNAL */
820 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
822 /* now handle the whole enchilada as if it was one
828 /* update the full solo state, which can't be
829 correctly determined on a per-route basis, but
830 needs the global overview that only the session
834 update_route_solo_state ();
838 Session::playlist_length_changed ()
840 /* we can't just increase end_location->end() if pl->get_maximum_extent()
841 if larger. if the playlist used to be the longest playlist,
842 and its now shorter, we have to decrease end_location->end(). hence,
843 we have to iterate over all diskstreams and check the
844 playlists currently in use.
850 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
852 boost::shared_ptr<Diskstream> dstream = wp.lock ();
857 boost::shared_ptr<Playlist> playlist;
859 if ((playlist = dstream->playlist()) != 0) {
860 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
863 /* see comment in playlist_length_changed () */
868 Session::record_enabling_legal () const
870 /* this used to be in here, but survey says.... we don't need to restrict it */
871 // if (record_status() == Recording) {
875 if (Config->get_all_safe()) {
882 Session::reset_input_monitor_state ()
884 if (transport_rolling()) {
886 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
888 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
889 if ((*i)->record_enabled ()) {
890 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
891 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
895 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
897 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
898 if ((*i)->record_enabled ()) {
899 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
900 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
907 Session::auto_punch_start_changed (Location* location)
909 replace_event (SessionEvent::PunchIn, location->start());
911 if (get_record_enabled() && config.get_punch_in()) {
912 /* capture start has been changed, so save new pending state */
913 save_state ("", true);
918 Session::auto_punch_end_changed (Location* location)
920 nframes_t when_to_stop = location->end();
921 // when_to_stop += _worst_output_latency + _worst_input_latency;
922 replace_event (SessionEvent::PunchOut, when_to_stop);
926 Session::auto_punch_changed (Location* location)
928 nframes_t when_to_stop = location->end();
930 replace_event (SessionEvent::PunchIn, location->start());
931 //when_to_stop += _worst_output_latency + _worst_input_latency;
932 replace_event (SessionEvent::PunchOut, when_to_stop);
936 Session::auto_loop_changed (Location* location)
938 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
940 if (transport_rolling() && play_loop) {
943 // if (_transport_frame > location->end()) {
945 if (_transport_frame < location->start() || _transport_frame > location->end()) {
946 // relocate to beginning of loop
947 clear_events (SessionEvent::LocateRoll);
949 request_locate (location->start(), true);
952 else if (Config->get_seamless_loop() && !loop_changing) {
954 // schedule a locate-roll to refill the diskstreams at the
956 loop_changing = true;
958 if (location->end() > last_loopend) {
959 clear_events (SessionEvent::LocateRoll);
960 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
967 last_loopend = location->end();
971 Session::set_auto_punch_location (Location* location)
975 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
976 punch_connections.drop_connections();
977 existing->set_auto_punch (false, this);
978 remove_event (existing->start(), SessionEvent::PunchIn);
979 clear_events (SessionEvent::PunchOut);
980 auto_punch_location_changed (0);
989 if (location->end() <= location->start()) {
990 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
994 punch_connections.drop_connections ();
996 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
997 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
998 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1000 location->set_auto_punch (true, this);
1002 auto_punch_changed (location);
1004 auto_punch_location_changed (location);
1008 Session::set_auto_loop_location (Location* location)
1012 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1013 loop_connections.drop_connections ();
1014 existing->set_auto_loop (false, this);
1015 remove_event (existing->end(), SessionEvent::AutoLoop);
1016 auto_loop_location_changed (0);
1021 if (location == 0) {
1025 if (location->end() <= location->start()) {
1026 error << _("Session: you can't use a mark for auto loop") << endmsg;
1030 last_loopend = location->end();
1032 loop_connections.drop_connections ();
1034 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1035 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1036 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1038 location->set_auto_loop (true, this);
1040 /* take care of our stuff first */
1042 auto_loop_changed (location);
1044 /* now tell everyone else */
1046 auto_loop_location_changed (location);
1050 Session::locations_added (Location *)
1056 Session::locations_changed ()
1058 _locations.apply (*this, &Session::handle_locations_changed);
1062 Session::handle_locations_changed (Locations::LocationList& locations)
1064 Locations::LocationList::iterator i;
1066 bool set_loop = false;
1067 bool set_punch = false;
1069 for (i = locations.begin(); i != locations.end(); ++i) {
1073 if (location->is_auto_punch()) {
1074 set_auto_punch_location (location);
1077 if (location->is_auto_loop()) {
1078 set_auto_loop_location (location);
1082 if (location->is_start()) {
1083 start_location = location;
1085 if (location->is_end()) {
1086 end_location = location;
1091 set_auto_loop_location (0);
1094 set_auto_punch_location (0);
1101 Session::enable_record ()
1103 /* XXX really atomic compare+swap here */
1104 if (g_atomic_int_get (&_record_status) != Recording) {
1105 g_atomic_int_set (&_record_status, Recording);
1106 _last_record_location = _transport_frame;
1107 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1109 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1110 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1111 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1112 if ((*i)->record_enabled ()) {
1113 (*i)->monitor_input (true);
1118 RecordStateChanged ();
1123 Session::disable_record (bool rt_context, bool force)
1127 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1129 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1130 g_atomic_int_set (&_record_status, Disabled);
1132 if (rs == Recording) {
1133 g_atomic_int_set (&_record_status, Enabled);
1137 // FIXME: timestamp correct? [DR]
1138 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1139 // does this /need/ to be sent in all cases?
1141 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1144 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1145 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1147 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1148 if ((*i)->record_enabled ()) {
1149 (*i)->monitor_input (false);
1154 RecordStateChanged (); /* emit signal */
1157 remove_pending_capture_state ();
1163 Session::step_back_from_record ()
1165 /* XXX really atomic compare+swap here */
1166 if (g_atomic_int_get (&_record_status) == Recording) {
1167 g_atomic_int_set (&_record_status, Enabled);
1169 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1170 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1172 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1173 if ((*i)->record_enabled ()) {
1174 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1175 (*i)->monitor_input (false);
1183 Session::maybe_enable_record ()
1185 g_atomic_int_set (&_record_status, Enabled);
1187 /* this function is currently called from somewhere other than an RT thread.
1188 this save_state() call therefore doesn't impact anything.
1191 save_state ("", true);
1193 if (_transport_speed) {
1194 if (!config.get_punch_in()) {
1198 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1199 RecordStateChanged (); /* EMIT SIGNAL */
1206 Session::audible_frame () const
1212 /* the first of these two possible settings for "offset"
1213 mean that the audible frame is stationary until
1214 audio emerges from the latency compensation
1217 the second means that the audible frame is stationary
1218 until audio would emerge from a physical port
1219 in the absence of any plugin latency compensation
1222 offset = _worst_output_latency;
1224 if (offset > current_block_size) {
1225 offset -= current_block_size;
1227 /* XXX is this correct? if we have no external
1228 physical connections and everything is internal
1229 then surely this is zero? still, how
1230 likely is that anyway?
1232 offset = current_block_size;
1235 if (synced_to_jack()) {
1236 tf = _engine.transport_frame();
1238 tf = _transport_frame;
1243 if (!non_realtime_work_pending()) {
1247 /* check to see if we have passed the first guaranteed
1248 audible frame past our last start position. if not,
1249 return that last start point because in terms
1250 of audible frames, we have not moved yet.
1253 if (_transport_speed > 0.0f) {
1255 if (!play_loop || !have_looped) {
1256 if (tf < _last_roll_location + offset) {
1257 return _last_roll_location;
1265 } else if (_transport_speed < 0.0f) {
1267 /* XXX wot? no backward looping? */
1269 if (tf > _last_roll_location - offset) {
1270 return _last_roll_location;
1282 Session::set_frame_rate (nframes_t frames_per_second)
1284 /** \fn void Session::set_frame_size(nframes_t)
1285 the AudioEngine object that calls this guarantees
1286 that it will not be called while we are also in
1287 ::process(). Its fine to do things that block
1291 _base_frame_rate = frames_per_second;
1295 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1299 // XXX we need some equivalent to this, somehow
1300 // SndFileSource::setup_standard_crossfades (frames_per_second);
1304 /* XXX need to reset/reinstantiate all LADSPA plugins */
1308 Session::set_block_size (nframes_t nframes)
1310 /* the AudioEngine guarantees
1311 that it will not be called while we are also in
1312 ::process(). It is therefore fine to do things that block
1317 current_block_size = nframes;
1319 ensure_buffers(_scratch_buffers->available());
1321 delete [] _gain_automation_buffer;
1322 _gain_automation_buffer = new gain_t[nframes];
1324 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1326 boost::shared_ptr<RouteList> r = routes.reader ();
1328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1329 (*i)->set_block_size (nframes);
1332 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1333 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1334 (*i)->set_block_size (nframes);
1337 set_worst_io_latencies ();
1342 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1345 nframes_t fade_frames;
1347 /* Don't allow fade of less 1 frame */
1349 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1356 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1360 default_fade_msecs = fade_msecs;
1361 default_fade_steepness = steepness;
1364 // jlc, WTF is this!
1365 Glib::RWLock::ReaderLock lm (route_lock);
1366 AudioRegion::set_default_fade (steepness, fade_frames);
1371 /* XXX have to do this at some point */
1372 /* foreach region using default fade, reset, then
1373 refill_all_diskstream_buffers ();
1378 struct RouteSorter {
1379 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1380 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1382 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1385 if (r1->fed_by.empty()) {
1386 if (r2->fed_by.empty()) {
1387 /* no ardour-based connections inbound to either route. just use signal order */
1388 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390 /* r2 has connections, r1 does not; run r1 early */
1394 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1401 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1403 shared_ptr<Route> r2;
1405 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1406 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1410 /* make a copy of the existing list of routes that feed r1 */
1412 set<weak_ptr<Route> > existing = r1->fed_by;
1414 /* for each route that feeds r1, recurse, marking it as feeding
1418 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1419 if (!(r2 = (*i).lock ())) {
1420 /* (*i) went away, ignore it */
1424 /* r2 is a route that feeds r1 which somehow feeds base. mark
1425 base as being fed by r2
1428 rbase->fed_by.insert (r2);
1432 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1436 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1440 /* now recurse, so that we can mark base as being fed by
1441 all routes that feed r2
1444 trace_terminal (r2, rbase);
1451 Session::resort_routes ()
1453 /* don't do anything here with signals emitted
1454 by Routes while we are being destroyed.
1457 if (_state_of_the_state & Deletion) {
1464 RCUWriter<RouteList> writer (routes);
1465 shared_ptr<RouteList> r = writer.get_copy ();
1466 resort_routes_using (r);
1467 /* writer goes out of scope and forces update */
1472 Session::resort_routes_using (shared_ptr<RouteList> r)
1474 RouteList::iterator i, j;
1476 for (i = r->begin(); i != r->end(); ++i) {
1478 (*i)->fed_by.clear ();
1480 for (j = r->begin(); j != r->end(); ++j) {
1482 /* although routes can feed themselves, it will
1483 cause an endless recursive descent if we
1484 detect it. so don't bother checking for
1492 if ((*j)->feeds (*i)) {
1493 (*i)->fed_by.insert (*j);
1498 for (i = r->begin(); i != r->end(); ++i) {
1499 trace_terminal (*i, *i);
1506 cerr << "finished route resort\n";
1508 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1509 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1516 list<boost::shared_ptr<MidiTrack> >
1517 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1519 char track_name[32];
1520 uint32_t track_id = 0;
1523 RouteList new_routes;
1524 list<boost::shared_ptr<MidiTrack> > ret;
1525 //uint32_t control_id;
1527 // FIXME: need physical I/O and autoconnect stuff for MIDI
1529 /* count existing midi tracks */
1532 shared_ptr<RouteList> r = routes.reader ();
1534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1535 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1536 if (!(*i)->is_hidden()) {
1538 //channels_used += (*i)->n_inputs().n_midi();
1544 vector<string> physinputs;
1545 vector<string> physoutputs;
1547 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1548 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1550 // control_id = ntracks() + nbusses();
1554 /* check for duplicate route names, since we might have pre-existing
1555 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1556 save, close,restart,add new route - first named route is now
1564 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1566 if (route_by_name (track_name) == 0) {
1570 } while (track_id < (UINT_MAX-1));
1572 shared_ptr<MidiTrack> track;
1575 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1577 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1578 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1583 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1584 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1590 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1594 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1595 port = physinputs[(channels_used+x)%nphysical_in];
1598 if (port.length() && track->connect_input (track->input (x), port, this)) {
1604 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1608 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1609 port = physoutputs[(channels_used+x)%nphysical_out];
1610 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1612 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1616 if (port.length() && track->connect_output (track->output (x), port, this)) {
1621 channels_used += track->n_inputs ().n_midi();
1625 track->midi_diskstream()->non_realtime_input_change();
1627 route_group->add (track);
1630 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1631 //track->set_remote_control_id (control_id);
1633 new_routes.push_back (track);
1634 ret.push_back (track);
1637 catch (failed_constructor &err) {
1638 error << _("Session: could not create new midi track.") << endmsg;
1641 /* we need to get rid of this, since the track failed to be created */
1642 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1645 RCUWriter<DiskstreamList> writer (diskstreams);
1646 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1647 ds->remove (track->midi_diskstream());
1654 catch (AudioEngine::PortRegistrationFailure& pfe) {
1656 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1659 /* we need to get rid of this, since the track failed to be created */
1660 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1663 RCUWriter<DiskstreamList> writer (diskstreams);
1664 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1665 ds->remove (track->midi_diskstream());
1676 if (!new_routes.empty()) {
1677 add_routes (new_routes, false);
1678 save_state (_current_snapshot_name);
1684 list<boost::shared_ptr<AudioTrack> >
1685 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1687 char track_name[32];
1688 uint32_t track_id = 0;
1690 uint32_t channels_used = 0;
1692 RouteList new_routes;
1693 list<boost::shared_ptr<AudioTrack> > ret;
1694 uint32_t control_id;
1696 /* count existing audio tracks */
1699 shared_ptr<RouteList> r = routes.reader ();
1701 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1702 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1703 if (!(*i)->is_hidden()) {
1705 channels_used += (*i)->n_inputs().n_audio();
1711 vector<string> physinputs;
1712 vector<string> physoutputs;
1714 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1715 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1717 control_id = ntracks() + nbusses() + 1;
1721 /* check for duplicate route names, since we might have pre-existing
1722 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1723 save, close,restart,add new route - first named route is now
1731 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1733 if (route_by_name (track_name) == 0) {
1737 } while (track_id < (UINT_MAX-1));
1739 shared_ptr<AudioTrack> track;
1742 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1743 boost_debug_shared_ptr_mark_interesting (at, "Track");
1744 track = boost::shared_ptr<AudioTrack>(at);
1746 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1747 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1748 input_channels, output_channels)
1753 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1754 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1755 input_channels, output_channels)
1760 if (!physinputs.empty()) {
1761 uint32_t nphysical_in = physinputs.size();
1763 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1767 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1768 port = physinputs[(channels_used+x)%nphysical_in];
1771 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1777 if (!physoutputs.empty()) {
1778 uint32_t nphysical_out = physoutputs.size();
1780 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1783 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1784 port = physoutputs[(channels_used+x)%nphysical_out];
1785 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1786 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1787 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1791 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1797 channels_used += track->n_inputs ().n_audio();
1800 route_group->add (track);
1803 track->audio_diskstream()->non_realtime_input_change();
1805 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1806 track->set_remote_control_id (control_id);
1809 new_routes.push_back (track);
1810 ret.push_back (track);
1813 catch (failed_constructor &err) {
1814 error << _("Session: could not create new audio track.") << endmsg;
1817 /* we need to get rid of this, since the track failed to be created */
1818 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1821 RCUWriter<DiskstreamList> writer (diskstreams);
1822 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1823 ds->remove (track->audio_diskstream());
1830 catch (AudioEngine::PortRegistrationFailure& pfe) {
1832 error << pfe.what() << endmsg;
1835 /* we need to get rid of this, since the track failed to be created */
1836 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1839 RCUWriter<DiskstreamList> writer (diskstreams);
1840 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1841 ds->remove (track->audio_diskstream());
1852 if (!new_routes.empty()) {
1853 add_routes (new_routes, true);
1860 Session::set_remote_control_ids ()
1862 RemoteModel m = Config->get_remote_model();
1864 shared_ptr<RouteList> r = routes.reader ();
1866 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1867 if ( MixerOrdered == m) {
1868 long order = (*i)->order_key(N_("signal"));
1869 (*i)->set_remote_control_id( order+1 );
1870 } else if ( EditorOrdered == m) {
1871 long order = (*i)->order_key(N_("editor"));
1872 (*i)->set_remote_control_id( order+1 );
1873 } else if ( UserOrdered == m) {
1874 //do nothing ... only changes to remote id's are initiated by user
1881 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1884 uint32_t bus_id = 1;
1886 uint32_t channels_used = 0;
1889 uint32_t control_id;
1891 /* count existing audio busses */
1894 shared_ptr<RouteList> r = routes.reader ();
1896 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1897 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1899 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1902 channels_used += (*i)->n_inputs().n_audio();
1908 vector<string> physinputs;
1909 vector<string> physoutputs;
1911 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1912 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1914 n_physical_audio_outputs = physoutputs.size();
1915 n_physical_audio_inputs = physinputs.size();
1917 control_id = ntracks() + nbusses() + 1;
1922 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1926 if (route_by_name (bus_name) == 0) {
1930 } while (bus_id < (UINT_MAX-1));
1933 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1934 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1935 shared_ptr<Route> bus (rt);
1937 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1938 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1939 input_channels, output_channels)
1945 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1946 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1947 input_channels, output_channels)
1952 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1955 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1956 port = physinputs[((n+x)%n_physical_audio_inputs)];
1959 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1964 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1967 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1968 port = physoutputs[((n+x)%n_physical_outputs)];
1969 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1971 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1975 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1980 channels_used += bus->n_inputs ().n_audio();
1983 route_group->add (bus);
1985 bus->set_remote_control_id (control_id);
1989 bus->add_internal_return ();
1992 ret.push_back (bus);
1996 catch (failed_constructor &err) {
1997 error << _("Session: could not create new audio route.") << endmsg;
2001 catch (AudioEngine::PortRegistrationFailure& pfe) {
2002 error << pfe.what() << endmsg;
2012 add_routes (ret, true);
2020 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2024 uint32_t control_id;
2026 uint32_t number = 1;
2028 if (!tree.read (template_path.c_str())) {
2032 XMLNode* node = tree.root();
2034 control_id = ntracks() + nbusses() + 1;
2038 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2040 std::string node_name = IO::name_from_state (*node_copy.children().front());
2042 /* generate a new name by adding a number to the end of the template name */
2045 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2049 if (route_by_name (name) == 0) {
2053 } while (number < UINT_MAX);
2055 if (number == UINT_MAX) {
2056 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2060 IO::set_name_in_state (*node_copy.children().front(), name);
2062 Track::zero_diskstream_id_in_xml (node_copy);
2065 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2068 error << _("Session: cannot create track/bus from template description") << endmsg;
2072 if (boost::dynamic_pointer_cast<Track>(route)) {
2073 /* force input/output change signals so that the new diskstream
2074 picks up the configuration of the route. During session
2075 loading this normally happens in a different way.
2077 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2078 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2081 route->set_remote_control_id (control_id);
2084 ret.push_back (route);
2087 catch (failed_constructor &err) {
2088 error << _("Session: could not create new route from template") << endmsg;
2092 catch (AudioEngine::PortRegistrationFailure& pfe) {
2093 error << pfe.what() << endmsg;
2102 add_routes (ret, true);
2109 Session::add_routes (RouteList& new_routes, bool save)
2112 RCUWriter<RouteList> writer (routes);
2113 shared_ptr<RouteList> r = writer.get_copy ();
2114 r->insert (r->end(), new_routes.begin(), new_routes.end());
2117 /* if there is no control out and we're not in the middle of loading,
2118 resort the graph here. if there is a control out, we will resort
2119 toward the end of this method. if we are in the middle of loading,
2120 we will resort when done.
2123 if (!_control_out && IO::connecting_legal) {
2124 resort_routes_using (r);
2128 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2130 boost::weak_ptr<Route> wpr (*x);
2131 boost::shared_ptr<Route> r (*x);
2133 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2134 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
2135 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2136 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2137 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2138 r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2140 if (r->is_master()) {
2144 if (r->is_control()) {
2149 if (_control_out && IO::connecting_legal) {
2151 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2152 if ((*x)->is_control() || (*x)->is_master()) {
2155 (*x)->listen_via (_control_out,
2156 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2166 save_state (_current_snapshot_name);
2169 RouteAdded (new_routes); /* EMIT SIGNAL */
2173 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2175 boost::shared_ptr<RouteList> r = routes.reader ();
2176 boost::shared_ptr<Send> s;
2180 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2181 if (boost::dynamic_pointer_cast<Track>(*i)) {
2182 if ((s = (*i)->internal_send_for (dest)) != 0) {
2183 s->amp()->gain_control()->set_value (0.0);
2190 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2192 boost::shared_ptr<RouteList> r = routes.reader ();
2193 boost::shared_ptr<Send> s;
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if (boost::dynamic_pointer_cast<Track>(*i)) {
2199 if ((s = (*i)->internal_send_for (dest)) != 0) {
2200 s->amp()->gain_control()->set_value (1.0);
2207 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2209 boost::shared_ptr<RouteList> r = routes.reader ();
2210 boost::shared_ptr<Send> s;
2214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2215 if (boost::dynamic_pointer_cast<Track>(*i)) {
2216 if ((s = (*i)->internal_send_for (dest)) != 0) {
2217 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2224 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2226 boost::shared_ptr<RouteList> r = routes.reader ();
2227 boost::shared_ptr<RouteList> t (new RouteList);
2229 /* only send tracks */
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if (boost::dynamic_pointer_cast<Track>(*i)) {
2237 add_internal_sends (dest, p, t);
2241 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2243 if (dest->is_control() || dest->is_master()) {
2247 if (!dest->internal_return()) {
2248 dest->add_internal_return();
2251 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2253 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2257 (*i)->listen_via (dest, p, true, true);
2264 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2266 /* need to do this in case we're rolling at the time, to prevent false underruns */
2267 dstream->do_refill_with_alloc ();
2269 dstream->set_block_size (current_block_size);
2272 RCUWriter<DiskstreamList> writer (diskstreams);
2273 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2274 ds->push_back (dstream);
2275 /* writer goes out of scope, copies ds back to main */
2278 dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr<Diskstream> (dstream)));
2279 /* this will connect to future changes, and check the current length */
2280 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2282 dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this));
2284 dstream->prepare ();
2289 Session::remove_route (shared_ptr<Route> route)
2292 RCUWriter<RouteList> writer (routes);
2293 shared_ptr<RouteList> rs = writer.get_copy ();
2297 /* deleting the master out seems like a dumb
2298 idea, but its more of a UI policy issue
2302 if (route == _master_out) {
2303 _master_out = shared_ptr<Route> ();
2306 if (route == _control_out) {
2308 /* cancel control outs for all routes */
2310 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2311 (*r)->drop_listen (_control_out);
2314 _control_out.reset ();
2317 update_route_solo_state ();
2319 /* writer goes out of scope, forces route list update */
2322 boost::shared_ptr<Track> t;
2323 boost::shared_ptr<Diskstream> ds;
2325 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2326 ds = t->diskstream();
2332 RCUWriter<DiskstreamList> dsl (diskstreams);
2333 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2338 find_current_end ();
2340 // We need to disconnect the routes inputs and outputs
2342 route->input()->disconnect (0);
2343 route->output()->disconnect (0);
2345 /* if the route had internal sends sending to it, remove them */
2346 if (route->internal_return()) {
2348 boost::shared_ptr<RouteList> r = routes.reader ();
2349 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2350 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2352 (*i)->remove_processor (s);
2357 update_latency_compensation (false, false);
2360 /* get rid of it from the dead wood collection in the route list manager */
2362 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2366 /* try to cause everyone to drop their references */
2368 route->drop_references ();
2370 sync_order_keys (N_("session"));
2372 /* save the new state of the world */
2374 if (save_state (_current_snapshot_name)) {
2375 save_history (_current_snapshot_name);
2380 Session::route_mute_changed (void* /*src*/)
2386 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2388 boost::shared_ptr<Route> route = wpr.lock();
2390 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2394 if (route->listening()) {
2396 } else if (_listen_cnt > 0) {
2402 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2404 if (solo_update_disabled) {
2409 boost::shared_ptr<Route> route = wpr.lock ();
2412 /* should not happen */
2413 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2417 shared_ptr<RouteList> r = routes.reader ();
2420 if (route->self_soloed()) {
2426 /* now mod the solo level of all other routes except master & control outs
2427 so that they will be silent if appropriate.
2430 solo_update_disabled = true;
2432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2433 bool via_sends_only;
2436 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2438 } else if ((*i)->feeds (route, &via_sends_only)) {
2439 if (!via_sends_only) {
2440 (*i)->mod_solo_by_others (delta);
2445 /* make sure master is never muted by solo */
2447 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2448 _master_out->mod_solo_by_others (1);
2451 /* ditto for control outs make sure master is never muted by solo */
2453 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2454 _control_out->mod_solo_by_others (1);
2457 solo_update_disabled = false;
2458 update_route_solo_state (r);
2459 SoloChanged (); /* EMIT SIGNAL */
2464 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2466 /* now figure out if anything that matters is soloed */
2468 bool something_soloed = false;
2471 r = routes.reader();
2474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2475 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2476 something_soloed = true;
2481 if (something_soloed != _non_soloed_outs_muted) {
2482 _non_soloed_outs_muted = something_soloed;
2483 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2487 boost::shared_ptr<RouteList>
2488 Session::get_routes_with_internal_returns() const
2490 shared_ptr<RouteList> r = routes.reader ();
2491 boost::shared_ptr<RouteList> rl (new RouteList);
2493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2494 if ((*i)->internal_return ()) {
2502 Session::route_by_name (string name)
2504 shared_ptr<RouteList> r = routes.reader ();
2506 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2507 if ((*i)->name() == name) {
2512 return shared_ptr<Route> ((Route*) 0);
2516 Session::route_by_id (PBD::ID id)
2518 shared_ptr<RouteList> r = routes.reader ();
2520 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2521 if ((*i)->id() == id) {
2526 return shared_ptr<Route> ((Route*) 0);
2530 Session::route_by_remote_id (uint32_t id)
2532 shared_ptr<RouteList> r = routes.reader ();
2534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2535 if ((*i)->remote_control_id() == id) {
2540 return shared_ptr<Route> ((Route*) 0);
2544 Session::find_current_end ()
2546 if (_state_of_the_state & Loading) {
2550 nframes_t max = get_maximum_extent ();
2552 if (max > end_location->end()) {
2553 end_location->set_end (max);
2555 DurationChanged(); /* EMIT SIGNAL */
2560 Session::get_maximum_extent () const
2565 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2567 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2568 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2570 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2571 if ((me = pl->get_maximum_extent()) > max) {
2579 boost::shared_ptr<Diskstream>
2580 Session::diskstream_by_name (string name)
2582 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2584 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2585 if ((*i)->name() == name) {
2590 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2593 boost::shared_ptr<Diskstream>
2594 Session::diskstream_by_id (const PBD::ID& id)
2596 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2598 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2599 if ((*i)->id() == id) {
2604 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2607 /* Region management */
2610 Session::new_region_name (string old)
2612 string::size_type last_period;
2614 string::size_type len = old.length() + 64;
2617 if ((last_period = old.find_last_of ('.')) == string::npos) {
2619 /* no period present - add one explicitly */
2622 last_period = old.length() - 1;
2627 number = atoi (old.substr (last_period+1).c_str());
2631 while (number < (UINT_MAX-1)) {
2633 RegionList::const_iterator i;
2638 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2641 for (i = regions.begin(); i != regions.end(); ++i) {
2642 if (i->second->name() == sbuf) {
2647 if (i == regions.end()) {
2652 if (number != (UINT_MAX-1)) {
2656 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2661 Session::region_name (string& result, string base, bool newlevel)
2666 if (base.find("/") != string::npos) {
2667 base = base.substr(base.find_last_of("/") + 1);
2672 Glib::Mutex::Lock lm (region_lock);
2674 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2683 string::size_type pos;
2685 pos = base.find_last_of ('.');
2687 /* pos may be npos, but then we just use entire base */
2689 subbase = base.substr (0, pos);
2694 Glib::Mutex::Lock lm (region_lock);
2696 map<string,uint32_t>::iterator x;
2700 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2702 region_name_map[subbase] = 1;
2705 snprintf (buf, sizeof (buf), ".%d", x->second);
2716 Session::add_region (boost::shared_ptr<Region> region)
2718 vector<boost::shared_ptr<Region> > v;
2719 v.push_back (region);
2724 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2729 Glib::Mutex::Lock lm (region_lock);
2731 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2733 boost::shared_ptr<Region> region = *ii;
2737 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2741 RegionList::iterator x;
2743 for (x = regions.begin(); x != regions.end(); ++x) {
2745 if (region->region_list_equivalent (x->second)) {
2750 if (x == regions.end()) {
2752 pair<RegionList::key_type,RegionList::mapped_type> entry;
2754 entry.first = region->id();
2755 entry.second = region;
2757 pair<RegionList::iterator,bool> x = regions.insert (entry);
2769 /* mark dirty because something has changed even if we didn't
2770 add the region to the region list.
2777 vector<boost::weak_ptr<Region> > v;
2778 boost::shared_ptr<Region> first_r;
2780 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2782 boost::shared_ptr<Region> region = *ii;
2786 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2789 v.push_back (region);
2796 region->StateChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region)));
2797 update_region_name_map (region);
2801 RegionsAdded (v); /* EMIT SIGNAL */
2807 Session::update_region_name_map (boost::shared_ptr<Region> region)
2809 string::size_type last_period = region->name().find_last_of ('.');
2811 if (last_period != string::npos && last_period < region->name().length() - 1) {
2813 string base = region->name().substr (0, last_period);
2814 string number = region->name().substr (last_period+1);
2815 map<string,uint32_t>::iterator x;
2817 /* note that if there is no number, we get zero from atoi,
2821 region_name_map[base] = atoi (number);
2826 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2828 boost::shared_ptr<Region> region (weak_region.lock ());
2834 if (what_changed & Region::HiddenChanged) {
2835 /* relay hidden changes */
2836 RegionHiddenChange (region);
2839 if (what_changed & NameChanged) {
2840 update_region_name_map (region);
2845 Session::remove_region (boost::weak_ptr<Region> weak_region)
2847 RegionList::iterator i;
2848 boost::shared_ptr<Region> region (weak_region.lock ());
2854 bool removed = false;
2857 Glib::Mutex::Lock lm (region_lock);
2859 if ((i = regions.find (region->id())) != regions.end()) {
2865 /* mark dirty because something has changed even if we didn't
2866 remove the region from the region list.
2872 RegionRemoved(region); /* EMIT SIGNAL */
2876 boost::shared_ptr<Region>
2877 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2879 RegionList::iterator i;
2880 boost::shared_ptr<Region> region;
2882 Glib::Mutex::Lock lm (region_lock);
2884 for (i = regions.begin(); i != regions.end(); ++i) {
2888 if (region->whole_file()) {
2890 if (child->source_equivalent (region)) {
2896 return boost::shared_ptr<Region> ();
2900 Session::destroy_region (boost::shared_ptr<Region> region)
2902 vector<boost::shared_ptr<Source> > srcs;
2905 if (region->playlist()) {
2906 region->playlist()->destroy_region (region);
2909 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2910 srcs.push_back (region->source (n));
2914 region->drop_references ();
2916 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2918 (*i)->mark_for_remove ();
2919 (*i)->drop_references ();
2921 cerr << "source was not used by any playlist\n";
2928 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2930 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2931 destroy_region (*i);
2937 Session::remove_last_capture ()
2939 list<boost::shared_ptr<Region> > r;
2941 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2943 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2944 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2947 r.insert (r.end(), l.begin(), l.end());
2952 for (list<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
2956 destroy_regions (r);
2958 save_state (_current_snapshot_name);
2964 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2970 /* Source Management */
2973 Session::add_source (boost::shared_ptr<Source> source)
2975 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2976 pair<SourceMap::iterator,bool> result;
2978 entry.first = source->id();
2979 entry.second = source;
2982 Glib::Mutex::Lock lm (source_lock);
2983 result = sources.insert (entry);
2986 if (result.second) {
2990 boost::shared_ptr<AudioFileSource> afs;
2992 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2993 if (Config->get_auto_analyse_audio()) {
2994 Analyser::queue_source_for_analysis (source, false);
3000 Session::remove_source (boost::weak_ptr<Source> src)
3002 SourceMap::iterator i;
3003 boost::shared_ptr<Source> source = src.lock();
3010 Glib::Mutex::Lock lm (source_lock);
3012 if ((i = sources.find (source->id())) != sources.end()) {
3017 if (!_state_of_the_state & InCleanup) {
3019 /* save state so we don't end up with a session file
3020 referring to non-existent sources.
3023 save_state (_current_snapshot_name);
3027 boost::shared_ptr<Source>
3028 Session::source_by_id (const PBD::ID& id)
3030 Glib::Mutex::Lock lm (source_lock);
3031 SourceMap::iterator i;
3032 boost::shared_ptr<Source> source;
3034 if ((i = sources.find (id)) != sources.end()) {
3041 boost::shared_ptr<Source>
3042 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3044 Glib::Mutex::Lock lm (source_lock);
3046 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3047 cerr << "comparing " << path << " with " << i->second->name() << endl;
3048 boost::shared_ptr<AudioFileSource> afs
3049 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3051 if (afs && afs->path() == path && chn == afs->channel()) {
3055 return boost::shared_ptr<Source>();
3060 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3063 string old_basename = PBD::basename_nosuffix (oldname);
3064 string new_legalized = legalize_for_path (newname);
3066 /* note: we know (or assume) the old path is already valid */
3070 /* destructive file sources have a name of the form:
3072 /path/to/Tnnnn-NAME(%[LR])?.wav
3074 the task here is to replace NAME with the new name.
3077 /* find last slash */
3081 string::size_type slash;
3082 string::size_type dash;
3084 if ((slash = path.find_last_of ('/')) == string::npos) {
3088 dir = path.substr (0, slash+1);
3090 /* '-' is not a legal character for the NAME part of the path */
3092 if ((dash = path.find_last_of ('-')) == string::npos) {
3096 prefix = path.substr (slash+1, dash-(slash+1));
3101 path += new_legalized;
3102 path += ".wav"; /* XXX gag me with a spoon */
3106 /* non-destructive file sources have a name of the form:
3108 /path/to/NAME-nnnnn(%[LR])?.ext
3110 the task here is to replace NAME with the new name.
3115 string::size_type slash;
3116 string::size_type dash;
3117 string::size_type postfix;
3119 /* find last slash */
3121 if ((slash = path.find_last_of ('/')) == string::npos) {
3125 dir = path.substr (0, slash+1);
3127 /* '-' is not a legal character for the NAME part of the path */
3129 if ((dash = path.find_last_of ('-')) == string::npos) {
3133 suffix = path.substr (dash+1);
3135 // Suffix is now everything after the dash. Now we need to eliminate
3136 // the nnnnn part, which is done by either finding a '%' or a '.'
3138 postfix = suffix.find_last_of ("%");
3139 if (postfix == string::npos) {
3140 postfix = suffix.find_last_of ('.');
3143 if (postfix != string::npos) {
3144 suffix = suffix.substr (postfix);
3146 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3150 const uint32_t limit = 10000;
3151 char buf[PATH_MAX+1];
3153 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3155 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3157 if (access (buf, F_OK) != 0) {
3165 error << "FATAL ERROR! Could not find a " << endl;
3173 /** Return the full path (in some session directory) for a new within-session source.
3174 * \a name must be a session-unique name that does not contain slashes
3175 * (e.g. as returned by new_*_source_name)
3178 Session::new_source_path_from_name (DataType type, const string& name)
3180 assert(name.find("/") == string::npos);
3182 SessionDirectory sdir(get_best_session_directory_for_new_source());
3185 if (type == DataType::AUDIO) {
3186 p = sdir.sound_path();
3187 } else if (type == DataType::MIDI) {
3188 p = sdir.midi_path();
3190 error << "Unknown source type, unable to create file path" << endmsg;
3195 return p.to_string();
3199 Session::peak_path (Glib::ustring base) const
3201 sys::path peakfile_path(_session_dir->peak_path());
3202 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3203 return peakfile_path.to_string();
3206 /** Return a unique name based on \a base for a new internal audio source */
3208 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3212 char buf[PATH_MAX+1];
3213 const uint32_t limit = 10000;
3217 legalized = legalize_for_path (base);
3219 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3220 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3222 vector<space_and_path>::iterator i;
3223 uint32_t existing = 0;
3225 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3227 SessionDirectory sdir((*i).path);
3229 spath = sdir.sound_path().to_string();
3234 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3235 spath.c_str(), cnt, legalized.c_str());
3236 } else if (nchan == 2) {
3238 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3239 spath.c_str(), cnt, legalized.c_str());
3241 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3242 spath.c_str(), cnt, legalized.c_str());
3244 } else if (nchan < 26) {
3245 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3246 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3248 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3249 spath.c_str(), cnt, legalized.c_str());
3258 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3259 } else if (nchan == 2) {
3261 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3263 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3265 } else if (nchan < 26) {
3266 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3268 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3272 if (sys::exists(buf)) {
3278 if (existing == 0) {
3283 error << string_compose(
3284 _("There are already %1 recordings for %2, which I consider too many."),
3285 limit, base) << endmsg;
3287 throw failed_constructor();
3291 return Glib::path_get_basename(buf);
3294 /** Create a new within-session audio source */
3295 boost::shared_ptr<AudioFileSource>
3296 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3298 const size_t n_chans = ds.n_channels().n_audio();
3299 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3300 const string path = new_source_path_from_name(DataType::AUDIO, name);
3302 return boost::dynamic_pointer_cast<AudioFileSource> (
3303 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3306 /** Return a unique name based on \a base for a new internal MIDI source */
3308 Session::new_midi_source_name (const string& base)
3311 char buf[PATH_MAX+1];
3312 const uint32_t limit = 10000;
3316 legalized = legalize_for_path (base);
3318 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3319 for (cnt = 1; cnt <= limit; ++cnt) {
3321 vector<space_and_path>::iterator i;
3322 uint32_t existing = 0;
3324 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3326 SessionDirectory sdir((*i).path);
3328 sys::path p = sdir.midi_path();
3331 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3333 if (sys::exists (buf)) {
3338 if (existing == 0) {
3343 error << string_compose(
3344 _("There are already %1 recordings for %2, which I consider too many."),
3345 limit, base) << endmsg;
3347 throw failed_constructor();
3351 return Glib::path_get_basename(buf);
3355 /** Create a new within-session MIDI source */
3356 boost::shared_ptr<MidiSource>
3357 Session::create_midi_source_for_session (MidiDiskstream& ds)
3359 const string name = new_midi_source_name (ds.name());
3360 const string path = new_source_path_from_name (DataType::MIDI, name);
3362 return boost::dynamic_pointer_cast<SMFSource> (
3363 SourceFactory::createWritable (
3364 DataType::MIDI, *this, path, false, frame_rate()));
3369 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3371 if (playlist->hidden()) {
3375 playlists->add (playlist);
3378 playlist->release();
3385 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3387 if (_state_of_the_state & Deletion) {
3391 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3397 playlists->remove (playlist);
3403 Session::set_audition (boost::shared_ptr<Region> r)
3405 pending_audition_region = r;
3406 add_post_transport_work (PostTransportAudition);
3407 _butler->schedule_transport_work ();
3411 Session::audition_playlist ()
3413 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3414 ev->region.reset ();
3419 Session::non_realtime_set_audition ()
3421 if (!pending_audition_region) {
3422 auditioner->audition_current_playlist ();
3424 auditioner->audition_region (pending_audition_region);
3425 pending_audition_region.reset ();
3427 AuditionActive (true); /* EMIT SIGNAL */
3431 Session::audition_region (boost::shared_ptr<Region> r)
3433 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3439 Session::cancel_audition ()
3441 if (auditioner->active()) {
3442 auditioner->cancel_audition ();
3443 AuditionActive (false); /* EMIT SIGNAL */
3448 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3450 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3454 Session::remove_empty_sounds ()
3456 vector<string> audio_filenames;
3458 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3460 Glib::Mutex::Lock lm (source_lock);
3462 TapeFileMatcher tape_file_matcher;
3464 remove_if (audio_filenames.begin(), audio_filenames.end(),
3465 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3467 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3469 sys::path audio_file_path (_session_dir->sound_path());
3471 audio_file_path /= *i;
3473 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3477 sys::remove (audio_file_path);
3478 const string peakfile = peak_path (audio_file_path.to_string());
3479 sys::remove (peakfile);
3481 catch (const sys::filesystem_error& err)
3483 error << err.what() << endmsg;
3490 Session::is_auditioning () const
3492 /* can be called before we have an auditioner object */
3494 return auditioner->active();
3501 Session::n_diskstreams () const
3505 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3507 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3508 if (!(*i)->hidden()) {
3516 Session::graph_reordered ()
3518 /* don't do this stuff if we are setting up connections
3519 from a set_state() call or creating new tracks. Ditto for deletion.
3522 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3526 /* every track/bus asked for this to be handled but it was deferred because
3527 we were connecting. do it now.
3530 request_input_change_handling ();
3534 /* force all diskstreams to update their capture offset values to
3535 reflect any changes in latencies within the graph.
3538 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3540 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3541 (*i)->set_capture_offset ();
3546 Session::add_processor (Processor* processor)
3548 /* Session does not own Processors (they belong to a Route) but we do want to track
3549 the arrival and departure of port inserts, sends and returns for naming
3552 processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
3557 Session::remove_processor (Processor* processor)
3561 PortInsert* port_insert;
3563 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3564 insert_bitset[port_insert->bit_slot()] = false;
3565 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3566 send_bitset[send->bit_slot()] = false;
3567 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3568 return_bitset[retrn->bit_slot()] = false;
3575 Session::available_capture_duration ()
3577 float sample_bytes_on_disk = 4.0; // keep gcc happy
3579 switch (config.get_native_file_data_format()) {
3581 sample_bytes_on_disk = 4.0;
3585 sample_bytes_on_disk = 3.0;
3589 sample_bytes_on_disk = 2.0;
3593 /* impossible, but keep some gcc versions happy */
3594 fatal << string_compose (_("programming error: %1"),
3595 X_("illegal native file data format"))
3600 double scale = 4096.0 / sample_bytes_on_disk;
3602 if (_total_free_4k_blocks * scale > (double) max_frames) {
3606 return (nframes_t) floor (_total_free_4k_blocks * scale);
3610 Session::add_bundle (shared_ptr<Bundle> bundle)
3613 RCUWriter<BundleList> writer (_bundles);
3614 boost::shared_ptr<BundleList> b = writer.get_copy ();
3615 b->push_back (bundle);
3618 BundleAdded (bundle); /* EMIT SIGNAL */
3624 Session::remove_bundle (shared_ptr<Bundle> bundle)
3626 bool removed = false;
3629 RCUWriter<BundleList> writer (_bundles);
3630 boost::shared_ptr<BundleList> b = writer.get_copy ();
3631 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3633 if (i != b->end()) {
3640 BundleRemoved (bundle); /* EMIT SIGNAL */
3647 Session::bundle_by_name (string name) const
3649 boost::shared_ptr<BundleList> b = _bundles.reader ();
3651 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3652 if ((*i)->name() == name) {
3657 return boost::shared_ptr<Bundle> ();
3661 Session::tempo_map_changed (Change)
3665 playlists->update_after_tempo_map_change ();
3670 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3671 * the given count with the current block size.
3674 Session::ensure_buffers (ChanCount howmany)
3676 if (current_block_size == 0) {
3677 return; // too early? (is this ok?)
3680 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3681 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3682 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3683 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3684 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3687 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3691 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3693 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3694 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3699 Session::next_insert_id ()
3701 /* this doesn't really loop forever. just think about it */
3704 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3705 if (!insert_bitset[n]) {
3706 insert_bitset[n] = true;
3712 /* none available, so resize and try again */
3714 insert_bitset.resize (insert_bitset.size() + 16, false);
3719 Session::next_send_id ()
3721 /* this doesn't really loop forever. just think about it */
3724 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3725 if (!send_bitset[n]) {
3726 send_bitset[n] = true;
3732 /* none available, so resize and try again */
3734 send_bitset.resize (send_bitset.size() + 16, false);
3739 Session::next_return_id ()
3741 /* this doesn't really loop forever. just think about it */
3744 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3745 if (!return_bitset[n]) {
3746 return_bitset[n] = true;
3752 /* none available, so resize and try again */
3754 return_bitset.resize (return_bitset.size() + 16, false);
3759 Session::mark_send_id (uint32_t id)
3761 if (id >= send_bitset.size()) {
3762 send_bitset.resize (id+16, false);
3764 if (send_bitset[id]) {
3765 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3767 send_bitset[id] = true;
3771 Session::mark_return_id (uint32_t id)
3773 if (id >= return_bitset.size()) {
3774 return_bitset.resize (id+16, false);
3776 if (return_bitset[id]) {
3777 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3779 return_bitset[id] = true;
3783 Session::mark_insert_id (uint32_t id)
3785 if (id >= insert_bitset.size()) {
3786 insert_bitset.resize (id+16, false);
3788 if (insert_bitset[id]) {
3789 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3791 insert_bitset[id] = true;
3794 /* Named Selection management */
3796 boost::shared_ptr<NamedSelection>
3797 Session::named_selection_by_name (string name)
3799 Glib::Mutex::Lock lm (named_selection_lock);
3800 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3801 if ((*i)->name == name) {
3805 return boost::shared_ptr<NamedSelection>();
3809 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3812 Glib::Mutex::Lock lm (named_selection_lock);
3813 named_selections.insert (named_selections.begin(), named_selection);
3818 NamedSelectionAdded (); /* EMIT SIGNAL */
3822 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3824 bool removed = false;
3827 Glib::Mutex::Lock lm (named_selection_lock);
3829 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3831 if (i != named_selections.end()) {
3832 named_selections.erase (i);
3839 NamedSelectionRemoved (); /* EMIT SIGNAL */
3844 Session::reset_native_file_format ()
3846 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3848 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3849 (*i)->reset_write_sources (false);
3854 Session::route_name_unique (string n) const
3856 shared_ptr<RouteList> r = routes.reader ();
3858 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3859 if ((*i)->name() == n) {
3868 Session::route_name_internal (string n) const
3870 if (auditioner && auditioner->name() == n) {
3874 if (_click_io && _click_io->name() == n) {
3882 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3884 if (!force && howmany <= _npan_buffers) {
3888 if (_pan_automation_buffer) {
3890 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3891 delete [] _pan_automation_buffer[i];
3894 delete [] _pan_automation_buffer;
3897 _pan_automation_buffer = new pan_t*[howmany];
3899 for (uint32_t i = 0; i < howmany; ++i) {
3900 _pan_automation_buffer[i] = new pan_t[nframes];
3903 _npan_buffers = howmany;
3907 Session::freeze (InterThreadInfo& itt)
3909 shared_ptr<RouteList> r = routes.reader ();
3911 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3913 boost::shared_ptr<Track> t;
3915 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3916 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3926 boost::shared_ptr<Region>
3927 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3928 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3929 InterThreadInfo& itt, bool enable_processing)
3931 boost::shared_ptr<Region> result;
3932 boost::shared_ptr<Playlist> playlist;
3933 boost::shared_ptr<AudioFileSource> fsource;
3935 char buf[PATH_MAX+1];
3936 ChanCount nchans(track.audio_diskstream()->n_channels());
3938 nframes_t this_chunk;
3941 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3942 const string sound_dir = sdir.sound_path().to_string();
3943 nframes_t len = end - start;
3946 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3947 end, start) << endmsg;
3951 const nframes_t chunk_size = (256 * 1024)/4;
3953 // block all process callback handling
3955 block_processing ();
3957 /* call tree *MUST* hold route_lock */
3959 if ((playlist = track.diskstream()->playlist()) == 0) {
3963 /* external redirects will be a problem */
3965 if (track.has_external_redirects()) {
3969 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3971 for (x = 0; x < 99999; ++x) {
3972 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3973 if (access (buf, F_OK) != 0) {
3979 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3984 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3985 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3988 catch (failed_constructor& err) {
3989 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3993 srcs.push_back (fsource);
3996 /* XXX need to flush all redirects */
4001 /* create a set of reasonably-sized buffers */
4002 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4003 buffers.set_count(nchans);
4005 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4006 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4008 afs->prepare_for_peakfile_writes ();
4011 while (to_do && !itt.cancel) {
4013 this_chunk = min (to_do, chunk_size);
4015 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4020 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4021 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4024 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4030 start += this_chunk;
4031 to_do -= this_chunk;
4033 itt.progress = (float) (1.0 - ((double) to_do / len));
4042 xnow = localtime (&now);
4044 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4045 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4048 afs->update_header (position, *xnow, now);
4049 afs->flush_header ();
4053 /* construct a region to represent the bounced material */
4055 result = RegionFactory::create (srcs, 0,
4056 srcs.front()->length(srcs.front()->timeline_position()),
4057 region_name_from_path (srcs.front()->name(), true));
4062 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4063 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4066 afs->mark_for_remove ();
4069 (*src)->drop_references ();
4073 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4074 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4077 afs->done_with_peakfile_writes ();
4081 unblock_processing ();
4087 Session::get_silent_buffers (ChanCount count)
4089 assert(_silent_buffers->available() >= count);
4090 _silent_buffers->set_count(count);
4092 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4093 for (size_t i= 0; i < count.get(*t); ++i) {
4094 _silent_buffers->get(*t, i).clear();
4098 return *_silent_buffers;
4102 Session::get_scratch_buffers (ChanCount count)
4104 if (count != ChanCount::ZERO) {
4105 assert(_scratch_buffers->available() >= count);
4106 _scratch_buffers->set_count(count);
4108 _scratch_buffers->set_count (_scratch_buffers->available());
4111 return *_scratch_buffers;
4115 Session::get_mix_buffers (ChanCount count)
4117 assert(_mix_buffers->available() >= count);
4118 _mix_buffers->set_count(count);
4119 return *_mix_buffers;
4123 Session::ntracks () const
4126 shared_ptr<RouteList> r = routes.reader ();
4128 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4129 if (boost::dynamic_pointer_cast<Track> (*i)) {
4138 Session::nbusses () const
4141 shared_ptr<RouteList> r = routes.reader ();
4143 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4144 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4153 Session::add_automation_list(AutomationList *al)
4155 automation_lists[al->id()] = al;
4159 Session::compute_initial_length ()
4161 return _engine.frame_rate() * 60 * 5;
4165 Session::sync_order_keys (std::string const & base)
4167 if (deletion_in_progress()) {
4171 if (!Config->get_sync_all_route_ordering()) {
4172 /* leave order keys as they are */
4176 boost::shared_ptr<RouteList> r = routes.reader ();
4178 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4179 (*i)->sync_order_keys (base);
4182 Route::SyncOrderKeys (base); // EMIT SIGNAL
4186 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4188 Session::have_rec_enabled_diskstream () const
4190 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4193 /** Update the state of our rec-enabled diskstreams flag */
4195 Session::update_have_rec_enabled_diskstream ()
4197 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4198 DiskstreamList::iterator i = dsl->begin ();
4199 while (i != dsl->end () && (*i)->record_enabled () == false) {
4203 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4205 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4207 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4208 RecordStateChanged (); /* EMIT SIGNAL */
4213 Session::listen_position_changed ()
4217 switch (Config->get_listen_position()) {
4218 case AfterFaderListen:
4222 case PreFaderListen:
4227 boost::shared_ptr<RouteList> r = routes.reader ();
4229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4230 (*i)->put_control_outs_at (p);
4235 Session::solo_control_mode_changed ()
4237 /* cancel all solo or all listen when solo control mode changes */
4239 if (Config->get_solo_control_is_listen_control()) {
4240 set_solo (routes.reader(), false);
4242 set_listen (routes.reader(), false);
4247 Session::route_group_changed ()
4249 RouteGroupChanged (); /* EMIT SIGNAL */
4253 Session::get_available_sync_options () const
4255 vector<SyncSource> ret;
4257 ret.push_back (JACK);
4260 ret.push_back (MTC);
4263 if (midi_clock_port()) {
4264 ret.push_back (MIDIClock);
4270 boost::shared_ptr<RouteList>
4271 Session::get_routes_with_regions_at (nframes64_t const p) const
4273 shared_ptr<RouteList> r = routes.reader ();
4274 shared_ptr<RouteList> rl (new RouteList);
4276 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4277 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4282 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4287 boost::shared_ptr<Playlist> pl = ds->playlist ();
4292 if (pl->has_region_at (p)) {