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 destroy_regions (r);
2954 save_state (_current_snapshot_name);
2960 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2966 /* Source Management */
2969 Session::add_source (boost::shared_ptr<Source> source)
2971 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2972 pair<SourceMap::iterator,bool> result;
2974 entry.first = source->id();
2975 entry.second = source;
2978 Glib::Mutex::Lock lm (source_lock);
2979 result = sources.insert (entry);
2982 if (result.second) {
2986 boost::shared_ptr<AudioFileSource> afs;
2988 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2989 if (Config->get_auto_analyse_audio()) {
2990 Analyser::queue_source_for_analysis (source, false);
2996 Session::remove_source (boost::weak_ptr<Source> src)
2998 SourceMap::iterator i;
2999 boost::shared_ptr<Source> source = src.lock();
3006 Glib::Mutex::Lock lm (source_lock);
3008 if ((i = sources.find (source->id())) != sources.end()) {
3013 if (!_state_of_the_state & InCleanup) {
3015 /* save state so we don't end up with a session file
3016 referring to non-existent sources.
3019 save_state (_current_snapshot_name);
3023 boost::shared_ptr<Source>
3024 Session::source_by_id (const PBD::ID& id)
3026 Glib::Mutex::Lock lm (source_lock);
3027 SourceMap::iterator i;
3028 boost::shared_ptr<Source> source;
3030 if ((i = sources.find (id)) != sources.end()) {
3037 boost::shared_ptr<Source>
3038 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3040 Glib::Mutex::Lock lm (source_lock);
3042 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3043 cerr << "comparing " << path << " with " << i->second->name() << endl;
3044 boost::shared_ptr<AudioFileSource> afs
3045 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3047 if (afs && afs->path() == path && chn == afs->channel()) {
3051 return boost::shared_ptr<Source>();
3056 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3059 string old_basename = PBD::basename_nosuffix (oldname);
3060 string new_legalized = legalize_for_path (newname);
3062 /* note: we know (or assume) the old path is already valid */
3066 /* destructive file sources have a name of the form:
3068 /path/to/Tnnnn-NAME(%[LR])?.wav
3070 the task here is to replace NAME with the new name.
3073 /* find last slash */
3077 string::size_type slash;
3078 string::size_type dash;
3080 if ((slash = path.find_last_of ('/')) == string::npos) {
3084 dir = path.substr (0, slash+1);
3086 /* '-' is not a legal character for the NAME part of the path */
3088 if ((dash = path.find_last_of ('-')) == string::npos) {
3092 prefix = path.substr (slash+1, dash-(slash+1));
3097 path += new_legalized;
3098 path += ".wav"; /* XXX gag me with a spoon */
3102 /* non-destructive file sources have a name of the form:
3104 /path/to/NAME-nnnnn(%[LR])?.ext
3106 the task here is to replace NAME with the new name.
3111 string::size_type slash;
3112 string::size_type dash;
3113 string::size_type postfix;
3115 /* find last slash */
3117 if ((slash = path.find_last_of ('/')) == string::npos) {
3121 dir = path.substr (0, slash+1);
3123 /* '-' is not a legal character for the NAME part of the path */
3125 if ((dash = path.find_last_of ('-')) == string::npos) {
3129 suffix = path.substr (dash+1);
3131 // Suffix is now everything after the dash. Now we need to eliminate
3132 // the nnnnn part, which is done by either finding a '%' or a '.'
3134 postfix = suffix.find_last_of ("%");
3135 if (postfix == string::npos) {
3136 postfix = suffix.find_last_of ('.');
3139 if (postfix != string::npos) {
3140 suffix = suffix.substr (postfix);
3142 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3146 const uint32_t limit = 10000;
3147 char buf[PATH_MAX+1];
3149 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3151 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3153 if (access (buf, F_OK) != 0) {
3161 error << "FATAL ERROR! Could not find a " << endl;
3169 /** Return the full path (in some session directory) for a new within-session source.
3170 * \a name must be a session-unique name that does not contain slashes
3171 * (e.g. as returned by new_*_source_name)
3174 Session::new_source_path_from_name (DataType type, const string& name)
3176 assert(name.find("/") == string::npos);
3178 SessionDirectory sdir(get_best_session_directory_for_new_source());
3181 if (type == DataType::AUDIO) {
3182 p = sdir.sound_path();
3183 } else if (type == DataType::MIDI) {
3184 p = sdir.midi_path();
3186 error << "Unknown source type, unable to create file path" << endmsg;
3191 return p.to_string();
3195 Session::peak_path (Glib::ustring base) const
3197 sys::path peakfile_path(_session_dir->peak_path());
3198 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3199 return peakfile_path.to_string();
3202 /** Return a unique name based on \a base for a new internal audio source */
3204 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3208 char buf[PATH_MAX+1];
3209 const uint32_t limit = 10000;
3213 legalized = legalize_for_path (base);
3215 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3216 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3218 vector<space_and_path>::iterator i;
3219 uint32_t existing = 0;
3221 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3223 SessionDirectory sdir((*i).path);
3225 spath = sdir.sound_path().to_string();
3230 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3231 spath.c_str(), cnt, legalized.c_str());
3232 } else if (nchan == 2) {
3234 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3235 spath.c_str(), cnt, legalized.c_str());
3237 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3238 spath.c_str(), cnt, legalized.c_str());
3240 } else if (nchan < 26) {
3241 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3242 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3244 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3245 spath.c_str(), cnt, legalized.c_str());
3254 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3255 } else if (nchan == 2) {
3257 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3259 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3261 } else if (nchan < 26) {
3262 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3264 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3268 if (sys::exists(buf)) {
3274 if (existing == 0) {
3279 error << string_compose(
3280 _("There are already %1 recordings for %2, which I consider too many."),
3281 limit, base) << endmsg;
3283 throw failed_constructor();
3287 return Glib::path_get_basename(buf);
3290 /** Create a new within-session audio source */
3291 boost::shared_ptr<AudioFileSource>
3292 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3294 const size_t n_chans = ds.n_channels().n_audio();
3295 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3296 const string path = new_source_path_from_name(DataType::AUDIO, name);
3298 return boost::dynamic_pointer_cast<AudioFileSource> (
3299 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3302 /** Return a unique name based on \a base for a new internal MIDI source */
3304 Session::new_midi_source_name (const string& base)
3307 char buf[PATH_MAX+1];
3308 const uint32_t limit = 10000;
3312 legalized = legalize_for_path (base);
3314 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3315 for (cnt = 1; cnt <= limit; ++cnt) {
3317 vector<space_and_path>::iterator i;
3318 uint32_t existing = 0;
3320 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3322 SessionDirectory sdir((*i).path);
3324 sys::path p = sdir.midi_path();
3327 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3329 if (sys::exists (buf)) {
3334 if (existing == 0) {
3339 error << string_compose(
3340 _("There are already %1 recordings for %2, which I consider too many."),
3341 limit, base) << endmsg;
3343 throw failed_constructor();
3347 return Glib::path_get_basename(buf);
3351 /** Create a new within-session MIDI source */
3352 boost::shared_ptr<MidiSource>
3353 Session::create_midi_source_for_session (MidiDiskstream& ds)
3355 const string name = new_midi_source_name (ds.name());
3356 const string path = new_source_path_from_name (DataType::MIDI, name);
3358 return boost::dynamic_pointer_cast<SMFSource> (
3359 SourceFactory::createWritable (
3360 DataType::MIDI, *this, path, false, frame_rate()));
3365 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3367 if (playlist->hidden()) {
3371 playlists->add (playlist);
3374 playlist->release();
3381 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3383 if (_state_of_the_state & Deletion) {
3387 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3393 playlists->remove (playlist);
3399 Session::set_audition (boost::shared_ptr<Region> r)
3401 pending_audition_region = r;
3402 add_post_transport_work (PostTransportAudition);
3403 _butler->schedule_transport_work ();
3407 Session::audition_playlist ()
3409 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3410 ev->region.reset ();
3415 Session::non_realtime_set_audition ()
3417 if (!pending_audition_region) {
3418 auditioner->audition_current_playlist ();
3420 auditioner->audition_region (pending_audition_region);
3421 pending_audition_region.reset ();
3423 AuditionActive (true); /* EMIT SIGNAL */
3427 Session::audition_region (boost::shared_ptr<Region> r)
3429 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3435 Session::cancel_audition ()
3437 if (auditioner->active()) {
3438 auditioner->cancel_audition ();
3439 AuditionActive (false); /* EMIT SIGNAL */
3444 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3446 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3450 Session::remove_empty_sounds ()
3452 vector<string> audio_filenames;
3454 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3456 Glib::Mutex::Lock lm (source_lock);
3458 TapeFileMatcher tape_file_matcher;
3460 remove_if (audio_filenames.begin(), audio_filenames.end(),
3461 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3463 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3465 sys::path audio_file_path (_session_dir->sound_path());
3467 audio_file_path /= *i;
3469 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3473 sys::remove (audio_file_path);
3474 const string peakfile = peak_path (audio_file_path.to_string());
3475 sys::remove (peakfile);
3477 catch (const sys::filesystem_error& err)
3479 error << err.what() << endmsg;
3486 Session::is_auditioning () const
3488 /* can be called before we have an auditioner object */
3490 return auditioner->active();
3497 Session::n_diskstreams () const
3501 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3503 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3504 if (!(*i)->hidden()) {
3512 Session::graph_reordered ()
3514 /* don't do this stuff if we are setting up connections
3515 from a set_state() call or creating new tracks. Ditto for deletion.
3518 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3522 /* every track/bus asked for this to be handled but it was deferred because
3523 we were connecting. do it now.
3526 request_input_change_handling ();
3530 /* force all diskstreams to update their capture offset values to
3531 reflect any changes in latencies within the graph.
3534 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3536 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3537 (*i)->set_capture_offset ();
3542 Session::add_processor (Processor* processor)
3544 /* Session does not own Processors (they belong to a Route) but we do want to track
3545 the arrival and departure of port inserts, sends and returns for naming
3548 processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
3553 Session::remove_processor (Processor* processor)
3557 PortInsert* port_insert;
3559 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3560 insert_bitset[port_insert->bit_slot()] = false;
3561 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3562 send_bitset[send->bit_slot()] = false;
3563 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3564 return_bitset[retrn->bit_slot()] = false;
3571 Session::available_capture_duration ()
3573 float sample_bytes_on_disk = 4.0; // keep gcc happy
3575 switch (config.get_native_file_data_format()) {
3577 sample_bytes_on_disk = 4.0;
3581 sample_bytes_on_disk = 3.0;
3585 sample_bytes_on_disk = 2.0;
3589 /* impossible, but keep some gcc versions happy */
3590 fatal << string_compose (_("programming error: %1"),
3591 X_("illegal native file data format"))
3596 double scale = 4096.0 / sample_bytes_on_disk;
3598 if (_total_free_4k_blocks * scale > (double) max_frames) {
3602 return (nframes_t) floor (_total_free_4k_blocks * scale);
3606 Session::add_bundle (shared_ptr<Bundle> bundle)
3609 RCUWriter<BundleList> writer (_bundles);
3610 boost::shared_ptr<BundleList> b = writer.get_copy ();
3611 b->push_back (bundle);
3614 BundleAdded (bundle); /* EMIT SIGNAL */
3620 Session::remove_bundle (shared_ptr<Bundle> bundle)
3622 bool removed = false;
3625 RCUWriter<BundleList> writer (_bundles);
3626 boost::shared_ptr<BundleList> b = writer.get_copy ();
3627 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3629 if (i != b->end()) {
3636 BundleRemoved (bundle); /* EMIT SIGNAL */
3643 Session::bundle_by_name (string name) const
3645 boost::shared_ptr<BundleList> b = _bundles.reader ();
3647 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3648 if ((*i)->name() == name) {
3653 return boost::shared_ptr<Bundle> ();
3657 Session::tempo_map_changed (Change)
3661 playlists->update_after_tempo_map_change ();
3666 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3667 * the given count with the current block size.
3670 Session::ensure_buffers (ChanCount howmany)
3672 if (current_block_size == 0) {
3673 return; // too early? (is this ok?)
3676 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3677 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3678 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3679 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3680 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3683 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3687 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3689 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3690 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3695 Session::next_insert_id ()
3697 /* this doesn't really loop forever. just think about it */
3700 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3701 if (!insert_bitset[n]) {
3702 insert_bitset[n] = true;
3708 /* none available, so resize and try again */
3710 insert_bitset.resize (insert_bitset.size() + 16, false);
3715 Session::next_send_id ()
3717 /* this doesn't really loop forever. just think about it */
3720 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3721 if (!send_bitset[n]) {
3722 send_bitset[n] = true;
3728 /* none available, so resize and try again */
3730 send_bitset.resize (send_bitset.size() + 16, false);
3735 Session::next_return_id ()
3737 /* this doesn't really loop forever. just think about it */
3740 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3741 if (!return_bitset[n]) {
3742 return_bitset[n] = true;
3748 /* none available, so resize and try again */
3750 return_bitset.resize (return_bitset.size() + 16, false);
3755 Session::mark_send_id (uint32_t id)
3757 if (id >= send_bitset.size()) {
3758 send_bitset.resize (id+16, false);
3760 if (send_bitset[id]) {
3761 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3763 send_bitset[id] = true;
3767 Session::mark_return_id (uint32_t id)
3769 if (id >= return_bitset.size()) {
3770 return_bitset.resize (id+16, false);
3772 if (return_bitset[id]) {
3773 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3775 return_bitset[id] = true;
3779 Session::mark_insert_id (uint32_t id)
3781 if (id >= insert_bitset.size()) {
3782 insert_bitset.resize (id+16, false);
3784 if (insert_bitset[id]) {
3785 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3787 insert_bitset[id] = true;
3790 /* Named Selection management */
3792 boost::shared_ptr<NamedSelection>
3793 Session::named_selection_by_name (string name)
3795 Glib::Mutex::Lock lm (named_selection_lock);
3796 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3797 if ((*i)->name == name) {
3801 return boost::shared_ptr<NamedSelection>();
3805 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3808 Glib::Mutex::Lock lm (named_selection_lock);
3809 named_selections.insert (named_selections.begin(), named_selection);
3814 NamedSelectionAdded (); /* EMIT SIGNAL */
3818 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3820 bool removed = false;
3823 Glib::Mutex::Lock lm (named_selection_lock);
3825 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3827 if (i != named_selections.end()) {
3828 named_selections.erase (i);
3835 NamedSelectionRemoved (); /* EMIT SIGNAL */
3840 Session::reset_native_file_format ()
3842 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3844 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3845 (*i)->reset_write_sources (false);
3850 Session::route_name_unique (string n) const
3852 shared_ptr<RouteList> r = routes.reader ();
3854 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3855 if ((*i)->name() == n) {
3864 Session::route_name_internal (string n) const
3866 if (auditioner && auditioner->name() == n) {
3870 if (_click_io && _click_io->name() == n) {
3878 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3880 if (!force && howmany <= _npan_buffers) {
3884 if (_pan_automation_buffer) {
3886 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3887 delete [] _pan_automation_buffer[i];
3890 delete [] _pan_automation_buffer;
3893 _pan_automation_buffer = new pan_t*[howmany];
3895 for (uint32_t i = 0; i < howmany; ++i) {
3896 _pan_automation_buffer[i] = new pan_t[nframes];
3899 _npan_buffers = howmany;
3903 Session::freeze (InterThreadInfo& itt)
3905 shared_ptr<RouteList> r = routes.reader ();
3907 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3909 boost::shared_ptr<Track> t;
3911 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3912 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3922 boost::shared_ptr<Region>
3923 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3924 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3925 InterThreadInfo& itt, bool enable_processing)
3927 boost::shared_ptr<Region> result;
3928 boost::shared_ptr<Playlist> playlist;
3929 boost::shared_ptr<AudioFileSource> fsource;
3931 char buf[PATH_MAX+1];
3932 ChanCount nchans(track.audio_diskstream()->n_channels());
3934 nframes_t this_chunk;
3937 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3938 const string sound_dir = sdir.sound_path().to_string();
3939 nframes_t len = end - start;
3942 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3943 end, start) << endmsg;
3947 const nframes_t chunk_size = (256 * 1024)/4;
3949 // block all process callback handling
3951 block_processing ();
3953 /* call tree *MUST* hold route_lock */
3955 if ((playlist = track.diskstream()->playlist()) == 0) {
3959 /* external redirects will be a problem */
3961 if (track.has_external_redirects()) {
3965 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3967 for (x = 0; x < 99999; ++x) {
3968 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3969 if (access (buf, F_OK) != 0) {
3975 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3980 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3981 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3984 catch (failed_constructor& err) {
3985 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3989 srcs.push_back (fsource);
3992 /* XXX need to flush all redirects */
3997 /* create a set of reasonably-sized buffers */
3998 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3999 buffers.set_count(nchans);
4001 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4002 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4004 afs->prepare_for_peakfile_writes ();
4007 while (to_do && !itt.cancel) {
4009 this_chunk = min (to_do, chunk_size);
4011 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4016 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4017 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4020 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4026 start += this_chunk;
4027 to_do -= this_chunk;
4029 itt.progress = (float) (1.0 - ((double) to_do / len));
4038 xnow = localtime (&now);
4040 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4041 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4044 afs->update_header (position, *xnow, now);
4045 afs->flush_header ();
4049 /* construct a region to represent the bounced material */
4051 result = RegionFactory::create (srcs, 0,
4052 srcs.front()->length(srcs.front()->timeline_position()),
4053 region_name_from_path (srcs.front()->name(), true));
4058 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4059 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4062 afs->mark_for_remove ();
4065 (*src)->drop_references ();
4069 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4070 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4073 afs->done_with_peakfile_writes ();
4077 unblock_processing ();
4083 Session::get_silent_buffers (ChanCount count)
4085 assert(_silent_buffers->available() >= count);
4086 _silent_buffers->set_count(count);
4088 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4089 for (size_t i= 0; i < count.get(*t); ++i) {
4090 _silent_buffers->get(*t, i).clear();
4094 return *_silent_buffers;
4098 Session::get_scratch_buffers (ChanCount count)
4100 if (count != ChanCount::ZERO) {
4101 assert(_scratch_buffers->available() >= count);
4102 _scratch_buffers->set_count(count);
4104 _scratch_buffers->set_count (_scratch_buffers->available());
4107 return *_scratch_buffers;
4111 Session::get_mix_buffers (ChanCount count)
4113 assert(_mix_buffers->available() >= count);
4114 _mix_buffers->set_count(count);
4115 return *_mix_buffers;
4119 Session::ntracks () const
4122 shared_ptr<RouteList> r = routes.reader ();
4124 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4125 if (boost::dynamic_pointer_cast<Track> (*i)) {
4134 Session::nbusses () const
4137 shared_ptr<RouteList> r = routes.reader ();
4139 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4140 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4149 Session::add_automation_list(AutomationList *al)
4151 automation_lists[al->id()] = al;
4155 Session::compute_initial_length ()
4157 return _engine.frame_rate() * 60 * 5;
4161 Session::sync_order_keys (std::string const & base)
4163 if (deletion_in_progress()) {
4167 if (!Config->get_sync_all_route_ordering()) {
4168 /* leave order keys as they are */
4172 boost::shared_ptr<RouteList> r = routes.reader ();
4174 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4175 (*i)->sync_order_keys (base);
4178 Route::SyncOrderKeys (base); // EMIT SIGNAL
4182 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4184 Session::have_rec_enabled_diskstream () const
4186 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4189 /** Update the state of our rec-enabled diskstreams flag */
4191 Session::update_have_rec_enabled_diskstream ()
4193 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4194 DiskstreamList::iterator i = dsl->begin ();
4195 while (i != dsl->end () && (*i)->record_enabled () == false) {
4199 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4201 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4203 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4204 RecordStateChanged (); /* EMIT SIGNAL */
4209 Session::listen_position_changed ()
4213 switch (Config->get_listen_position()) {
4214 case AfterFaderListen:
4218 case PreFaderListen:
4223 boost::shared_ptr<RouteList> r = routes.reader ();
4225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4226 (*i)->put_control_outs_at (p);
4231 Session::solo_control_mode_changed ()
4233 /* cancel all solo or all listen when solo control mode changes */
4235 if (Config->get_solo_control_is_listen_control()) {
4236 set_solo (routes.reader(), false);
4238 set_listen (routes.reader(), false);
4243 Session::route_group_changed ()
4245 RouteGroupChanged (); /* EMIT SIGNAL */
4249 Session::get_available_sync_options () const
4251 vector<SyncSource> ret;
4253 ret.push_back (JACK);
4256 ret.push_back (MTC);
4259 if (midi_clock_port()) {
4260 ret.push_back (MIDIClock);
4266 boost::shared_ptr<RouteList>
4267 Session::get_routes_with_regions_at (nframes64_t const p) const
4269 shared_ptr<RouteList> r = routes.reader ();
4270 shared_ptr<RouteList> rl (new RouteList);
4272 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4273 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4278 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4283 boost::shared_ptr<Playlist> pl = ds->playlist ();
4288 if (pl->has_region_at (p)) {