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>
35 #include <glibmm/thread.h>
37 #include "pbd/error.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"
44 #include "pbd/convert.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/butler.h"
60 #include "ardour/click.h"
61 #include "ardour/configuration.h"
62 #include "ardour/crossfade.h"
63 #include "ardour/cycle_timer.h"
64 #include "ardour/data_type.h"
65 #include "ardour/debug.h"
66 #include "ardour/filename_extensions.h"
67 #include "ardour/internal_send.h"
68 #include "ardour/io_processor.h"
69 #include "ardour/midi_diskstream.h"
70 #include "ardour/midi_playlist.h"
71 #include "ardour/midi_region.h"
72 #include "ardour/midi_track.h"
73 #include "ardour/midi_ui.h"
74 #include "ardour/named_selection.h"
75 #include "ardour/playlist.h"
76 #include "ardour/plugin_insert.h"
77 #include "ardour/port_insert.h"
78 #include "ardour/processor.h"
79 #include "ardour/rc_configuration.h"
80 #include "ardour/recent_sessions.h"
81 #include "ardour/region_factory.h"
82 #include "ardour/return.h"
83 #include "ardour/route_group.h"
84 #include "ardour/send.h"
85 #include "ardour/session.h"
86 #include "ardour/session_directory.h"
87 #include "ardour/session_directory.h"
88 #include "ardour/session_metadata.h"
89 #include "ardour/session_playlists.h"
90 #include "ardour/slave.h"
91 #include "ardour/smf_source.h"
92 #include "ardour/source_factory.h"
93 #include "ardour/tape_file_matcher.h"
94 #include "ardour/tempo.h"
95 #include "ardour/utils.h"
97 #include "midi++/jack.h"
102 using namespace ARDOUR;
104 using boost::shared_ptr;
105 using boost::weak_ptr;
107 bool Session::_disable_all_loaded_plugins = false;
109 PBD::Signal1<void,std::string> Session::Dialog;
110 PBD::Signal0<int> Session::AskAboutPendingState;
111 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
112 PBD::Signal0<void> Session::SendFeedback;
114 PBD::Signal0<void> Session::TimecodeOffsetChanged;
115 PBD::Signal0<void> Session::StartTimeChanged;
116 PBD::Signal0<void> Session::EndTimeChanged;
117 PBD::Signal0<void> Session::AutoBindingOn;
118 PBD::Signal0<void> Session::AutoBindingOff;
119 PBD::Signal2<void,std::string, std::string> Session::Exported;
120 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
122 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
123 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
125 Session::Session (AudioEngine &eng,
126 const string& fullpath,
127 const string& snapshot_name,
131 _target_transport_speed (0.0),
132 _requested_return_frame (-1),
133 _scratch_buffers(new BufferSet()),
134 _silent_buffers(new BufferSet()),
135 _mix_buffers(new BufferSet()),
137 _mmc_port (default_mmc_port),
138 _mtc_port (default_mtc_port),
139 _midi_port (default_midi_port),
140 _midi_clock_port (default_midi_clock_port),
141 _session_dir (new SessionDirectory(fullpath)),
143 _butler (new Butler (*this)),
144 _post_transport_work (0),
145 _send_timecode_update (false),
146 diskstreams (new DiskstreamList),
147 routes (new RouteList),
148 _total_free_4k_blocks (0),
149 _bundles (new BundleList),
150 _bundle_xml_node (0),
153 click_emphasis_data (0),
155 _metadata (new SessionMetadata()),
156 _have_rec_enabled_diskstream (false)
159 playlists.reset (new SessionPlaylists);
163 interpolation.add_channel_to (0, 0);
165 if (!eng.connected()) {
166 throw failed_constructor();
169 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
171 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
172 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
174 first_stage_init (fullpath, snapshot_name);
176 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
179 if (create (new_session, mix_template, compute_initial_length())) {
181 throw failed_constructor ();
185 if (second_stage_init (new_session)) {
187 throw failed_constructor ();
190 store_recent_sessions(_name, _path);
192 bool was_dirty = dirty();
194 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
196 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
197 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
200 DirtyChanged (); /* EMIT SIGNAL */
204 Session::Session (AudioEngine &eng,
206 string snapshot_name,
207 AutoConnectOption input_ac,
208 AutoConnectOption output_ac,
209 uint32_t control_out_channels,
210 uint32_t master_out_channels,
211 uint32_t requested_physical_in,
212 uint32_t requested_physical_out,
213 nframes_t initial_length)
216 _target_transport_speed (0.0),
217 _requested_return_frame (-1),
218 _scratch_buffers(new BufferSet()),
219 _silent_buffers(new BufferSet()),
220 _mix_buffers(new BufferSet()),
222 _mmc_port (default_mmc_port),
223 _mtc_port (default_mtc_port),
224 _midi_port (default_midi_port),
225 _midi_clock_port (default_midi_clock_port),
226 _session_dir ( new SessionDirectory(fullpath)),
228 _butler (new Butler (*this)),
229 _post_transport_work (0),
230 _send_timecode_update (false),
231 diskstreams (new DiskstreamList),
232 routes (new RouteList),
233 _total_free_4k_blocks (0),
234 _bundles (new BundleList),
235 _bundle_xml_node (0),
236 _click_io ((IO *) 0),
238 click_emphasis_data (0),
240 _metadata (new SessionMetadata()),
241 _have_rec_enabled_diskstream (false)
243 playlists.reset (new SessionPlaylists);
247 interpolation.add_channel_to (0, 0);
249 if (!eng.connected()) {
250 throw failed_constructor();
253 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
255 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
256 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
258 if (n_physical_inputs) {
259 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
262 if (n_physical_outputs) {
263 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
266 first_stage_init (fullpath, snapshot_name);
268 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
271 if (create (new_session, string(), initial_length)) {
273 throw failed_constructor ();
278 /* set up Master Out and Control Out if necessary */
283 if (master_out_channels) {
284 ChanCount count(DataType::AUDIO, master_out_channels);
285 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
286 boost_debug_shared_ptr_mark_interesting (rt, "Route");
287 boost::shared_ptr<Route> r (rt);
288 r->input()->ensure_io (count, false, this);
289 r->output()->ensure_io (count, false, this);
290 r->set_remote_control_id (control_id);
294 /* prohibit auto-connect to master, because there isn't one */
295 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
298 if (control_out_channels) {
299 ChanCount count(DataType::AUDIO, control_out_channels);
300 Route* rt = new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO);
301 boost_debug_shared_ptr_mark_interesting (rt, "Route");
302 shared_ptr<Route> r (rt);
303 r->input()->ensure_io (count, false, this);
304 r->output()->ensure_io (count, false, this);
305 r->set_remote_control_id (control_id++);
311 add_routes (rl, false);
316 if (no_auto_connect()) {
317 input_ac = AutoConnectOption (0);
318 output_ac = AutoConnectOption (0);
321 Config->set_input_auto_connect (input_ac);
322 Config->set_output_auto_connect (output_ac);
324 if (second_stage_init (new_session)) {
326 throw failed_constructor ();
329 store_recent_sessions (_name, _path);
331 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
333 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
344 vector<void*> debug_pointers;
346 /* if we got to here, leaving pending capture state around
350 remove_pending_capture_state ();
352 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
354 _engine.remove_session ();
356 /* clear history so that no references to objects are held any more */
360 /* clear state tree so that no references to objects are held any more */
364 /* reset dynamic state version back to default */
366 Stateful::loading_state_version = 0;
369 delete midi_control_ui;
371 if (click_data != default_click) {
372 delete [] click_data;
375 if (click_emphasis_data != default_click_emphasis) {
376 delete [] click_emphasis_data;
381 delete _scratch_buffers;
382 delete _silent_buffers;
385 /* clear out any pending dead wood from RCU managed objects */
388 diskstreams.flush ();
391 AudioDiskstream::free_working_buffers();
393 /* tell everyone who is still standing that we're about to die */
396 /* tell everyone to drop references and delete objects as we go */
398 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
399 named_selections.clear ();
401 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
402 RegionFactory::delete_all_regions ();
404 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
406 /* reset these three references to special routes before we do the usual route delete thing */
409 _master_out.reset ();
410 _control_out.reset ();
413 RCUWriter<RouteList> writer (routes);
414 boost::shared_ptr<RouteList> r = writer.get_copy ();
416 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
417 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
418 (*i)->drop_references ();
422 /* writer goes out of scope and updates master */
426 boost::shared_ptr<RouteList> r = routes.reader ();
428 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
430 RCUWriter<DiskstreamList> dwriter (diskstreams);
431 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
432 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
433 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
434 (*i)->drop_references ();
439 diskstreams.flush ();
441 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
442 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
443 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
444 i->second->drop_references ();
449 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
450 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
455 Crossfade::set_buffer_size (0);
459 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
462 boost_debug_list_ptrs ();
464 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
468 Session::set_worst_io_latencies ()
470 _worst_output_latency = 0;
471 _worst_input_latency = 0;
473 if (!_engine.connected()) {
477 boost::shared_ptr<RouteList> r = routes.reader ();
479 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
480 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
481 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
486 Session::when_engine_running (bool new_session)
488 string first_physical_output;
490 BootMessage (_("Set block size and sample rate"));
492 set_block_size (_engine.frames_per_cycle());
493 set_frame_rate (_engine.frame_rate());
495 BootMessage (_("Using configuration"));
497 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
498 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
500 Config->map_parameters (ff);
501 config.map_parameters (ft);
503 /* every time we reconnect, recompute worst case output latencies */
505 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
507 if (synced_to_jack()) {
508 _engine.transport_stop ();
511 if (config.get_jack_time_master()) {
512 _engine.transport_locate (_transport_frame);
520 _click_io.reset (new ClickIO (*this, "click"));
522 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
524 /* existing state for Click */
527 if (Stateful::loading_state_version < 3000) {
528 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
530 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
535 _clicking = Config->get_clicking ();
539 error << _("could not setup Click I/O") << endmsg;
546 /* default state for Click: dual-mono to first 2 physical outputs */
548 for (int physport = 0; physport < 2; ++physport) {
549 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
551 if (physical_output.length()) {
552 if (_click_io->add_port (physical_output, this)) {
553 // relax, even though its an error
558 if (_click_io->n_ports () > ChanCount::ZERO) {
559 _clicking = Config->get_clicking ();
564 catch (failed_constructor& err) {
565 error << _("cannot setup Click I/O") << endmsg;
568 BootMessage (_("Compute I/O Latencies"));
570 set_worst_io_latencies ();
573 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
576 BootMessage (_("Set up standard connections"));
578 /* Create a set of Bundle objects that map
579 to the physical I/O currently available. We create both
580 mono and stereo bundles, so that the common cases of mono
581 and stereo tracks get bundles to put in their mixer strip
582 in / out menus. There may be a nicer way of achieving that;
583 it doesn't really scale that well to higher channel counts
586 /* mono output bundles */
588 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
590 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
592 shared_ptr<Bundle> c (new Bundle (buf, true));
593 c->add_channel (_("mono"));
594 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
599 /* stereo output bundles */
601 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
602 if (np + 1 < n_physical_outputs) {
604 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
605 shared_ptr<Bundle> c (new Bundle (buf, true));
606 c->add_channel (_("L"));
607 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
608 c->add_channel (_("R"));
609 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
615 /* mono input bundles */
617 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
619 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
621 shared_ptr<Bundle> c (new Bundle (buf, false));
622 c->add_channel (_("mono"));
623 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
628 /* stereo input bundles */
630 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
631 if (np + 1 < n_physical_inputs) {
633 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
635 shared_ptr<Bundle> c (new Bundle (buf, false));
636 c->add_channel (_("L"));
637 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
638 c->add_channel (_("R"));
639 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
645 BootMessage (_("Setup signal flow and plugins"));
647 hookup_io (new_session);
649 if (new_session && !no_auto_connect()) {
651 if (_master_out && Config->get_auto_connect_standard_busses()) {
653 /* if requested auto-connect the outputs to the first N physical ports.
656 uint32_t limit = _master_out->n_outputs().n_total();
658 for (uint32_t n = 0; n < limit; ++n) {
659 Port* p = _master_out->output()->nth (n);
660 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
662 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
663 if (_master_out->output()->connect (p, connect_to, this)) {
664 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
674 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
675 are undefined, at best.
678 /* control out listens to master bus (but ignores it
679 under some conditions)
682 uint32_t limit = _control_out->n_inputs().n_audio();
685 for (uint32_t n = 0; n < limit; ++n) {
686 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
687 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
690 string connect_to = o->name();
691 if (_control_out->input()->connect (p, connect_to, this)) {
692 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
700 /* if control out is not connected,
701 connect control out to physical outs, but use ones after the master if possible
704 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
706 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
708 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
711 _control_out->output()->connect_ports_to_bundle (b, this);
713 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
714 Config->get_monitor_bus_preferred_bundle())
720 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
721 uint32_t shift = _master_out->n_outputs().get(*t);
722 uint32_t mod = _engine.n_physical_outputs (*t);
723 uint32_t limit = _control_out->n_outputs().get(*t);
725 cerr << "Connecting " << limit << " control out ports, shift is " << shift
726 << " mod is " << mod << endl;
728 for (uint32_t n = 0; n < limit; ++n) {
730 Port* p = _control_out->output()->ports().port(*t, n);
731 string connect_to = _engine.get_nth_physical_output (*t, (n+shift) % mod);
733 if (!connect_to.empty()) {
734 if (_control_out->output()->connect (p, connect_to, this)) {
735 error << string_compose (
736 _("cannot connect control output %1 to %2"),
749 /* catch up on send+insert cnts */
751 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
753 /* hook us up to the engine */
755 BootMessage (_("Connect to engine"));
757 _engine.set_session (this);
761 Session::hookup_io (bool new_session)
763 /* stop graph reordering notifications from
764 causing resorts, etc.
767 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
772 /* we delay creating the auditioner till now because
773 it makes its own connections to ports.
777 auditioner.reset (new Auditioner (*this));
780 catch (failed_constructor& err) {
781 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
785 /* load bundles, which we may have postponed earlier on */
786 if (_bundle_xml_node) {
787 load_bundles (*_bundle_xml_node);
788 delete _bundle_xml_node;
791 /* Tell all IO objects to connect themselves together */
793 IO::enable_connecting ();
794 MIDI::JACK_MidiPort::MakeConnections ();
796 /* Now reset all panners */
798 Delivery::reset_panners ();
800 /* Connect tracks to monitor/listen bus if there is one.
801 Note that in an existing session, the internal sends will
802 already exist, but we want the routes to notice that
803 they connect to the control out specifically.
807 boost::shared_ptr<RouteList> r = routes.reader ();
808 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
810 if ((*x)->is_control()) {
814 } else if ((*x)->is_master()) {
820 cerr << "Connecting route " << (*x)->name() << " to control outs\n";
822 (*x)->listen_via (_control_out,
823 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
829 /* Anyone who cares about input state, wake up and do something */
831 IOConnectionsComplete (); /* EMIT SIGNAL */
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
835 /* now handle the whole enchilada as if it was one
841 /* update the full solo state, which can't be
842 correctly determined on a per-route basis, but
843 needs the global overview that only the session
847 update_route_solo_state ();
851 Session::playlist_length_changed ()
853 /* we can't just increase end_location->end() if pl->get_maximum_extent()
854 if larger. if the playlist used to be the longest playlist,
855 and its now shorter, we have to decrease end_location->end(). hence,
856 we have to iterate over all diskstreams and check the
857 playlists currently in use.
863 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
865 boost::shared_ptr<Diskstream> dstream = wp.lock ();
870 boost::shared_ptr<Playlist> playlist;
872 if ((playlist = dstream->playlist()) != 0) {
873 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
876 /* see comment in playlist_length_changed () */
881 Session::record_enabling_legal () const
883 /* this used to be in here, but survey says.... we don't need to restrict it */
884 // if (record_status() == Recording) {
888 if (Config->get_all_safe()) {
895 Session::reset_input_monitor_state ()
897 if (transport_rolling()) {
899 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
901 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
902 if ((*i)->record_enabled ()) {
903 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
904 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
908 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
910 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
911 if ((*i)->record_enabled ()) {
912 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
913 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
920 Session::auto_punch_start_changed (Location* location)
922 replace_event (SessionEvent::PunchIn, location->start());
924 if (get_record_enabled() && config.get_punch_in()) {
925 /* capture start has been changed, so save new pending state */
926 save_state ("", true);
931 Session::auto_punch_end_changed (Location* location)
933 nframes_t when_to_stop = location->end();
934 // when_to_stop += _worst_output_latency + _worst_input_latency;
935 replace_event (SessionEvent::PunchOut, when_to_stop);
939 Session::auto_punch_changed (Location* location)
941 nframes_t when_to_stop = location->end();
943 replace_event (SessionEvent::PunchIn, location->start());
944 //when_to_stop += _worst_output_latency + _worst_input_latency;
945 replace_event (SessionEvent::PunchOut, when_to_stop);
949 Session::auto_loop_changed (Location* location)
951 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
953 if (transport_rolling() && play_loop) {
956 // if (_transport_frame > location->end()) {
958 if (_transport_frame < location->start() || _transport_frame > location->end()) {
959 // relocate to beginning of loop
960 clear_events (SessionEvent::LocateRoll);
962 request_locate (location->start(), true);
965 else if (Config->get_seamless_loop() && !loop_changing) {
967 // schedule a locate-roll to refill the diskstreams at the
969 loop_changing = true;
971 if (location->end() > last_loopend) {
972 clear_events (SessionEvent::LocateRoll);
973 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
980 last_loopend = location->end();
984 Session::set_auto_punch_location (Location* location)
988 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
989 punch_connections.drop_connections();
990 existing->set_auto_punch (false, this);
991 remove_event (existing->start(), SessionEvent::PunchIn);
992 clear_events (SessionEvent::PunchOut);
993 auto_punch_location_changed (0);
1002 if (location->end() <= location->start()) {
1003 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1007 punch_connections.drop_connections ();
1009 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1010 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1011 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1013 location->set_auto_punch (true, this);
1015 auto_punch_changed (location);
1017 auto_punch_location_changed (location);
1021 Session::set_auto_loop_location (Location* location)
1025 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1026 loop_connections.drop_connections ();
1027 existing->set_auto_loop (false, this);
1028 remove_event (existing->end(), SessionEvent::AutoLoop);
1029 auto_loop_location_changed (0);
1034 if (location == 0) {
1038 if (location->end() <= location->start()) {
1039 error << _("Session: you can't use a mark for auto loop") << endmsg;
1043 last_loopend = location->end();
1045 loop_connections.drop_connections ();
1047 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1048 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1049 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1051 location->set_auto_loop (true, this);
1053 /* take care of our stuff first */
1055 auto_loop_changed (location);
1057 /* now tell everyone else */
1059 auto_loop_location_changed (location);
1063 Session::locations_added (Location *)
1069 Session::locations_changed ()
1071 _locations.apply (*this, &Session::handle_locations_changed);
1075 Session::handle_locations_changed (Locations::LocationList& locations)
1077 Locations::LocationList::iterator i;
1079 bool set_loop = false;
1080 bool set_punch = false;
1082 for (i = locations.begin(); i != locations.end(); ++i) {
1086 if (location->is_auto_punch()) {
1087 set_auto_punch_location (location);
1090 if (location->is_auto_loop()) {
1091 set_auto_loop_location (location);
1095 if (location->is_start()) {
1096 start_location = location;
1098 if (location->is_end()) {
1099 end_location = location;
1104 set_auto_loop_location (0);
1107 set_auto_punch_location (0);
1114 Session::enable_record ()
1116 /* XXX really atomic compare+swap here */
1117 if (g_atomic_int_get (&_record_status) != Recording) {
1118 g_atomic_int_set (&_record_status, Recording);
1119 _last_record_location = _transport_frame;
1120 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1122 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1123 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1124 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1125 if ((*i)->record_enabled ()) {
1126 (*i)->monitor_input (true);
1131 RecordStateChanged ();
1136 Session::disable_record (bool rt_context, bool force)
1140 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1142 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1143 g_atomic_int_set (&_record_status, Disabled);
1145 if (rs == Recording) {
1146 g_atomic_int_set (&_record_status, Enabled);
1150 // FIXME: timestamp correct? [DR]
1151 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1152 // does this /need/ to be sent in all cases?
1154 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1157 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1158 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1160 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1161 if ((*i)->record_enabled ()) {
1162 (*i)->monitor_input (false);
1167 RecordStateChanged (); /* emit signal */
1170 remove_pending_capture_state ();
1176 Session::step_back_from_record ()
1178 /* XXX really atomic compare+swap here */
1179 if (g_atomic_int_get (&_record_status) == Recording) {
1180 g_atomic_int_set (&_record_status, Enabled);
1182 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1185 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1186 if ((*i)->record_enabled ()) {
1187 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1188 (*i)->monitor_input (false);
1196 Session::maybe_enable_record ()
1198 g_atomic_int_set (&_record_status, Enabled);
1200 /* this function is currently called from somewhere other than an RT thread.
1201 this save_state() call therefore doesn't impact anything.
1204 save_state ("", true);
1206 if (_transport_speed) {
1207 if (!config.get_punch_in()) {
1211 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1212 RecordStateChanged (); /* EMIT SIGNAL */
1219 Session::audible_frame () const
1225 /* the first of these two possible settings for "offset"
1226 mean that the audible frame is stationary until
1227 audio emerges from the latency compensation
1230 the second means that the audible frame is stationary
1231 until audio would emerge from a physical port
1232 in the absence of any plugin latency compensation
1235 offset = _worst_output_latency;
1237 if (offset > current_block_size) {
1238 offset -= current_block_size;
1240 /* XXX is this correct? if we have no external
1241 physical connections and everything is internal
1242 then surely this is zero? still, how
1243 likely is that anyway?
1245 offset = current_block_size;
1248 if (synced_to_jack()) {
1249 tf = _engine.transport_frame();
1251 tf = _transport_frame;
1256 if (!non_realtime_work_pending()) {
1260 /* check to see if we have passed the first guaranteed
1261 audible frame past our last start position. if not,
1262 return that last start point because in terms
1263 of audible frames, we have not moved yet.
1266 if (_transport_speed > 0.0f) {
1268 if (!play_loop || !have_looped) {
1269 if (tf < _last_roll_location + offset) {
1270 return _last_roll_location;
1278 } else if (_transport_speed < 0.0f) {
1280 /* XXX wot? no backward looping? */
1282 if (tf > _last_roll_location - offset) {
1283 return _last_roll_location;
1295 Session::set_frame_rate (nframes_t frames_per_second)
1297 /** \fn void Session::set_frame_size(nframes_t)
1298 the AudioEngine object that calls this guarantees
1299 that it will not be called while we are also in
1300 ::process(). Its fine to do things that block
1304 _base_frame_rate = frames_per_second;
1308 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1312 // XXX we need some equivalent to this, somehow
1313 // SndFileSource::setup_standard_crossfades (frames_per_second);
1317 /* XXX need to reset/reinstantiate all LADSPA plugins */
1321 Session::set_block_size (nframes_t nframes)
1323 /* the AudioEngine guarantees
1324 that it will not be called while we are also in
1325 ::process(). It is therefore fine to do things that block
1330 current_block_size = nframes;
1332 ensure_buffers(_scratch_buffers->available());
1334 delete [] _gain_automation_buffer;
1335 _gain_automation_buffer = new gain_t[nframes];
1337 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1339 boost::shared_ptr<RouteList> r = routes.reader ();
1341 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1342 (*i)->set_block_size (nframes);
1345 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1346 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1347 (*i)->set_block_size (nframes);
1350 set_worst_io_latencies ();
1355 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1358 nframes_t fade_frames;
1360 /* Don't allow fade of less 1 frame */
1362 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1369 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1373 default_fade_msecs = fade_msecs;
1374 default_fade_steepness = steepness;
1377 // jlc, WTF is this!
1378 Glib::RWLock::ReaderLock lm (route_lock);
1379 AudioRegion::set_default_fade (steepness, fade_frames);
1384 /* XXX have to do this at some point */
1385 /* foreach region using default fade, reset, then
1386 refill_all_diskstream_buffers ();
1391 struct RouteSorter {
1392 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1393 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1395 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1398 if (r1->fed_by.empty()) {
1399 if (r2->fed_by.empty()) {
1400 /* no ardour-based connections inbound to either route. just use signal order */
1401 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1403 /* r2 has connections, r1 does not; run r1 early */
1407 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1414 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1416 shared_ptr<Route> r2;
1418 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1419 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1423 /* make a copy of the existing list of routes that feed r1 */
1425 set<weak_ptr<Route> > existing = r1->fed_by;
1427 /* for each route that feeds r1, recurse, marking it as feeding
1431 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1432 if (!(r2 = (*i).lock ())) {
1433 /* (*i) went away, ignore it */
1437 /* r2 is a route that feeds r1 which somehow feeds base. mark
1438 base as being fed by r2
1441 rbase->fed_by.insert (r2);
1445 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1449 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1453 /* now recurse, so that we can mark base as being fed by
1454 all routes that feed r2
1457 trace_terminal (r2, rbase);
1464 Session::resort_routes ()
1466 /* don't do anything here with signals emitted
1467 by Routes while we are being destroyed.
1470 if (_state_of_the_state & Deletion) {
1477 RCUWriter<RouteList> writer (routes);
1478 shared_ptr<RouteList> r = writer.get_copy ();
1479 resort_routes_using (r);
1480 /* writer goes out of scope and forces update */
1485 Session::resort_routes_using (shared_ptr<RouteList> r)
1487 RouteList::iterator i, j;
1489 for (i = r->begin(); i != r->end(); ++i) {
1491 (*i)->fed_by.clear ();
1493 for (j = r->begin(); j != r->end(); ++j) {
1495 /* although routes can feed themselves, it will
1496 cause an endless recursive descent if we
1497 detect it. so don't bother checking for
1505 if ((*j)->feeds (*i)) {
1506 (*i)->fed_by.insert (*j);
1511 for (i = r->begin(); i != r->end(); ++i) {
1512 trace_terminal (*i, *i);
1519 cerr << "finished route resort\n";
1521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1522 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1529 /** Find the route name starting with \a base with the lowest \a id.
1531 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1532 * The available route name with the lowest ID will be used, and \a id
1533 * will be set to the ID.
1535 * \return false if a route name could not be found, and \a track_name
1536 * and \a id do not reflect a free route name.
1539 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1542 snprintf (name, name_len, "%s %" PRIu32, base, id);
1544 if (route_by_name (name) == 0) {
1550 } while (id < (UINT_MAX-1));
1556 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1558 in = ChanCount::ZERO;
1559 out = ChanCount::ZERO;
1560 shared_ptr<RouteList> r = routes.reader ();
1561 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1562 if (!(*i)->is_hidden()) {
1563 in += (*i)->n_inputs();
1564 out += (*i)->n_outputs();
1569 list<boost::shared_ptr<MidiTrack> >
1570 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1572 char track_name[32];
1573 uint32_t track_id = 0;
1574 ChanCount existing_inputs;
1575 ChanCount existing_outputs;
1577 RouteList new_routes;
1578 list<boost::shared_ptr<MidiTrack> > ret;
1579 uint32_t control_id;
1581 count_existing_route_channels (existing_inputs, existing_outputs);
1583 control_id = ntracks() + nbusses();
1586 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1587 error << "cannot find name for new midi track" << endmsg;
1591 shared_ptr<MidiTrack> track;
1594 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1595 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1596 track = boost::shared_ptr<MidiTrack>(mt);
1598 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1599 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1604 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1605 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1609 auto_connect_route (track, existing_inputs, existing_outputs);
1611 track->midi_diskstream()->non_realtime_input_change();
1613 route_group->add (track);
1616 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1617 track->set_remote_control_id (control_id);
1619 new_routes.push_back (track);
1620 ret.push_back (track);
1623 catch (failed_constructor &err) {
1624 error << _("Session: could not create new midi track.") << endmsg;
1627 /* we need to get rid of this, since the track failed to be created */
1628 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1631 RCUWriter<DiskstreamList> writer (diskstreams);
1632 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1633 ds->remove (track->midi_diskstream());
1640 catch (AudioEngine::PortRegistrationFailure& pfe) {
1642 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;
1645 /* we need to get rid of this, since the track failed to be created */
1646 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1649 RCUWriter<DiskstreamList> writer (diskstreams);
1650 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1651 ds->remove (track->midi_diskstream());
1662 if (!new_routes.empty()) {
1663 add_routes (new_routes, false);
1664 save_state (_current_snapshot_name);
1671 Session::auto_connect_route (boost::shared_ptr<Route> route,
1672 ChanCount& existing_inputs, ChanCount& existing_outputs)
1674 /* If both inputs and outputs are auto-connected to physical ports,
1675 use the max of input and output offsets to ensure auto-connected
1676 port numbers always match up (e.g. the first audio input and the
1677 first audio output of the route will have the same physical
1678 port number). Otherwise just use the lowest input or output
1681 const bool in_out_physical =
1682 (Config->get_input_auto_connect() & AutoConnectPhysical)
1683 && (Config->get_output_auto_connect() & AutoConnectPhysical);
1685 const ChanCount in_offset = in_out_physical
1686 ? ChanCount::max(existing_inputs, existing_outputs)
1689 const ChanCount out_offset = in_out_physical
1690 ? ChanCount::max(existing_inputs, existing_outputs)
1693 static string empty_string;
1694 string& port = empty_string;
1696 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1697 vector<string> physinputs;
1698 vector<string> physoutputs;
1700 _engine.get_physical_outputs (*t, physoutputs);
1701 _engine.get_physical_inputs (*t, physinputs);
1703 if (!physinputs.empty()) {
1704 uint32_t nphysical_in = physinputs.size();
1705 for (uint32_t i = 0; i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1706 port = empty_string;
1708 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1709 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1712 if (!port.empty() && route->input()->connect (
1713 route->input()->ports().port(*t, i), port, this)) {
1719 if (!physoutputs.empty()) {
1720 uint32_t nphysical_out = physoutputs.size();
1721 for (uint32_t i = 0; i < route->n_outputs().get(*t); ++i) {
1722 port = empty_string;
1724 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1725 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1726 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1727 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1728 port = _master_out->input()->ports().port(*t,
1729 i % _master_out->input()->n_ports().get(*t))->name();
1733 if (!port.empty() && route->output()->connect (
1734 route->output()->ports().port(*t, i), port, this)) {
1741 existing_inputs += route->n_inputs();
1742 existing_outputs += route->n_outputs();
1745 list< boost::shared_ptr<AudioTrack> >
1746 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1748 char track_name[32];
1749 uint32_t track_id = 0;
1750 ChanCount existing_inputs;
1751 ChanCount existing_outputs;
1753 RouteList new_routes;
1754 list<boost::shared_ptr<AudioTrack> > ret;
1755 uint32_t control_id;
1757 count_existing_route_channels (existing_inputs, existing_outputs);
1759 control_id = ntracks() + nbusses() + 1;
1762 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1763 error << "cannot find name for new audio track" << endmsg;
1767 shared_ptr<AudioTrack> track;
1770 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1771 boost_debug_shared_ptr_mark_interesting (at, "Track");
1772 track = boost::shared_ptr<AudioTrack>(at);
1774 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1775 error << string_compose (
1776 _("cannot configure %1 in/%2 out configuration for new audio track"),
1777 input_channels, output_channels)
1782 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1783 error << string_compose (
1784 _("cannot configure %1 in/%2 out configuration for new audio track"),
1785 input_channels, output_channels)
1790 auto_connect_route (track, existing_inputs, existing_outputs);
1793 route_group->add (track);
1796 track->audio_diskstream()->non_realtime_input_change();
1798 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1799 track->set_remote_control_id (control_id);
1802 new_routes.push_back (track);
1803 ret.push_back (track);
1806 catch (failed_constructor &err) {
1807 error << _("Session: could not create new audio track.") << endmsg;
1810 /* we need to get rid of this, since the track failed to be created */
1811 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1814 RCUWriter<DiskstreamList> writer (diskstreams);
1815 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1816 ds->remove (track->audio_diskstream());
1823 catch (AudioEngine::PortRegistrationFailure& pfe) {
1825 error << pfe.what() << endmsg;
1828 /* we need to get rid of this, since the track failed to be created */
1829 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1832 RCUWriter<DiskstreamList> writer (diskstreams);
1833 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1834 ds->remove (track->audio_diskstream());
1845 if (!new_routes.empty()) {
1846 add_routes (new_routes, true);
1853 Session::set_remote_control_ids ()
1855 RemoteModel m = Config->get_remote_model();
1856 bool emit_signal = false;
1858 shared_ptr<RouteList> r = routes.reader ();
1860 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1861 if (MixerOrdered == m) {
1862 long order = (*i)->order_key(N_("signal"));
1863 (*i)->set_remote_control_id (order+1, false);
1865 } else if (EditorOrdered == m) {
1866 long order = (*i)->order_key(N_("editor"));
1867 (*i)->set_remote_control_id (order+1, false);
1869 } else if (UserOrdered == m) {
1870 //do nothing ... only changes to remote id's are initiated by user
1875 Route::RemoteControlIDChange();
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 = 0;
1885 ChanCount existing_inputs;
1886 ChanCount existing_outputs;
1889 uint32_t control_id;
1891 count_existing_route_channels (existing_inputs, existing_outputs);
1893 control_id = ntracks() + nbusses() + 1;
1896 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1897 error << "cannot find name for new audio bus" << endmsg;
1902 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1903 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1904 shared_ptr<Route> bus (rt);
1906 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1907 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1908 input_channels, output_channels)
1914 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1915 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1916 input_channels, output_channels)
1921 auto_connect_route (bus, existing_inputs, existing_outputs);
1924 route_group->add (bus);
1926 bus->set_remote_control_id (control_id);
1930 bus->add_internal_return ();
1933 ret.push_back (bus);
1937 catch (failed_constructor &err) {
1938 error << _("Session: could not create new audio route.") << endmsg;
1942 catch (AudioEngine::PortRegistrationFailure& pfe) {
1943 error << pfe.what() << endmsg;
1953 add_routes (ret, true);
1961 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1965 uint32_t control_id;
1967 uint32_t number = 0;
1969 if (!tree.read (template_path.c_str())) {
1973 XMLNode* node = tree.root();
1975 control_id = ntracks() + nbusses() + 1;
1979 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1981 std::string node_name = IO::name_from_state (*node_copy.children().front());
1983 /* generate a new name by adding a number to the end of the template name */
1984 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1985 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1989 IO::set_name_in_state (*node_copy.children().front(), name);
1991 Track::zero_diskstream_id_in_xml (node_copy);
1994 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1997 error << _("Session: cannot create track/bus from template description") << endmsg;
2001 if (boost::dynamic_pointer_cast<Track>(route)) {
2002 /* force input/output change signals so that the new diskstream
2003 picks up the configuration of the route. During session
2004 loading this normally happens in a different way.
2006 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2007 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2010 route->set_remote_control_id (control_id);
2013 ret.push_back (route);
2016 catch (failed_constructor &err) {
2017 error << _("Session: could not create new route from template") << endmsg;
2021 catch (AudioEngine::PortRegistrationFailure& pfe) {
2022 error << pfe.what() << endmsg;
2031 add_routes (ret, true);
2038 Session::add_routes (RouteList& new_routes, bool save)
2041 RCUWriter<RouteList> writer (routes);
2042 shared_ptr<RouteList> r = writer.get_copy ();
2043 r->insert (r->end(), new_routes.begin(), new_routes.end());
2046 /* if there is no control out and we're not in the middle of loading,
2047 resort the graph here. if there is a control out, we will resort
2048 toward the end of this method. if we are in the middle of loading,
2049 we will resort when done.
2052 if (!_control_out && IO::connecting_legal) {
2053 resort_routes_using (r);
2057 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2059 boost::weak_ptr<Route> wpr (*x);
2060 boost::shared_ptr<Route> r (*x);
2062 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2063 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
2064 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2065 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2066 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2067 r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2069 if (r->is_master()) {
2073 if (r->is_control()) {
2078 if (_control_out && IO::connecting_legal) {
2080 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2081 if ((*x)->is_control()) {
2083 } else if ((*x)->is_master()) {
2086 (*x)->listen_via (_control_out,
2087 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2098 save_state (_current_snapshot_name);
2101 RouteAdded (new_routes); /* EMIT SIGNAL */
2102 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2106 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2108 boost::shared_ptr<RouteList> r = routes.reader ();
2109 boost::shared_ptr<Send> s;
2113 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2114 if (boost::dynamic_pointer_cast<Track>(*i)) {
2115 if ((s = (*i)->internal_send_for (dest)) != 0) {
2116 s->amp()->gain_control()->set_value (0.0);
2123 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2125 boost::shared_ptr<RouteList> r = routes.reader ();
2126 boost::shared_ptr<Send> s;
2130 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2131 if (boost::dynamic_pointer_cast<Track>(*i)) {
2132 if ((s = (*i)->internal_send_for (dest)) != 0) {
2133 s->amp()->gain_control()->set_value (1.0);
2140 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2142 boost::shared_ptr<RouteList> r = routes.reader ();
2143 boost::shared_ptr<Send> s;
2147 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2148 if (boost::dynamic_pointer_cast<Track>(*i)) {
2149 if ((s = (*i)->internal_send_for (dest)) != 0) {
2150 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2157 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2159 boost::shared_ptr<RouteList> r = routes.reader ();
2160 boost::shared_ptr<RouteList> t (new RouteList);
2162 /* only send tracks */
2164 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2165 if (boost::dynamic_pointer_cast<Track>(*i)) {
2170 add_internal_sends (dest, p, t);
2174 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2176 if (dest->is_control() || dest->is_master()) {
2180 if (!dest->internal_return()) {
2181 dest->add_internal_return();
2184 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2186 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2190 (*i)->listen_via (dest, p, true, true);
2197 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2199 /* need to do this in case we're rolling at the time, to prevent false underruns */
2200 dstream->do_refill_with_alloc ();
2202 dstream->set_block_size (current_block_size);
2205 RCUWriter<DiskstreamList> writer (diskstreams);
2206 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2207 ds->push_back (dstream);
2208 /* writer goes out of scope, copies ds back to main */
2211 dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr<Diskstream> (dstream)));
2212 /* this will connect to future changes, and check the current length */
2213 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2215 dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this));
2217 dstream->prepare ();
2222 Session::remove_route (shared_ptr<Route> route)
2225 RCUWriter<RouteList> writer (routes);
2226 shared_ptr<RouteList> rs = writer.get_copy ();
2230 /* deleting the master out seems like a dumb
2231 idea, but its more of a UI policy issue
2235 if (route == _master_out) {
2236 _master_out = shared_ptr<Route> ();
2239 if (route == _control_out) {
2241 /* cancel control outs for all routes */
2243 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2244 (*r)->drop_listen (_control_out);
2247 _control_out.reset ();
2250 update_route_solo_state ();
2252 /* writer goes out of scope, forces route list update */
2255 boost::shared_ptr<Track> t;
2256 boost::shared_ptr<Diskstream> ds;
2258 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2259 ds = t->diskstream();
2265 RCUWriter<DiskstreamList> dsl (diskstreams);
2266 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2271 find_current_end ();
2273 // We need to disconnect the routes inputs and outputs
2275 route->input()->disconnect (0);
2276 route->output()->disconnect (0);
2278 /* if the route had internal sends sending to it, remove them */
2279 if (route->internal_return()) {
2281 boost::shared_ptr<RouteList> r = routes.reader ();
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2285 (*i)->remove_processor (s);
2290 update_latency_compensation (false, false);
2293 /* get rid of it from the dead wood collection in the route list manager */
2295 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2299 /* try to cause everyone to drop their references */
2301 route->drop_references ();
2303 sync_order_keys (N_("session"));
2305 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2307 /* save the new state of the world */
2309 if (save_state (_current_snapshot_name)) {
2310 save_history (_current_snapshot_name);
2315 Session::route_mute_changed (void* /*src*/)
2321 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2323 boost::shared_ptr<Route> route = wpr.lock();
2325 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2329 if (route->listening()) {
2331 } else if (_listen_cnt > 0) {
2337 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2339 if (solo_update_disabled) {
2344 boost::shared_ptr<Route> route = wpr.lock ();
2347 /* should not happen */
2348 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2352 shared_ptr<RouteList> r = routes.reader ();
2355 if (route->self_soloed()) {
2361 /* now mod the solo level of all other routes except master & control outs
2362 so that they will be silent if appropriate.
2365 solo_update_disabled = true;
2367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2368 bool via_sends_only;
2370 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_control() || (*i)->is_hidden()) {
2372 } else if ((*i)->feeds (route, &via_sends_only)) {
2373 if (!via_sends_only) {
2374 (*i)->mod_solo_by_others (delta);
2379 /* make sure master is never muted by solo */
2381 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2382 _master_out->mod_solo_by_others (1);
2385 /* ditto for control outs make sure master is never muted by solo */
2387 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2388 _control_out->mod_solo_by_others (1);
2391 solo_update_disabled = false;
2392 update_route_solo_state (r);
2393 SoloChanged (); /* EMIT SIGNAL */
2398 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2400 /* now figure out if anything that matters is soloed (or is "listening")*/
2402 bool something_soloed = false;
2403 uint32_t listeners = 0;
2406 r = routes.reader();
2409 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2410 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2411 something_soloed = true;
2415 if (!(*i)->is_hidden() && (*i)->listening()) {
2420 if (something_soloed != _non_soloed_outs_muted) {
2421 _non_soloed_outs_muted = something_soloed;
2422 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2426 _listen_cnt = listeners;
2430 boost::shared_ptr<RouteList>
2431 Session::get_routes_with_internal_returns() const
2433 shared_ptr<RouteList> r = routes.reader ();
2434 boost::shared_ptr<RouteList> rl (new RouteList);
2436 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2437 if ((*i)->internal_return ()) {
2445 Session::route_by_name (string name)
2447 shared_ptr<RouteList> r = routes.reader ();
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 if ((*i)->name() == name) {
2455 return shared_ptr<Route> ((Route*) 0);
2459 Session::route_by_id (PBD::ID id)
2461 shared_ptr<RouteList> r = routes.reader ();
2463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2464 if ((*i)->id() == id) {
2469 return shared_ptr<Route> ((Route*) 0);
2473 Session::route_by_remote_id (uint32_t id)
2475 shared_ptr<RouteList> r = routes.reader ();
2477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2478 if ((*i)->remote_control_id() == id) {
2483 return shared_ptr<Route> ((Route*) 0);
2487 Session::find_current_end ()
2489 if (_state_of_the_state & Loading) {
2493 nframes_t max = get_maximum_extent ();
2495 if (max > end_location->end()) {
2496 end_location->set_end (max);
2498 DurationChanged(); /* EMIT SIGNAL */
2503 Session::get_maximum_extent () const
2508 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2510 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2511 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2513 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2514 if ((me = pl->get_maximum_extent()) > max) {
2522 boost::shared_ptr<Diskstream>
2523 Session::diskstream_by_name (string name)
2525 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2527 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2528 if ((*i)->name() == name) {
2533 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2536 boost::shared_ptr<Diskstream>
2537 Session::diskstream_by_id (const PBD::ID& id)
2539 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2541 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2542 if ((*i)->id() == id) {
2547 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2550 /* Region management */
2553 Session::new_region_name (string old)
2555 string::size_type last_period;
2557 string::size_type len = old.length() + 64;
2560 if ((last_period = old.find_last_of ('.')) == string::npos) {
2562 /* no period present - add one explicitly */
2565 last_period = old.length() - 1;
2570 number = atoi (old.substr (last_period+1).c_str());
2574 while (number < (UINT_MAX-1)) {
2576 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2577 RegionFactory::RegionMap::const_iterator i;
2582 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2585 for (i = regions.begin(); i != regions.end(); ++i) {
2586 if (i->second->name() == sbuf) {
2591 if (i == regions.end()) {
2596 if (number != (UINT_MAX-1)) {
2600 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2605 Session::region_name (string& result, string base, bool newlevel)
2610 if (base.find("/") != string::npos) {
2611 base = base.substr(base.find_last_of("/") + 1);
2616 snprintf (buf, sizeof (buf), "%d", RegionFactory::nregions() + 1);
2625 string::size_type pos;
2627 pos = base.find_last_of ('.');
2629 /* pos may be npos, but then we just use entire base */
2631 subbase = base.substr (0, pos);
2636 Glib::Mutex::Lock lm (region_lock);
2638 map<string,uint32_t>::iterator x;
2642 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2644 region_name_map[subbase] = 1;
2647 snprintf (buf, sizeof (buf), ".%d", x->second);
2658 Session::add_region (boost::shared_ptr<Region> region)
2660 vector<boost::shared_ptr<Region> > v;
2661 v.push_back (region);
2666 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2668 /* mark dirty because something has changed
2673 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2675 boost::shared_ptr<Region> region = *ii;
2678 region->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region)));
2679 update_region_name_map (region);
2682 if (!new_regions.empty()) {
2683 RegionsAdded (new_regions); /* EMIT SIGNAL */
2688 Session::update_region_name_map (boost::shared_ptr<Region> region)
2690 string::size_type last_period = region->name().find_last_of ('.');
2692 if (last_period != string::npos && last_period < region->name().length() - 1) {
2694 string base = region->name().substr (0, last_period);
2695 string number = region->name().substr (last_period+1);
2696 map<string,uint32_t>::iterator x;
2698 /* note that if there is no number, we get zero from atoi,
2702 region_name_map[base] = atoi (number);
2707 Session::region_changed (const PropertyChange& what_changed, boost::weak_ptr<Region> weak_region)
2709 boost::shared_ptr<Region> region (weak_region.lock ());
2715 if (what_changed.contains (Properties::hidden)) {
2716 /* relay hidden changes */
2717 RegionHiddenChange (region);
2720 if (what_changed.contains (Properties::name)) {
2721 update_region_name_map (region);
2726 Session::remove_region (boost::weak_ptr<Region> weak_region)
2728 boost::shared_ptr<Region> region (weak_region.lock ());
2734 RegionFactory::map_remove (region);
2737 RegionRemoved(region); /* EMIT SIGNAL */
2740 boost::shared_ptr<Region>
2741 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2743 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2744 RegionFactory::RegionMap::const_iterator i;
2745 boost::shared_ptr<Region> region;
2747 Glib::Mutex::Lock lm (region_lock);
2749 for (i = regions.begin(); i != regions.end(); ++i) {
2753 if (region->whole_file()) {
2755 if (child->source_equivalent (region)) {
2761 return boost::shared_ptr<Region> ();
2765 Session::destroy_region (boost::shared_ptr<Region> region)
2767 vector<boost::shared_ptr<Source> > srcs;
2770 if (region->playlist()) {
2771 region->playlist()->destroy_region (region);
2774 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2775 srcs.push_back (region->source (n));
2779 region->drop_references ();
2781 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2783 (*i)->mark_for_remove ();
2784 (*i)->drop_references ();
2786 cerr << "source was not used by any playlist\n";
2793 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2795 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2796 destroy_region (*i);
2802 Session::remove_last_capture ()
2804 list<boost::shared_ptr<Region> > r;
2806 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2808 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2809 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2812 r.insert (r.end(), l.begin(), l.end());
2817 destroy_regions (r);
2819 save_state (_current_snapshot_name);
2824 /* Source Management */
2827 Session::add_source (boost::shared_ptr<Source> source)
2829 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2830 pair<SourceMap::iterator,bool> result;
2832 entry.first = source->id();
2833 entry.second = source;
2836 Glib::Mutex::Lock lm (source_lock);
2837 result = sources.insert (entry);
2840 if (result.second) {
2844 boost::shared_ptr<AudioFileSource> afs;
2846 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2847 if (Config->get_auto_analyse_audio()) {
2848 Analyser::queue_source_for_analysis (source, false);
2854 Session::remove_source (boost::weak_ptr<Source> src)
2856 SourceMap::iterator i;
2857 boost::shared_ptr<Source> source = src.lock();
2864 Glib::Mutex::Lock lm (source_lock);
2866 if ((i = sources.find (source->id())) != sources.end()) {
2871 if (!_state_of_the_state & InCleanup) {
2873 /* save state so we don't end up with a session file
2874 referring to non-existent sources.
2877 save_state (_current_snapshot_name);
2881 boost::shared_ptr<Source>
2882 Session::source_by_id (const PBD::ID& id)
2884 Glib::Mutex::Lock lm (source_lock);
2885 SourceMap::iterator i;
2886 boost::shared_ptr<Source> source;
2888 if ((i = sources.find (id)) != sources.end()) {
2895 boost::shared_ptr<Source>
2896 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2898 Glib::Mutex::Lock lm (source_lock);
2900 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2901 cerr << "comparing " << path << " with " << i->second->name() << endl;
2902 boost::shared_ptr<AudioFileSource> afs
2903 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2905 if (afs && afs->path() == path && chn == afs->channel()) {
2909 return boost::shared_ptr<Source>();
2914 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2917 string old_basename = PBD::basename_nosuffix (oldname);
2918 string new_legalized = legalize_for_path (newname);
2920 /* note: we know (or assume) the old path is already valid */
2924 /* destructive file sources have a name of the form:
2926 /path/to/Tnnnn-NAME(%[LR])?.wav
2928 the task here is to replace NAME with the new name.
2931 /* find last slash */
2935 string::size_type slash;
2936 string::size_type dash;
2938 if ((slash = path.find_last_of ('/')) == string::npos) {
2942 dir = path.substr (0, slash+1);
2944 /* '-' is not a legal character for the NAME part of the path */
2946 if ((dash = path.find_last_of ('-')) == string::npos) {
2950 prefix = path.substr (slash+1, dash-(slash+1));
2955 path += new_legalized;
2956 path += ".wav"; /* XXX gag me with a spoon */
2960 /* non-destructive file sources have a name of the form:
2962 /path/to/NAME-nnnnn(%[LR])?.ext
2964 the task here is to replace NAME with the new name.
2969 string::size_type slash;
2970 string::size_type dash;
2971 string::size_type postfix;
2973 /* find last slash */
2975 if ((slash = path.find_last_of ('/')) == string::npos) {
2979 dir = path.substr (0, slash+1);
2981 /* '-' is not a legal character for the NAME part of the path */
2983 if ((dash = path.find_last_of ('-')) == string::npos) {
2987 suffix = path.substr (dash+1);
2989 // Suffix is now everything after the dash. Now we need to eliminate
2990 // the nnnnn part, which is done by either finding a '%' or a '.'
2992 postfix = suffix.find_last_of ("%");
2993 if (postfix == string::npos) {
2994 postfix = suffix.find_last_of ('.');
2997 if (postfix != string::npos) {
2998 suffix = suffix.substr (postfix);
3000 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3004 const uint32_t limit = 10000;
3005 char buf[PATH_MAX+1];
3007 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3009 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3011 if (access (buf, F_OK) != 0) {
3019 error << "FATAL ERROR! Could not find a " << endl;
3027 /** Return the full path (in some session directory) for a new within-session source.
3028 * \a name must be a session-unique name that does not contain slashes
3029 * (e.g. as returned by new_*_source_name)
3032 Session::new_source_path_from_name (DataType type, const string& name)
3034 assert(name.find("/") == string::npos);
3036 SessionDirectory sdir(get_best_session_directory_for_new_source());
3039 if (type == DataType::AUDIO) {
3040 p = sdir.sound_path();
3041 } else if (type == DataType::MIDI) {
3042 p = sdir.midi_path();
3044 error << "Unknown source type, unable to create file path" << endmsg;
3049 return p.to_string();
3053 Session::peak_path (Glib::ustring base) const
3055 sys::path peakfile_path(_session_dir->peak_path());
3056 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3057 return peakfile_path.to_string();
3060 /** Return a unique name based on \a base for a new internal audio source */
3062 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3066 char buf[PATH_MAX+1];
3067 const uint32_t limit = 10000;
3071 legalized = legalize_for_path (base);
3073 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3074 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3076 vector<space_and_path>::iterator i;
3077 uint32_t existing = 0;
3079 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3081 SessionDirectory sdir((*i).path);
3083 spath = sdir.sound_path().to_string();
3088 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3089 spath.c_str(), cnt, legalized.c_str());
3090 } else if (nchan == 2) {
3092 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3093 spath.c_str(), cnt, legalized.c_str());
3095 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3096 spath.c_str(), cnt, legalized.c_str());
3098 } else if (nchan < 26) {
3099 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3100 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3102 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3103 spath.c_str(), cnt, legalized.c_str());
3112 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3113 } else if (nchan == 2) {
3115 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3117 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3119 } else if (nchan < 26) {
3120 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3122 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3126 if (sys::exists(buf)) {
3132 if (existing == 0) {
3137 error << string_compose(
3138 _("There are already %1 recordings for %2, which I consider too many."),
3139 limit, base) << endmsg;
3141 throw failed_constructor();
3145 return Glib::path_get_basename(buf);
3148 /** Create a new within-session audio source */
3149 boost::shared_ptr<AudioFileSource>
3150 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3152 const size_t n_chans = ds.n_channels().n_audio();
3153 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3154 const string path = new_source_path_from_name(DataType::AUDIO, name);
3156 return boost::dynamic_pointer_cast<AudioFileSource> (
3157 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3160 /** Return a unique name based on \a base for a new internal MIDI source */
3162 Session::new_midi_source_name (const string& base)
3165 char buf[PATH_MAX+1];
3166 const uint32_t limit = 10000;
3170 legalized = legalize_for_path (base);
3172 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3173 for (cnt = 1; cnt <= limit; ++cnt) {
3175 vector<space_and_path>::iterator i;
3176 uint32_t existing = 0;
3178 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3180 SessionDirectory sdir((*i).path);
3182 sys::path p = sdir.midi_path();
3185 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3187 if (sys::exists (buf)) {
3192 if (existing == 0) {
3197 error << string_compose(
3198 _("There are already %1 recordings for %2, which I consider too many."),
3199 limit, base) << endmsg;
3201 throw failed_constructor();
3205 return Glib::path_get_basename(buf);
3209 /** Create a new within-session MIDI source */
3210 boost::shared_ptr<MidiSource>
3211 Session::create_midi_source_for_session (MidiDiskstream& ds)
3213 const string name = new_midi_source_name (ds.name());
3214 const string path = new_source_path_from_name (DataType::MIDI, name);
3216 return boost::dynamic_pointer_cast<SMFSource> (
3217 SourceFactory::createWritable (
3218 DataType::MIDI, *this, path, false, frame_rate()));
3223 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3225 if (playlist->hidden()) {
3229 playlists->add (playlist);
3232 playlist->release();
3239 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3241 if (_state_of_the_state & Deletion) {
3245 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3251 playlists->remove (playlist);
3257 Session::set_audition (boost::shared_ptr<Region> r)
3259 pending_audition_region = r;
3260 add_post_transport_work (PostTransportAudition);
3261 _butler->schedule_transport_work ();
3265 Session::audition_playlist ()
3267 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3268 ev->region.reset ();
3273 Session::non_realtime_set_audition ()
3275 if (!pending_audition_region) {
3276 auditioner->audition_current_playlist ();
3278 auditioner->audition_region (pending_audition_region);
3279 pending_audition_region.reset ();
3281 AuditionActive (true); /* EMIT SIGNAL */
3285 Session::audition_region (boost::shared_ptr<Region> r)
3287 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3293 Session::cancel_audition ()
3295 if (auditioner->active()) {
3296 auditioner->cancel_audition ();
3297 AuditionActive (false); /* EMIT SIGNAL */
3302 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3304 if (a->is_control()) {
3307 if (b->is_control()) {
3310 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3314 Session::remove_empty_sounds ()
3316 vector<string> audio_filenames;
3318 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3320 Glib::Mutex::Lock lm (source_lock);
3322 TapeFileMatcher tape_file_matcher;
3324 remove_if (audio_filenames.begin(), audio_filenames.end(),
3325 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3327 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3329 sys::path audio_file_path (_session_dir->sound_path());
3331 audio_file_path /= *i;
3333 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3337 sys::remove (audio_file_path);
3338 const string peakfile = peak_path (audio_file_path.to_string());
3339 sys::remove (peakfile);
3341 catch (const sys::filesystem_error& err)
3343 error << err.what() << endmsg;
3350 Session::is_auditioning () const
3352 /* can be called before we have an auditioner object */
3354 return auditioner->active();
3361 Session::n_diskstreams () const
3365 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3367 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3368 if (!(*i)->hidden()) {
3376 Session::graph_reordered ()
3378 /* don't do this stuff if we are setting up connections
3379 from a set_state() call or creating new tracks. Ditto for deletion.
3382 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3386 /* every track/bus asked for this to be handled but it was deferred because
3387 we were connecting. do it now.
3390 request_input_change_handling ();
3394 /* force all diskstreams to update their capture offset values to
3395 reflect any changes in latencies within the graph.
3398 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3400 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3401 (*i)->set_capture_offset ();
3406 Session::add_processor (Processor* processor)
3408 /* Session does not own Processors (they belong to a Route) but we do want to track
3409 the arrival and departure of port inserts, sends and returns for naming
3412 processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
3417 Session::remove_processor (Processor* processor)
3421 PortInsert* port_insert;
3423 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3424 insert_bitset[port_insert->bit_slot()] = false;
3425 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3426 send_bitset[send->bit_slot()] = false;
3427 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3428 return_bitset[retrn->bit_slot()] = false;
3435 Session::available_capture_duration ()
3437 float sample_bytes_on_disk = 4.0; // keep gcc happy
3439 switch (config.get_native_file_data_format()) {
3441 sample_bytes_on_disk = 4.0;
3445 sample_bytes_on_disk = 3.0;
3449 sample_bytes_on_disk = 2.0;
3453 /* impossible, but keep some gcc versions happy */
3454 fatal << string_compose (_("programming error: %1"),
3455 X_("illegal native file data format"))
3460 double scale = 4096.0 / sample_bytes_on_disk;
3462 if (_total_free_4k_blocks * scale > (double) max_frames) {
3466 return (nframes_t) floor (_total_free_4k_blocks * scale);
3470 Session::add_bundle (shared_ptr<Bundle> bundle)
3473 RCUWriter<BundleList> writer (_bundles);
3474 boost::shared_ptr<BundleList> b = writer.get_copy ();
3475 b->push_back (bundle);
3478 BundleAdded (bundle); /* EMIT SIGNAL */
3484 Session::remove_bundle (shared_ptr<Bundle> bundle)
3486 bool removed = false;
3489 RCUWriter<BundleList> writer (_bundles);
3490 boost::shared_ptr<BundleList> b = writer.get_copy ();
3491 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3493 if (i != b->end()) {
3500 BundleRemoved (bundle); /* EMIT SIGNAL */
3507 Session::bundle_by_name (string name) const
3509 boost::shared_ptr<BundleList> b = _bundles.reader ();
3511 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3512 if ((*i)->name() == name) {
3517 return boost::shared_ptr<Bundle> ();
3521 Session::tempo_map_changed (const PropertyChange&)
3525 playlists->update_after_tempo_map_change ();
3530 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3531 * the given count with the current block size.
3534 Session::ensure_buffers (ChanCount howmany)
3536 if (current_block_size == 0) {
3537 return; // too early? (is this ok?)
3540 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3541 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3542 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3543 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3544 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3547 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3551 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3553 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3554 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3559 Session::next_insert_id ()
3561 /* this doesn't really loop forever. just think about it */
3564 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3565 if (!insert_bitset[n]) {
3566 insert_bitset[n] = true;
3572 /* none available, so resize and try again */
3574 insert_bitset.resize (insert_bitset.size() + 16, false);
3579 Session::next_send_id ()
3581 /* this doesn't really loop forever. just think about it */
3584 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3585 if (!send_bitset[n]) {
3586 send_bitset[n] = true;
3592 /* none available, so resize and try again */
3594 send_bitset.resize (send_bitset.size() + 16, false);
3599 Session::next_return_id ()
3601 /* this doesn't really loop forever. just think about it */
3604 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3605 if (!return_bitset[n]) {
3606 return_bitset[n] = true;
3612 /* none available, so resize and try again */
3614 return_bitset.resize (return_bitset.size() + 16, false);
3619 Session::mark_send_id (uint32_t id)
3621 if (id >= send_bitset.size()) {
3622 send_bitset.resize (id+16, false);
3624 if (send_bitset[id]) {
3625 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3627 send_bitset[id] = true;
3631 Session::mark_return_id (uint32_t id)
3633 if (id >= return_bitset.size()) {
3634 return_bitset.resize (id+16, false);
3636 if (return_bitset[id]) {
3637 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3639 return_bitset[id] = true;
3643 Session::mark_insert_id (uint32_t id)
3645 if (id >= insert_bitset.size()) {
3646 insert_bitset.resize (id+16, false);
3648 if (insert_bitset[id]) {
3649 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3651 insert_bitset[id] = true;
3654 /* Named Selection management */
3656 boost::shared_ptr<NamedSelection>
3657 Session::named_selection_by_name (string name)
3659 Glib::Mutex::Lock lm (named_selection_lock);
3660 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3661 if ((*i)->name == name) {
3665 return boost::shared_ptr<NamedSelection>();
3669 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3672 Glib::Mutex::Lock lm (named_selection_lock);
3673 named_selections.insert (named_selections.begin(), named_selection);
3678 NamedSelectionAdded (); /* EMIT SIGNAL */
3682 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3684 bool removed = false;
3687 Glib::Mutex::Lock lm (named_selection_lock);
3689 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3691 if (i != named_selections.end()) {
3692 named_selections.erase (i);
3699 NamedSelectionRemoved (); /* EMIT SIGNAL */
3704 Session::reset_native_file_format ()
3706 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3708 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3709 (*i)->reset_write_sources (false);
3714 Session::route_name_unique (string n) const
3716 shared_ptr<RouteList> r = routes.reader ();
3718 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3719 if ((*i)->name() == n) {
3728 Session::route_name_internal (string n) const
3730 if (auditioner && auditioner->name() == n) {
3734 if (_click_io && _click_io->name() == n) {
3742 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3744 if (!force && howmany <= _npan_buffers) {
3748 if (_pan_automation_buffer) {
3750 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3751 delete [] _pan_automation_buffer[i];
3754 delete [] _pan_automation_buffer;
3757 _pan_automation_buffer = new pan_t*[howmany];
3759 for (uint32_t i = 0; i < howmany; ++i) {
3760 _pan_automation_buffer[i] = new pan_t[nframes];
3763 _npan_buffers = howmany;
3767 Session::freeze_all (InterThreadInfo& itt)
3769 shared_ptr<RouteList> r = routes.reader ();
3771 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3773 boost::shared_ptr<Track> t;
3775 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3776 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3786 boost::shared_ptr<Region>
3787 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3788 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3789 InterThreadInfo& itt, bool enable_processing)
3791 boost::shared_ptr<Region> result;
3792 boost::shared_ptr<Playlist> playlist;
3793 boost::shared_ptr<AudioFileSource> fsource;
3795 char buf[PATH_MAX+1];
3796 ChanCount nchans(track.audio_diskstream()->n_channels());
3798 nframes_t this_chunk;
3801 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3802 const string sound_dir = sdir.sound_path().to_string();
3803 nframes_t len = end - start;
3806 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3807 end, start) << endmsg;
3811 const nframes_t chunk_size = (256 * 1024)/4;
3813 // block all process callback handling
3815 block_processing ();
3817 /* call tree *MUST* hold route_lock */
3819 if ((playlist = track.diskstream()->playlist()) == 0) {
3823 /* external redirects will be a problem */
3825 if (track.has_external_redirects()) {
3829 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3831 for (x = 0; x < 99999; ++x) {
3832 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3833 if (access (buf, F_OK) != 0) {
3839 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3844 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3845 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3848 catch (failed_constructor& err) {
3849 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3853 srcs.push_back (fsource);
3856 /* XXX need to flush all redirects */
3861 /* create a set of reasonably-sized buffers */
3862 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3863 buffers.set_count(nchans);
3865 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3866 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3868 afs->prepare_for_peakfile_writes ();
3871 while (to_do && !itt.cancel) {
3873 this_chunk = min (to_do, chunk_size);
3875 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3880 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3881 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3884 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3890 start += this_chunk;
3891 to_do -= this_chunk;
3893 itt.progress = (float) (1.0 - ((double) to_do / len));
3902 xnow = localtime (&now);
3904 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3905 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3908 afs->update_header (position, *xnow, now);
3909 afs->flush_header ();
3913 /* construct a region to represent the bounced material */
3917 plist.add (Properties::start, 0);
3918 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3919 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3921 result = RegionFactory::create (srcs, plist);
3927 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3928 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3931 afs->mark_for_remove ();
3934 (*src)->drop_references ();
3938 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3939 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3942 afs->done_with_peakfile_writes ();
3946 unblock_processing ();
3952 Session::get_silent_buffers (ChanCount count)
3954 assert(_silent_buffers->available() >= count);
3955 _silent_buffers->set_count(count);
3957 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3958 for (size_t i= 0; i < count.get(*t); ++i) {
3959 _silent_buffers->get(*t, i).clear();
3963 return *_silent_buffers;
3967 Session::get_scratch_buffers (ChanCount count)
3969 if (count != ChanCount::ZERO) {
3970 assert(_scratch_buffers->available() >= count);
3971 _scratch_buffers->set_count(count);
3973 _scratch_buffers->set_count (_scratch_buffers->available());
3976 return *_scratch_buffers;
3980 Session::get_mix_buffers (ChanCount count)
3982 assert(_mix_buffers->available() >= count);
3983 _mix_buffers->set_count(count);
3984 return *_mix_buffers;
3988 Session::ntracks () const
3991 shared_ptr<RouteList> r = routes.reader ();
3993 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3994 if (boost::dynamic_pointer_cast<Track> (*i)) {
4003 Session::nbusses () const
4006 shared_ptr<RouteList> r = routes.reader ();
4008 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4009 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4018 Session::add_automation_list(AutomationList *al)
4020 automation_lists[al->id()] = al;
4024 Session::compute_initial_length ()
4026 return _engine.frame_rate() * 60 * 5;
4030 Session::sync_order_keys (std::string const & base)
4032 if (deletion_in_progress()) {
4036 if (!Config->get_sync_all_route_ordering()) {
4037 /* leave order keys as they are */
4041 boost::shared_ptr<RouteList> r = routes.reader ();
4043 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4044 (*i)->sync_order_keys (base);
4047 Route::SyncOrderKeys (base); // EMIT SIGNAL
4049 /* this might not do anything */
4051 set_remote_control_ids ();
4054 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4056 Session::have_rec_enabled_diskstream () const
4058 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4061 /** Update the state of our rec-enabled diskstreams flag */
4063 Session::update_have_rec_enabled_diskstream ()
4065 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4066 DiskstreamList::iterator i = dsl->begin ();
4067 while (i != dsl->end () && (*i)->record_enabled () == false) {
4071 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4073 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4075 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4076 RecordStateChanged (); /* EMIT SIGNAL */
4081 Session::listen_position_changed ()
4085 switch (Config->get_listen_position()) {
4086 case AfterFaderListen:
4090 case PreFaderListen:
4095 boost::shared_ptr<RouteList> r = routes.reader ();
4097 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4098 (*i)->put_control_outs_at (p);
4103 Session::solo_control_mode_changed ()
4105 /* cancel all solo or all listen when solo control mode changes */
4107 if (Config->get_solo_control_is_listen_control()) {
4108 set_solo (routes.reader(), false);
4110 set_listen (routes.reader(), false);
4115 Session::route_group_changed ()
4117 RouteGroupChanged (); /* EMIT SIGNAL */
4121 Session::get_available_sync_options () const
4123 vector<SyncSource> ret;
4125 ret.push_back (JACK);
4128 ret.push_back (MTC);
4131 if (midi_clock_port()) {
4132 ret.push_back (MIDIClock);
4138 boost::shared_ptr<RouteList>
4139 Session::get_routes_with_regions_at (nframes64_t const p) const
4141 shared_ptr<RouteList> r = routes.reader ();
4142 shared_ptr<RouteList> rl (new RouteList);
4144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4145 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4150 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4155 boost::shared_ptr<Playlist> pl = ds->playlist ();
4160 if (pl->has_region_at (p)) {