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 region map. it doesn't hold references, but lets just be sensible here */
358 RegionFactory::clear_map ();
360 /* clear history so that no references to objects are held any more */
364 /* clear state tree so that no references to objects are held any more */
368 /* reset dynamic state version back to default */
370 Stateful::loading_state_version = 0;
373 delete midi_control_ui;
375 if (click_data != default_click) {
376 delete [] click_data;
379 if (click_emphasis_data != default_click_emphasis) {
380 delete [] click_emphasis_data;
385 delete _scratch_buffers;
386 delete _silent_buffers;
389 /* clear out any pending dead wood from RCU managed objects */
392 diskstreams.flush ();
395 AudioDiskstream::free_working_buffers();
397 /* tell everyone who is still standing that we're about to die */
400 /* tell everyone to drop references and delete objects as we go */
402 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
403 named_selections.clear ();
405 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
406 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
407 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
408 i->second->drop_references ();
412 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
414 /* reset these three references to special routes before we do the usual route delete thing */
417 _master_out.reset ();
418 _control_out.reset ();
421 RCUWriter<RouteList> writer (routes);
422 boost::shared_ptr<RouteList> r = writer.get_copy ();
424 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
425 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
426 (*i)->drop_references ();
430 /* writer goes out of scope and updates master */
434 boost::shared_ptr<RouteList> r = routes.reader ();
436 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
438 RCUWriter<DiskstreamList> dwriter (diskstreams);
439 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
440 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
441 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
442 (*i)->drop_references ();
447 diskstreams.flush ();
449 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
450 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
451 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
452 i->second->drop_references ();
457 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
458 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
463 Crossfade::set_buffer_size (0);
467 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
470 boost_debug_list_ptrs ();
472 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
476 Session::set_worst_io_latencies ()
478 _worst_output_latency = 0;
479 _worst_input_latency = 0;
481 if (!_engine.connected()) {
485 boost::shared_ptr<RouteList> r = routes.reader ();
487 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
488 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
489 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
494 Session::when_engine_running ()
496 string first_physical_output;
498 BootMessage (_("Set block size and sample rate"));
500 set_block_size (_engine.frames_per_cycle());
501 set_frame_rate (_engine.frame_rate());
503 BootMessage (_("Using configuration"));
505 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
506 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
508 Config->map_parameters (ff);
509 config.map_parameters (ft);
511 /* every time we reconnect, recompute worst case output latencies */
513 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
515 if (synced_to_jack()) {
516 _engine.transport_stop ();
519 if (config.get_jack_time_master()) {
520 _engine.transport_locate (_transport_frame);
528 _click_io.reset (new ClickIO (*this, "click"));
530 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
532 /* existing state for Click */
535 if (Stateful::loading_state_version < 3000) {
536 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
538 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
543 _clicking = Config->get_clicking ();
547 error << _("could not setup Click I/O") << endmsg;
554 /* default state for Click: dual-mono to first 2 physical outputs */
556 for (int physport = 0; physport < 2; ++physport) {
557 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
559 if (physical_output.length()) {
560 if (_click_io->add_port (physical_output, this)) {
561 // relax, even though its an error
566 if (_click_io->n_ports () > ChanCount::ZERO) {
567 _clicking = Config->get_clicking ();
572 catch (failed_constructor& err) {
573 error << _("cannot setup Click I/O") << endmsg;
576 BootMessage (_("Compute I/O Latencies"));
578 set_worst_io_latencies ();
581 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
584 BootMessage (_("Set up standard connections"));
586 /* Create a set of Bundle objects that map
587 to the physical I/O currently available. We create both
588 mono and stereo bundles, so that the common cases of mono
589 and stereo tracks get bundles to put in their mixer strip
590 in / out menus. There may be a nicer way of achieving that;
591 it doesn't really scale that well to higher channel counts
594 /* mono output bundles */
596 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
598 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
600 shared_ptr<Bundle> c (new Bundle (buf, true));
601 c->add_channel (_("mono"));
602 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
607 /* stereo output bundles */
609 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
610 if (np + 1 < n_physical_outputs) {
612 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
613 shared_ptr<Bundle> c (new Bundle (buf, true));
614 c->add_channel (_("L"));
615 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
616 c->add_channel (_("R"));
617 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
623 /* mono input bundles */
625 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
627 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
629 shared_ptr<Bundle> c (new Bundle (buf, false));
630 c->add_channel (_("mono"));
631 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
636 /* stereo input bundles */
638 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
639 if (np + 1 < n_physical_inputs) {
641 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
643 shared_ptr<Bundle> c (new Bundle (buf, false));
644 c->add_channel (_("L"));
645 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
646 c->add_channel (_("R"));
647 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
653 BootMessage (_("Setup signal flow and plugins"));
657 if (!no_auto_connect()) {
659 if (_master_out && Config->get_auto_connect_standard_busses()) {
661 /* if requested auto-connect the outputs to the first N physical ports.
664 uint32_t limit = _master_out->n_outputs().n_total();
666 for (uint32_t n = 0; n < limit; ++n) {
667 Port* p = _master_out->output()->nth (n);
668 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
670 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
671 if (_master_out->output()->connect (p, connect_to, this)) {
672 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
682 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
683 are undefined, at best.
686 /* control out listens to master bus (but ignores it
687 under some conditions)
690 uint32_t limit = _control_out->n_inputs().n_audio();
693 for (uint32_t n = 0; n < limit; ++n) {
694 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
695 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
698 string connect_to = o->name();
699 if (_control_out->input()->connect (p, connect_to, this)) {
700 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
708 /* if control out is not connected,
709 connect control out to physical outs, but use ones after the master if possible
712 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
714 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
716 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
719 _control_out->output()->connect_ports_to_bundle (b, this);
721 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
722 Config->get_monitor_bus_preferred_bundle())
728 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
729 uint32_t shift = _master_out->n_outputs().get(*t);
730 uint32_t mod = _engine.n_physical_outputs (*t);
731 limit = _control_out->n_outputs().get(*t);
733 cerr << "Connecting " << limit << " control out ports, shift is " << shift
734 << " mod is " << mod << endl;
736 for (uint32_t n = 0; n < limit; ++n) {
738 Port* p = _control_out->output()->ports().port(*t, n);
739 string connect_to = _engine.get_nth_physical_output (*t, (n+shift) % mod);
741 if (!connect_to.empty()) {
742 if (_control_out->output()->connect (p, connect_to, this)) {
743 error << string_compose (
744 _("cannot connect control output %1 to %2"),
757 /* catch up on send+insert cnts */
759 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
761 /* hook us up to the engine */
763 BootMessage (_("Connect to engine"));
765 _engine.set_session (this);
769 Session::hookup_io ()
771 /* stop graph reordering notifications from
772 causing resorts, etc.
775 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
780 /* we delay creating the auditioner till now because
781 it makes its own connections to ports.
782 the engine has to be running for this to work.
786 auditioner.reset (new Auditioner (*this));
789 catch (failed_constructor& err) {
790 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
794 /* load bundles, which we may have postponed earlier on */
795 if (_bundle_xml_node) {
796 load_bundles (*_bundle_xml_node);
797 delete _bundle_xml_node;
800 /* Tell all IO objects to connect themselves together */
802 IO::enable_connecting ();
803 MIDI::JACK_MidiPort::MakeConnections ();
805 /* Now reset all panners */
807 Delivery::reset_panners ();
809 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
813 boost::shared_ptr<RouteList> r = routes.reader ();
815 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
817 if ((*x)->is_control() || (*x)->is_master()) {
821 (*x)->listen_via (_control_out,
822 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
827 /* Anyone who cares about input state, wake up and do something */
829 IOConnectionsComplete (); /* EMIT SIGNAL */
831 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
833 /* now handle the whole enchilada as if it was one
839 /* update the full solo state, which can't be
840 correctly determined on a per-route basis, but
841 needs the global overview that only the session
845 update_route_solo_state ();
849 Session::playlist_length_changed ()
851 /* we can't just increase end_location->end() if pl->get_maximum_extent()
852 if larger. if the playlist used to be the longest playlist,
853 and its now shorter, we have to decrease end_location->end(). hence,
854 we have to iterate over all diskstreams and check the
855 playlists currently in use.
861 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
863 boost::shared_ptr<Diskstream> dstream = wp.lock ();
868 boost::shared_ptr<Playlist> playlist;
870 if ((playlist = dstream->playlist()) != 0) {
871 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
874 /* see comment in playlist_length_changed () */
879 Session::record_enabling_legal () const
881 /* this used to be in here, but survey says.... we don't need to restrict it */
882 // if (record_status() == Recording) {
886 if (Config->get_all_safe()) {
893 Session::reset_input_monitor_state ()
895 if (transport_rolling()) {
897 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
899 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
900 if ((*i)->record_enabled ()) {
901 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
902 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
906 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
908 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
909 if ((*i)->record_enabled ()) {
910 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
911 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
918 Session::auto_punch_start_changed (Location* location)
920 replace_event (SessionEvent::PunchIn, location->start());
922 if (get_record_enabled() && config.get_punch_in()) {
923 /* capture start has been changed, so save new pending state */
924 save_state ("", true);
929 Session::auto_punch_end_changed (Location* location)
931 nframes_t when_to_stop = location->end();
932 // when_to_stop += _worst_output_latency + _worst_input_latency;
933 replace_event (SessionEvent::PunchOut, when_to_stop);
937 Session::auto_punch_changed (Location* location)
939 nframes_t when_to_stop = location->end();
941 replace_event (SessionEvent::PunchIn, location->start());
942 //when_to_stop += _worst_output_latency + _worst_input_latency;
943 replace_event (SessionEvent::PunchOut, when_to_stop);
947 Session::auto_loop_changed (Location* location)
949 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
951 if (transport_rolling() && play_loop) {
954 // if (_transport_frame > location->end()) {
956 if (_transport_frame < location->start() || _transport_frame > location->end()) {
957 // relocate to beginning of loop
958 clear_events (SessionEvent::LocateRoll);
960 request_locate (location->start(), true);
963 else if (Config->get_seamless_loop() && !loop_changing) {
965 // schedule a locate-roll to refill the diskstreams at the
967 loop_changing = true;
969 if (location->end() > last_loopend) {
970 clear_events (SessionEvent::LocateRoll);
971 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
978 last_loopend = location->end();
982 Session::set_auto_punch_location (Location* location)
986 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
987 punch_connections.drop_connections();
988 existing->set_auto_punch (false, this);
989 remove_event (existing->start(), SessionEvent::PunchIn);
990 clear_events (SessionEvent::PunchOut);
991 auto_punch_location_changed (0);
1000 if (location->end() <= location->start()) {
1001 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1005 punch_connections.drop_connections ();
1007 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1008 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1009 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1011 location->set_auto_punch (true, this);
1013 auto_punch_changed (location);
1015 auto_punch_location_changed (location);
1019 Session::set_auto_loop_location (Location* location)
1023 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1024 loop_connections.drop_connections ();
1025 existing->set_auto_loop (false, this);
1026 remove_event (existing->end(), SessionEvent::AutoLoop);
1027 auto_loop_location_changed (0);
1032 if (location == 0) {
1036 if (location->end() <= location->start()) {
1037 error << _("Session: you can't use a mark for auto loop") << endmsg;
1041 last_loopend = location->end();
1043 loop_connections.drop_connections ();
1045 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1046 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1047 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1049 location->set_auto_loop (true, this);
1051 /* take care of our stuff first */
1053 auto_loop_changed (location);
1055 /* now tell everyone else */
1057 auto_loop_location_changed (location);
1061 Session::locations_added (Location *)
1067 Session::locations_changed ()
1069 _locations.apply (*this, &Session::handle_locations_changed);
1073 Session::handle_locations_changed (Locations::LocationList& locations)
1075 Locations::LocationList::iterator i;
1077 bool set_loop = false;
1078 bool set_punch = false;
1080 for (i = locations.begin(); i != locations.end(); ++i) {
1084 if (location->is_auto_punch()) {
1085 set_auto_punch_location (location);
1088 if (location->is_auto_loop()) {
1089 set_auto_loop_location (location);
1093 if (location->is_start()) {
1094 start_location = location;
1096 if (location->is_end()) {
1097 end_location = location;
1102 set_auto_loop_location (0);
1105 set_auto_punch_location (0);
1112 Session::enable_record ()
1114 /* XXX really atomic compare+swap here */
1115 if (g_atomic_int_get (&_record_status) != Recording) {
1116 g_atomic_int_set (&_record_status, Recording);
1117 _last_record_location = _transport_frame;
1118 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1120 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1121 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1122 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1123 if ((*i)->record_enabled ()) {
1124 (*i)->monitor_input (true);
1129 RecordStateChanged ();
1134 Session::disable_record (bool rt_context, bool force)
1138 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1140 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1141 g_atomic_int_set (&_record_status, Disabled);
1143 if (rs == Recording) {
1144 g_atomic_int_set (&_record_status, Enabled);
1148 // FIXME: timestamp correct? [DR]
1149 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1150 // does this /need/ to be sent in all cases?
1152 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1155 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1156 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1158 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1159 if ((*i)->record_enabled ()) {
1160 (*i)->monitor_input (false);
1165 RecordStateChanged (); /* emit signal */
1168 remove_pending_capture_state ();
1174 Session::step_back_from_record ()
1176 /* XXX really atomic compare+swap here */
1177 if (g_atomic_int_get (&_record_status) == Recording) {
1178 g_atomic_int_set (&_record_status, Enabled);
1180 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1181 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1183 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1184 if ((*i)->record_enabled ()) {
1185 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1186 (*i)->monitor_input (false);
1194 Session::maybe_enable_record ()
1196 g_atomic_int_set (&_record_status, Enabled);
1198 /* this function is currently called from somewhere other than an RT thread.
1199 this save_state() call therefore doesn't impact anything.
1202 save_state ("", true);
1204 if (_transport_speed) {
1205 if (!config.get_punch_in()) {
1209 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1210 RecordStateChanged (); /* EMIT SIGNAL */
1217 Session::audible_frame () const
1223 /* the first of these two possible settings for "offset"
1224 mean that the audible frame is stationary until
1225 audio emerges from the latency compensation
1228 the second means that the audible frame is stationary
1229 until audio would emerge from a physical port
1230 in the absence of any plugin latency compensation
1233 offset = _worst_output_latency;
1235 if (offset > current_block_size) {
1236 offset -= current_block_size;
1238 /* XXX is this correct? if we have no external
1239 physical connections and everything is internal
1240 then surely this is zero? still, how
1241 likely is that anyway?
1243 offset = current_block_size;
1246 if (synced_to_jack()) {
1247 tf = _engine.transport_frame();
1249 tf = _transport_frame;
1254 if (!non_realtime_work_pending()) {
1258 /* check to see if we have passed the first guaranteed
1259 audible frame past our last start position. if not,
1260 return that last start point because in terms
1261 of audible frames, we have not moved yet.
1264 if (_transport_speed > 0.0f) {
1266 if (!play_loop || !have_looped) {
1267 if (tf < _last_roll_location + offset) {
1268 return _last_roll_location;
1276 } else if (_transport_speed < 0.0f) {
1278 /* XXX wot? no backward looping? */
1280 if (tf > _last_roll_location - offset) {
1281 return _last_roll_location;
1293 Session::set_frame_rate (nframes_t frames_per_second)
1295 /** \fn void Session::set_frame_size(nframes_t)
1296 the AudioEngine object that calls this guarantees
1297 that it will not be called while we are also in
1298 ::process(). Its fine to do things that block
1302 _base_frame_rate = frames_per_second;
1306 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1310 // XXX we need some equivalent to this, somehow
1311 // SndFileSource::setup_standard_crossfades (frames_per_second);
1315 /* XXX need to reset/reinstantiate all LADSPA plugins */
1319 Session::set_block_size (nframes_t nframes)
1321 /* the AudioEngine guarantees
1322 that it will not be called while we are also in
1323 ::process(). It is therefore fine to do things that block
1328 current_block_size = nframes;
1330 ensure_buffers(_scratch_buffers->available());
1332 delete [] _gain_automation_buffer;
1333 _gain_automation_buffer = new gain_t[nframes];
1335 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1337 boost::shared_ptr<RouteList> r = routes.reader ();
1339 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1340 (*i)->set_block_size (nframes);
1343 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1344 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1345 (*i)->set_block_size (nframes);
1348 set_worst_io_latencies ();
1353 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1356 nframes_t fade_frames;
1358 /* Don't allow fade of less 1 frame */
1360 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1367 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1371 default_fade_msecs = fade_msecs;
1372 default_fade_steepness = steepness;
1375 // jlc, WTF is this!
1376 Glib::RWLock::ReaderLock lm (route_lock);
1377 AudioRegion::set_default_fade (steepness, fade_frames);
1382 /* XXX have to do this at some point */
1383 /* foreach region using default fade, reset, then
1384 refill_all_diskstream_buffers ();
1389 struct RouteSorter {
1390 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1391 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1393 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1396 if (r1->fed_by.empty()) {
1397 if (r2->fed_by.empty()) {
1398 /* no ardour-based connections inbound to either route. just use signal order */
1399 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1401 /* r2 has connections, r1 does not; run r1 early */
1405 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1412 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1414 shared_ptr<Route> r2;
1416 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1417 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1421 /* make a copy of the existing list of routes that feed r1 */
1423 set<weak_ptr<Route> > existing = r1->fed_by;
1425 /* for each route that feeds r1, recurse, marking it as feeding
1429 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1430 if (!(r2 = (*i).lock ())) {
1431 /* (*i) went away, ignore it */
1435 /* r2 is a route that feeds r1 which somehow feeds base. mark
1436 base as being fed by r2
1439 rbase->fed_by.insert (r2);
1443 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1447 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1451 /* now recurse, so that we can mark base as being fed by
1452 all routes that feed r2
1455 trace_terminal (r2, rbase);
1462 Session::resort_routes ()
1464 /* don't do anything here with signals emitted
1465 by Routes while we are being destroyed.
1468 if (_state_of_the_state & Deletion) {
1475 RCUWriter<RouteList> writer (routes);
1476 shared_ptr<RouteList> r = writer.get_copy ();
1477 resort_routes_using (r);
1478 /* writer goes out of scope and forces update */
1483 Session::resort_routes_using (shared_ptr<RouteList> r)
1485 RouteList::iterator i, j;
1487 for (i = r->begin(); i != r->end(); ++i) {
1489 (*i)->fed_by.clear ();
1491 for (j = r->begin(); j != r->end(); ++j) {
1493 /* although routes can feed themselves, it will
1494 cause an endless recursive descent if we
1495 detect it. so don't bother checking for
1503 if ((*j)->feeds (*i)) {
1504 (*i)->fed_by.insert (*j);
1509 for (i = r->begin(); i != r->end(); ++i) {
1510 trace_terminal (*i, *i);
1517 cerr << "finished route resort\n";
1519 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1520 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1527 /** Find the route name starting with \a base with the lowest \a id.
1529 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1530 * The available route name with the lowest ID will be used, and \a id
1531 * will be set to the ID.
1533 * \return false if a route name could not be found, and \a track_name
1534 * and \a id do not reflect a free route name.
1537 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1540 snprintf (name, name_len, "%s %" PRIu32, base, id);
1542 if (route_by_name (name) == 0) {
1548 } while (id < (UINT_MAX-1));
1554 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1556 in = ChanCount::ZERO;
1557 out = ChanCount::ZERO;
1558 shared_ptr<RouteList> r = routes.reader ();
1559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1560 if (!(*i)->is_hidden()) {
1561 in += (*i)->n_inputs();
1562 out += (*i)->n_outputs();
1567 list<boost::shared_ptr<MidiTrack> >
1568 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1570 char track_name[32];
1571 uint32_t track_id = 1;
1572 ChanCount existing_inputs;
1573 ChanCount existing_outputs;
1575 RouteList new_routes;
1576 list<boost::shared_ptr<MidiTrack> > ret;
1577 uint32_t control_id;
1579 count_existing_route_channels (existing_inputs, existing_outputs);
1581 control_id = ntracks() + nbusses();
1584 if (!find_route_name ("Midi", track_id, track_name, sizeof(track_name))) {
1585 error << "cannot find name for new midi track" << endmsg;
1589 shared_ptr<MidiTrack> track;
1592 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1593 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1594 track = boost::shared_ptr<MidiTrack>(mt);
1596 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1597 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1602 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1603 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1607 auto_connect_route (track, existing_inputs, existing_outputs);
1609 track->midi_diskstream()->non_realtime_input_change();
1611 route_group->add (track);
1614 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1615 track->set_remote_control_id (control_id);
1617 new_routes.push_back (track);
1618 ret.push_back (track);
1621 catch (failed_constructor &err) {
1622 error << _("Session: could not create new midi track.") << endmsg;
1625 /* we need to get rid of this, since the track failed to be created */
1626 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1629 RCUWriter<DiskstreamList> writer (diskstreams);
1630 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1631 ds->remove (track->midi_diskstream());
1638 catch (AudioEngine::PortRegistrationFailure& pfe) {
1640 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;
1643 /* we need to get rid of this, since the track failed to be created */
1644 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1647 RCUWriter<DiskstreamList> writer (diskstreams);
1648 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1649 ds->remove (track->midi_diskstream());
1660 if (!new_routes.empty()) {
1661 add_routes (new_routes, false);
1662 save_state (_current_snapshot_name);
1669 Session::auto_connect_route (boost::shared_ptr<Route> route,
1670 ChanCount& existing_inputs, ChanCount& existing_outputs)
1672 /* If both inputs and outputs are auto-connected to physical ports,
1673 use the max of input and output offsets to ensure auto-connected
1674 port numbers always match up (e.g. the first audio input and the
1675 first audio output of the route will have the same physical
1676 port number). Otherwise just use the lowest input or output
1679 const bool in_out_physical =
1680 (Config->get_input_auto_connect() & AutoConnectPhysical)
1681 && (Config->get_output_auto_connect() & AutoConnectPhysical);
1683 const ChanCount in_offset = in_out_physical
1684 ? ChanCount::max(existing_inputs, existing_outputs)
1687 const ChanCount out_offset = in_out_physical
1688 ? ChanCount::max(existing_inputs, existing_outputs)
1691 static string empty_string;
1692 string& port = empty_string;
1694 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1695 vector<string> physinputs;
1696 vector<string> physoutputs;
1698 _engine.get_physical_outputs (*t, physoutputs);
1699 _engine.get_physical_inputs (*t, physinputs);
1701 if (!physinputs.empty()) {
1702 uint32_t nphysical_in = physinputs.size();
1703 for (uint32_t i = 0; i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1704 port = empty_string;
1706 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1707 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1710 if (!port.empty() && route->input()->connect (
1711 route->input()->ports().port(*t, i), port, this)) {
1717 if (!physoutputs.empty()) {
1718 uint32_t nphysical_out = physoutputs.size();
1719 for (uint32_t i = 0; i < route->n_outputs().get(*t); ++i) {
1720 port = empty_string;
1722 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1723 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1724 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1725 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1726 port = _master_out->input()->ports().port(*t,
1727 i % _master_out->input()->n_ports().get(*t))->name();
1731 if (!port.empty() && route->output()->connect (
1732 route->output()->ports().port(*t, i), port, this)) {
1739 existing_inputs += route->n_inputs();
1740 existing_outputs += route->n_outputs();
1743 list<boost::shared_ptr<AudioTrack> >
1744 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1746 char track_name[32];
1747 uint32_t track_id = 1;
1748 ChanCount existing_inputs;
1749 ChanCount existing_outputs;
1751 RouteList new_routes;
1752 list<boost::shared_ptr<AudioTrack> > ret;
1753 uint32_t control_id;
1755 count_existing_route_channels (existing_inputs, existing_outputs);
1757 control_id = ntracks() + nbusses() + 1;
1760 if (!find_route_name ("Audio", track_id, track_name, sizeof(track_name))) {
1761 error << "cannot find name for new audio track" << endmsg;
1765 shared_ptr<AudioTrack> track;
1768 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1769 boost_debug_shared_ptr_mark_interesting (at, "Track");
1770 track = boost::shared_ptr<AudioTrack>(at);
1772 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1773 error << string_compose (
1774 _("cannot configure %1 in/%2 out configuration for new audio track"),
1775 input_channels, output_channels)
1780 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1781 error << string_compose (
1782 _("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1788 auto_connect_route (track, existing_inputs, existing_outputs);
1791 route_group->add (track);
1794 track->audio_diskstream()->non_realtime_input_change();
1796 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1797 track->set_remote_control_id (control_id);
1800 new_routes.push_back (track);
1801 ret.push_back (track);
1804 catch (failed_constructor &err) {
1805 error << _("Session: could not create new audio track.") << endmsg;
1808 /* we need to get rid of this, since the track failed to be created */
1809 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1812 RCUWriter<DiskstreamList> writer (diskstreams);
1813 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1814 ds->remove (track->audio_diskstream());
1821 catch (AudioEngine::PortRegistrationFailure& pfe) {
1823 error << pfe.what() << endmsg;
1826 /* we need to get rid of this, since the track failed to be created */
1827 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1830 RCUWriter<DiskstreamList> writer (diskstreams);
1831 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1832 ds->remove (track->audio_diskstream());
1843 if (!new_routes.empty()) {
1844 add_routes (new_routes, true);
1851 Session::set_remote_control_ids ()
1853 RemoteModel m = Config->get_remote_model();
1854 bool emit_signal = false;
1856 shared_ptr<RouteList> r = routes.reader ();
1858 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1859 if (MixerOrdered == m) {
1860 long order = (*i)->order_key(N_("signal"));
1861 (*i)->set_remote_control_id (order+1, false);
1863 } else if (EditorOrdered == m) {
1864 long order = (*i)->order_key(N_("editor"));
1865 (*i)->set_remote_control_id (order+1, false);
1867 } else if (UserOrdered == m) {
1868 //do nothing ... only changes to remote id's are initiated by user
1873 Route::RemoteControlIDChange();
1879 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1882 uint32_t bus_id = 1;
1883 ChanCount existing_inputs;
1884 ChanCount existing_outputs;
1887 uint32_t control_id;
1889 count_existing_route_channels (existing_inputs, existing_outputs);
1891 control_id = ntracks() + nbusses() + 1;
1894 if (!find_route_name ("Bus", bus_id, bus_name, sizeof(bus_name))) {
1895 error << "cannot find name for new audio bus" << endmsg;
1900 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1901 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1902 shared_ptr<Route> bus (rt);
1904 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1905 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1906 input_channels, output_channels)
1912 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1913 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1914 input_channels, output_channels)
1919 auto_connect_route (bus, existing_inputs, existing_outputs);
1922 route_group->add (bus);
1924 bus->set_remote_control_id (control_id);
1928 bus->add_internal_return ();
1931 ret.push_back (bus);
1935 catch (failed_constructor &err) {
1936 error << _("Session: could not create new audio route.") << endmsg;
1940 catch (AudioEngine::PortRegistrationFailure& pfe) {
1941 error << pfe.what() << endmsg;
1951 add_routes (ret, true);
1959 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1963 uint32_t control_id;
1965 uint32_t number = 1;
1967 if (!tree.read (template_path.c_str())) {
1971 XMLNode* node = tree.root();
1973 control_id = ntracks() + nbusses() + 1;
1977 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1979 std::string node_name = IO::name_from_state (*node_copy.children().front());
1981 /* generate a new name by adding a number to the end of the template name */
1982 if (!find_route_name (node_name.c_str(), number, name, sizeof(name))) {
1983 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1987 IO::set_name_in_state (*node_copy.children().front(), name);
1989 Track::zero_diskstream_id_in_xml (node_copy);
1992 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1995 error << _("Session: cannot create track/bus from template description") << endmsg;
1999 if (boost::dynamic_pointer_cast<Track>(route)) {
2000 /* force input/output change signals so that the new diskstream
2001 picks up the configuration of the route. During session
2002 loading this normally happens in a different way.
2004 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2005 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2008 route->set_remote_control_id (control_id);
2011 ret.push_back (route);
2014 catch (failed_constructor &err) {
2015 error << _("Session: could not create new route from template") << endmsg;
2019 catch (AudioEngine::PortRegistrationFailure& pfe) {
2020 error << pfe.what() << endmsg;
2029 add_routes (ret, true);
2036 Session::add_routes (RouteList& new_routes, bool save)
2039 RCUWriter<RouteList> writer (routes);
2040 shared_ptr<RouteList> r = writer.get_copy ();
2041 r->insert (r->end(), new_routes.begin(), new_routes.end());
2044 /* if there is no control out and we're not in the middle of loading,
2045 resort the graph here. if there is a control out, we will resort
2046 toward the end of this method. if we are in the middle of loading,
2047 we will resort when done.
2050 if (!_control_out && IO::connecting_legal) {
2051 resort_routes_using (r);
2055 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2057 boost::weak_ptr<Route> wpr (*x);
2058 boost::shared_ptr<Route> r (*x);
2060 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2061 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
2062 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2063 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2064 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2065 r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2067 if (r->is_master()) {
2071 if (r->is_control()) {
2076 if (_control_out && IO::connecting_legal) {
2078 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2079 if ((*x)->is_control() || (*x)->is_master()) {
2082 (*x)->listen_via (_control_out,
2083 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2093 save_state (_current_snapshot_name);
2096 RouteAdded (new_routes); /* EMIT SIGNAL */
2097 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2101 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2103 boost::shared_ptr<RouteList> r = routes.reader ();
2104 boost::shared_ptr<Send> s;
2108 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2109 if (boost::dynamic_pointer_cast<Track>(*i)) {
2110 if ((s = (*i)->internal_send_for (dest)) != 0) {
2111 s->amp()->gain_control()->set_value (0.0);
2118 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2120 boost::shared_ptr<RouteList> r = routes.reader ();
2121 boost::shared_ptr<Send> s;
2125 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2126 if (boost::dynamic_pointer_cast<Track>(*i)) {
2127 if ((s = (*i)->internal_send_for (dest)) != 0) {
2128 s->amp()->gain_control()->set_value (1.0);
2135 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2137 boost::shared_ptr<RouteList> r = routes.reader ();
2138 boost::shared_ptr<Send> s;
2142 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2143 if (boost::dynamic_pointer_cast<Track>(*i)) {
2144 if ((s = (*i)->internal_send_for (dest)) != 0) {
2145 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2152 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2154 boost::shared_ptr<RouteList> r = routes.reader ();
2155 boost::shared_ptr<RouteList> t (new RouteList);
2157 /* only send tracks */
2159 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2160 if (boost::dynamic_pointer_cast<Track>(*i)) {
2165 add_internal_sends (dest, p, t);
2169 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2171 if (dest->is_control() || dest->is_master()) {
2175 if (!dest->internal_return()) {
2176 dest->add_internal_return();
2179 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2181 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2185 (*i)->listen_via (dest, p, true, true);
2192 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2194 /* need to do this in case we're rolling at the time, to prevent false underruns */
2195 dstream->do_refill_with_alloc ();
2197 dstream->set_block_size (current_block_size);
2200 RCUWriter<DiskstreamList> writer (diskstreams);
2201 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2202 ds->push_back (dstream);
2203 /* writer goes out of scope, copies ds back to main */
2206 dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr<Diskstream> (dstream)));
2207 /* this will connect to future changes, and check the current length */
2208 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2210 dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this));
2212 dstream->prepare ();
2217 Session::remove_route (shared_ptr<Route> route)
2220 RCUWriter<RouteList> writer (routes);
2221 shared_ptr<RouteList> rs = writer.get_copy ();
2225 /* deleting the master out seems like a dumb
2226 idea, but its more of a UI policy issue
2230 if (route == _master_out) {
2231 _master_out = shared_ptr<Route> ();
2234 if (route == _control_out) {
2236 /* cancel control outs for all routes */
2238 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2239 (*r)->drop_listen (_control_out);
2242 _control_out.reset ();
2245 update_route_solo_state ();
2247 /* writer goes out of scope, forces route list update */
2250 boost::shared_ptr<Track> t;
2251 boost::shared_ptr<Diskstream> ds;
2253 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2254 ds = t->diskstream();
2260 RCUWriter<DiskstreamList> dsl (diskstreams);
2261 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2266 find_current_end ();
2268 // We need to disconnect the routes inputs and outputs
2270 route->input()->disconnect (0);
2271 route->output()->disconnect (0);
2273 /* if the route had internal sends sending to it, remove them */
2274 if (route->internal_return()) {
2276 boost::shared_ptr<RouteList> r = routes.reader ();
2277 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2278 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2280 (*i)->remove_processor (s);
2285 update_latency_compensation (false, false);
2288 /* get rid of it from the dead wood collection in the route list manager */
2290 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2294 /* try to cause everyone to drop their references */
2296 route->drop_references ();
2298 sync_order_keys (N_("session"));
2300 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2302 /* save the new state of the world */
2304 if (save_state (_current_snapshot_name)) {
2305 save_history (_current_snapshot_name);
2310 Session::route_mute_changed (void* /*src*/)
2316 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2318 boost::shared_ptr<Route> route = wpr.lock();
2320 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2324 if (route->listening()) {
2326 } else if (_listen_cnt > 0) {
2332 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2334 if (solo_update_disabled) {
2339 boost::shared_ptr<Route> route = wpr.lock ();
2342 /* should not happen */
2343 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2347 shared_ptr<RouteList> r = routes.reader ();
2350 if (route->self_soloed()) {
2356 /* now mod the solo level of all other routes except master & control outs
2357 so that they will be silent if appropriate.
2360 solo_update_disabled = true;
2362 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2363 bool via_sends_only;
2365 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_control() || (*i)->is_hidden()) {
2367 } else if ((*i)->feeds (route, &via_sends_only)) {
2368 if (!via_sends_only) {
2369 (*i)->mod_solo_by_others (delta);
2374 /* make sure master is never muted by solo */
2376 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2377 _master_out->mod_solo_by_others (1);
2380 /* ditto for control outs make sure master is never muted by solo */
2382 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2383 _control_out->mod_solo_by_others (1);
2386 solo_update_disabled = false;
2387 update_route_solo_state (r);
2388 SoloChanged (); /* EMIT SIGNAL */
2393 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2395 /* now figure out if anything that matters is soloed */
2397 bool something_soloed = false;
2400 r = routes.reader();
2403 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2404 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2405 something_soloed = true;
2410 if (something_soloed != _non_soloed_outs_muted) {
2411 _non_soloed_outs_muted = something_soloed;
2412 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2416 boost::shared_ptr<RouteList>
2417 Session::get_routes_with_internal_returns() const
2419 shared_ptr<RouteList> r = routes.reader ();
2420 boost::shared_ptr<RouteList> rl (new RouteList);
2422 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2423 if ((*i)->internal_return ()) {
2431 Session::route_by_name (string name)
2433 shared_ptr<RouteList> r = routes.reader ();
2435 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2436 if ((*i)->name() == name) {
2441 return shared_ptr<Route> ((Route*) 0);
2445 Session::route_by_id (PBD::ID id)
2447 shared_ptr<RouteList> r = routes.reader ();
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 if ((*i)->id() == id) {
2455 return shared_ptr<Route> ((Route*) 0);
2459 Session::route_by_remote_id (uint32_t id)
2461 shared_ptr<RouteList> r = routes.reader ();
2463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2464 if ((*i)->remote_control_id() == id) {
2469 return shared_ptr<Route> ((Route*) 0);
2473 Session::find_current_end ()
2475 if (_state_of_the_state & Loading) {
2479 nframes_t max = get_maximum_extent ();
2481 if (max > end_location->end()) {
2482 end_location->set_end (max);
2484 DurationChanged(); /* EMIT SIGNAL */
2489 Session::get_maximum_extent () const
2494 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2496 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2497 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2499 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2500 if ((me = pl->get_maximum_extent()) > max) {
2508 boost::shared_ptr<Diskstream>
2509 Session::diskstream_by_name (string name)
2511 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2513 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2514 if ((*i)->name() == name) {
2519 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2522 boost::shared_ptr<Diskstream>
2523 Session::diskstream_by_id (const PBD::ID& id)
2525 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2527 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2528 if ((*i)->id() == id) {
2533 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2536 /* Region management */
2539 Session::new_region_name (string old)
2541 string::size_type last_period;
2543 string::size_type len = old.length() + 64;
2546 if ((last_period = old.find_last_of ('.')) == string::npos) {
2548 /* no period present - add one explicitly */
2551 last_period = old.length() - 1;
2556 number = atoi (old.substr (last_period+1).c_str());
2560 while (number < (UINT_MAX-1)) {
2562 RegionList::const_iterator i;
2567 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2570 for (i = regions.begin(); i != regions.end(); ++i) {
2571 if (i->second->name() == sbuf) {
2576 if (i == regions.end()) {
2581 if (number != (UINT_MAX-1)) {
2585 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2590 Session::region_name (string& result, string base, bool newlevel)
2595 if (base.find("/") != string::npos) {
2596 base = base.substr(base.find_last_of("/") + 1);
2601 Glib::Mutex::Lock lm (region_lock);
2603 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2612 string::size_type pos;
2614 pos = base.find_last_of ('.');
2616 /* pos may be npos, but then we just use entire base */
2618 subbase = base.substr (0, pos);
2623 Glib::Mutex::Lock lm (region_lock);
2625 map<string,uint32_t>::iterator x;
2629 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2631 region_name_map[subbase] = 1;
2634 snprintf (buf, sizeof (buf), ".%d", x->second);
2645 Session::add_region (boost::shared_ptr<Region> region)
2647 vector<boost::shared_ptr<Region> > v;
2648 v.push_back (region);
2653 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2658 Glib::Mutex::Lock lm (region_lock);
2660 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2662 boost::shared_ptr<Region> region = *ii;
2666 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2670 RegionList::iterator x;
2672 for (x = regions.begin(); x != regions.end(); ++x) {
2674 if (region->region_list_equivalent (x->second)) {
2679 if (x == regions.end()) {
2681 pair<RegionList::key_type,RegionList::mapped_type> entry;
2683 entry.first = region->id();
2684 entry.second = region;
2686 pair<RegionList::iterator,bool> x = regions.insert (entry);
2698 /* mark dirty because something has changed even if we didn't
2699 add the region to the region list.
2706 vector<boost::weak_ptr<Region> > v;
2707 boost::shared_ptr<Region> first_r;
2709 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2711 boost::shared_ptr<Region> region = *ii;
2715 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2718 v.push_back (region);
2725 region->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region)));
2726 update_region_name_map (region);
2730 RegionsAdded (v); /* EMIT SIGNAL */
2736 Session::update_region_name_map (boost::shared_ptr<Region> region)
2738 string::size_type last_period = region->name().find_last_of ('.');
2740 if (last_period != string::npos && last_period < region->name().length() - 1) {
2742 string base = region->name().substr (0, last_period);
2743 string number = region->name().substr (last_period+1);
2744 map<string,uint32_t>::iterator x;
2746 /* note that if there is no number, we get zero from atoi,
2750 region_name_map[base] = atoi (number);
2755 Session::region_changed (const PropertyChange& what_changed, boost::weak_ptr<Region> weak_region)
2757 boost::shared_ptr<Region> region (weak_region.lock ());
2763 if (what_changed.contains (Properties::hidden)) {
2764 /* relay hidden changes */
2765 RegionHiddenChange (region);
2768 if (what_changed.contains (Properties::name)) {
2769 update_region_name_map (region);
2774 Session::remove_region (boost::weak_ptr<Region> weak_region)
2776 RegionList::iterator i;
2777 boost::shared_ptr<Region> region (weak_region.lock ());
2783 bool removed = false;
2786 Glib::Mutex::Lock lm (region_lock);
2788 if ((i = regions.find (region->id())) != regions.end()) {
2794 /* mark dirty because something has changed even if we didn't
2795 remove the region from the region list.
2801 RegionRemoved(region); /* EMIT SIGNAL */
2805 boost::shared_ptr<Region>
2806 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2808 RegionList::iterator i;
2809 boost::shared_ptr<Region> region;
2811 Glib::Mutex::Lock lm (region_lock);
2813 for (i = regions.begin(); i != regions.end(); ++i) {
2817 if (region->whole_file()) {
2819 if (child->source_equivalent (region)) {
2825 return boost::shared_ptr<Region> ();
2829 Session::destroy_region (boost::shared_ptr<Region> region)
2831 vector<boost::shared_ptr<Source> > srcs;
2834 if (region->playlist()) {
2835 region->playlist()->destroy_region (region);
2838 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2839 srcs.push_back (region->source (n));
2843 region->drop_references ();
2845 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2847 (*i)->mark_for_remove ();
2848 (*i)->drop_references ();
2850 cerr << "source was not used by any playlist\n";
2857 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2859 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2860 destroy_region (*i);
2866 Session::remove_last_capture ()
2868 list<boost::shared_ptr<Region> > r;
2870 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2872 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2873 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2876 r.insert (r.end(), l.begin(), l.end());
2881 for (list<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
2885 destroy_regions (r);
2887 save_state (_current_snapshot_name);
2893 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2899 /* Source Management */
2902 Session::add_source (boost::shared_ptr<Source> source)
2904 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2905 pair<SourceMap::iterator,bool> result;
2907 entry.first = source->id();
2908 entry.second = source;
2911 Glib::Mutex::Lock lm (source_lock);
2912 result = sources.insert (entry);
2915 if (result.second) {
2919 boost::shared_ptr<AudioFileSource> afs;
2921 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2922 if (Config->get_auto_analyse_audio()) {
2923 Analyser::queue_source_for_analysis (source, false);
2929 Session::remove_source (boost::weak_ptr<Source> src)
2931 SourceMap::iterator i;
2932 boost::shared_ptr<Source> source = src.lock();
2939 Glib::Mutex::Lock lm (source_lock);
2941 if ((i = sources.find (source->id())) != sources.end()) {
2946 if (!_state_of_the_state & InCleanup) {
2948 /* save state so we don't end up with a session file
2949 referring to non-existent sources.
2952 save_state (_current_snapshot_name);
2956 boost::shared_ptr<Source>
2957 Session::source_by_id (const PBD::ID& id)
2959 Glib::Mutex::Lock lm (source_lock);
2960 SourceMap::iterator i;
2961 boost::shared_ptr<Source> source;
2963 if ((i = sources.find (id)) != sources.end()) {
2970 boost::shared_ptr<Source>
2971 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2973 Glib::Mutex::Lock lm (source_lock);
2975 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2976 cerr << "comparing " << path << " with " << i->second->name() << endl;
2977 boost::shared_ptr<AudioFileSource> afs
2978 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2980 if (afs && afs->path() == path && chn == afs->channel()) {
2984 return boost::shared_ptr<Source>();
2989 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2992 string old_basename = PBD::basename_nosuffix (oldname);
2993 string new_legalized = legalize_for_path (newname);
2995 /* note: we know (or assume) the old path is already valid */
2999 /* destructive file sources have a name of the form:
3001 /path/to/Tnnnn-NAME(%[LR])?.wav
3003 the task here is to replace NAME with the new name.
3006 /* find last slash */
3010 string::size_type slash;
3011 string::size_type dash;
3013 if ((slash = path.find_last_of ('/')) == string::npos) {
3017 dir = path.substr (0, slash+1);
3019 /* '-' is not a legal character for the NAME part of the path */
3021 if ((dash = path.find_last_of ('-')) == string::npos) {
3025 prefix = path.substr (slash+1, dash-(slash+1));
3030 path += new_legalized;
3031 path += ".wav"; /* XXX gag me with a spoon */
3035 /* non-destructive file sources have a name of the form:
3037 /path/to/NAME-nnnnn(%[LR])?.ext
3039 the task here is to replace NAME with the new name.
3044 string::size_type slash;
3045 string::size_type dash;
3046 string::size_type postfix;
3048 /* find last slash */
3050 if ((slash = path.find_last_of ('/')) == string::npos) {
3054 dir = path.substr (0, slash+1);
3056 /* '-' is not a legal character for the NAME part of the path */
3058 if ((dash = path.find_last_of ('-')) == string::npos) {
3062 suffix = path.substr (dash+1);
3064 // Suffix is now everything after the dash. Now we need to eliminate
3065 // the nnnnn part, which is done by either finding a '%' or a '.'
3067 postfix = suffix.find_last_of ("%");
3068 if (postfix == string::npos) {
3069 postfix = suffix.find_last_of ('.');
3072 if (postfix != string::npos) {
3073 suffix = suffix.substr (postfix);
3075 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3079 const uint32_t limit = 10000;
3080 char buf[PATH_MAX+1];
3082 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3084 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3086 if (access (buf, F_OK) != 0) {
3094 error << "FATAL ERROR! Could not find a " << endl;
3102 /** Return the full path (in some session directory) for a new within-session source.
3103 * \a name must be a session-unique name that does not contain slashes
3104 * (e.g. as returned by new_*_source_name)
3107 Session::new_source_path_from_name (DataType type, const string& name)
3109 assert(name.find("/") == string::npos);
3111 SessionDirectory sdir(get_best_session_directory_for_new_source());
3114 if (type == DataType::AUDIO) {
3115 p = sdir.sound_path();
3116 } else if (type == DataType::MIDI) {
3117 p = sdir.midi_path();
3119 error << "Unknown source type, unable to create file path" << endmsg;
3124 return p.to_string();
3128 Session::peak_path (Glib::ustring base) const
3130 sys::path peakfile_path(_session_dir->peak_path());
3131 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3132 return peakfile_path.to_string();
3135 /** Return a unique name based on \a base for a new internal audio source */
3137 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3141 char buf[PATH_MAX+1];
3142 const uint32_t limit = 10000;
3146 legalized = legalize_for_path (base);
3148 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3149 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3151 vector<space_and_path>::iterator i;
3152 uint32_t existing = 0;
3154 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3156 SessionDirectory sdir((*i).path);
3158 spath = sdir.sound_path().to_string();
3163 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3164 spath.c_str(), cnt, legalized.c_str());
3165 } else if (nchan == 2) {
3167 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3168 spath.c_str(), cnt, legalized.c_str());
3170 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3171 spath.c_str(), cnt, legalized.c_str());
3173 } else if (nchan < 26) {
3174 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3175 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3177 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3178 spath.c_str(), cnt, legalized.c_str());
3187 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3188 } else if (nchan == 2) {
3190 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3192 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3194 } else if (nchan < 26) {
3195 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3197 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3201 if (sys::exists(buf)) {
3207 if (existing == 0) {
3212 error << string_compose(
3213 _("There are already %1 recordings for %2, which I consider too many."),
3214 limit, base) << endmsg;
3216 throw failed_constructor();
3220 return Glib::path_get_basename(buf);
3223 /** Create a new within-session audio source */
3224 boost::shared_ptr<AudioFileSource>
3225 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3227 const size_t n_chans = ds.n_channels().n_audio();
3228 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3229 const string path = new_source_path_from_name(DataType::AUDIO, name);
3231 return boost::dynamic_pointer_cast<AudioFileSource> (
3232 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3235 /** Return a unique name based on \a base for a new internal MIDI source */
3237 Session::new_midi_source_name (const string& base)
3240 char buf[PATH_MAX+1];
3241 const uint32_t limit = 10000;
3245 legalized = legalize_for_path (base);
3247 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3248 for (cnt = 1; cnt <= limit; ++cnt) {
3250 vector<space_and_path>::iterator i;
3251 uint32_t existing = 0;
3253 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3255 SessionDirectory sdir((*i).path);
3257 sys::path p = sdir.midi_path();
3260 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3262 if (sys::exists (buf)) {
3267 if (existing == 0) {
3272 error << string_compose(
3273 _("There are already %1 recordings for %2, which I consider too many."),
3274 limit, base) << endmsg;
3276 throw failed_constructor();
3280 return Glib::path_get_basename(buf);
3284 /** Create a new within-session MIDI source */
3285 boost::shared_ptr<MidiSource>
3286 Session::create_midi_source_for_session (MidiDiskstream& ds)
3288 const string name = new_midi_source_name (ds.name());
3289 const string path = new_source_path_from_name (DataType::MIDI, name);
3291 return boost::dynamic_pointer_cast<SMFSource> (
3292 SourceFactory::createWritable (
3293 DataType::MIDI, *this, path, false, frame_rate()));
3298 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3300 if (playlist->hidden()) {
3304 playlists->add (playlist);
3307 playlist->release();
3314 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3316 if (_state_of_the_state & Deletion) {
3320 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3326 playlists->remove (playlist);
3332 Session::set_audition (boost::shared_ptr<Region> r)
3334 pending_audition_region = r;
3335 add_post_transport_work (PostTransportAudition);
3336 _butler->schedule_transport_work ();
3340 Session::audition_playlist ()
3342 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3343 ev->region.reset ();
3348 Session::non_realtime_set_audition ()
3350 if (!pending_audition_region) {
3351 auditioner->audition_current_playlist ();
3353 auditioner->audition_region (pending_audition_region);
3354 pending_audition_region.reset ();
3356 AuditionActive (true); /* EMIT SIGNAL */
3360 Session::audition_region (boost::shared_ptr<Region> r)
3362 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3368 Session::cancel_audition ()
3370 if (auditioner->active()) {
3371 auditioner->cancel_audition ();
3372 AuditionActive (false); /* EMIT SIGNAL */
3377 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3379 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3383 Session::remove_empty_sounds ()
3385 vector<string> audio_filenames;
3387 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3389 Glib::Mutex::Lock lm (source_lock);
3391 TapeFileMatcher tape_file_matcher;
3393 remove_if (audio_filenames.begin(), audio_filenames.end(),
3394 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3396 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3398 sys::path audio_file_path (_session_dir->sound_path());
3400 audio_file_path /= *i;
3402 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3406 sys::remove (audio_file_path);
3407 const string peakfile = peak_path (audio_file_path.to_string());
3408 sys::remove (peakfile);
3410 catch (const sys::filesystem_error& err)
3412 error << err.what() << endmsg;
3419 Session::is_auditioning () const
3421 /* can be called before we have an auditioner object */
3423 return auditioner->active();
3430 Session::n_diskstreams () const
3434 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3436 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3437 if (!(*i)->hidden()) {
3445 Session::graph_reordered ()
3447 /* don't do this stuff if we are setting up connections
3448 from a set_state() call or creating new tracks. Ditto for deletion.
3451 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3455 /* every track/bus asked for this to be handled but it was deferred because
3456 we were connecting. do it now.
3459 request_input_change_handling ();
3463 /* force all diskstreams to update their capture offset values to
3464 reflect any changes in latencies within the graph.
3467 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3469 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3470 (*i)->set_capture_offset ();
3475 Session::add_processor (Processor* processor)
3477 /* Session does not own Processors (they belong to a Route) but we do want to track
3478 the arrival and departure of port inserts, sends and returns for naming
3481 processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
3486 Session::remove_processor (Processor* processor)
3490 PortInsert* port_insert;
3492 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3493 insert_bitset[port_insert->bit_slot()] = false;
3494 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3495 send_bitset[send->bit_slot()] = false;
3496 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3497 return_bitset[retrn->bit_slot()] = false;
3504 Session::available_capture_duration ()
3506 float sample_bytes_on_disk = 4.0; // keep gcc happy
3508 switch (config.get_native_file_data_format()) {
3510 sample_bytes_on_disk = 4.0;
3514 sample_bytes_on_disk = 3.0;
3518 sample_bytes_on_disk = 2.0;
3522 /* impossible, but keep some gcc versions happy */
3523 fatal << string_compose (_("programming error: %1"),
3524 X_("illegal native file data format"))
3529 double scale = 4096.0 / sample_bytes_on_disk;
3531 if (_total_free_4k_blocks * scale > (double) max_frames) {
3535 return (nframes_t) floor (_total_free_4k_blocks * scale);
3539 Session::add_bundle (shared_ptr<Bundle> bundle)
3542 RCUWriter<BundleList> writer (_bundles);
3543 boost::shared_ptr<BundleList> b = writer.get_copy ();
3544 b->push_back (bundle);
3547 BundleAdded (bundle); /* EMIT SIGNAL */
3553 Session::remove_bundle (shared_ptr<Bundle> bundle)
3555 bool removed = false;
3558 RCUWriter<BundleList> writer (_bundles);
3559 boost::shared_ptr<BundleList> b = writer.get_copy ();
3560 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3562 if (i != b->end()) {
3569 BundleRemoved (bundle); /* EMIT SIGNAL */
3576 Session::bundle_by_name (string name) const
3578 boost::shared_ptr<BundleList> b = _bundles.reader ();
3580 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3581 if ((*i)->name() == name) {
3586 return boost::shared_ptr<Bundle> ();
3590 Session::tempo_map_changed (const PropertyChange&)
3594 playlists->update_after_tempo_map_change ();
3599 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3600 * the given count with the current block size.
3603 Session::ensure_buffers (ChanCount howmany)
3605 if (current_block_size == 0) {
3606 return; // too early? (is this ok?)
3609 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3610 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3611 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3612 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3613 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3616 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3620 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3622 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3623 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3628 Session::next_insert_id ()
3630 /* this doesn't really loop forever. just think about it */
3633 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3634 if (!insert_bitset[n]) {
3635 insert_bitset[n] = true;
3641 /* none available, so resize and try again */
3643 insert_bitset.resize (insert_bitset.size() + 16, false);
3648 Session::next_send_id ()
3650 /* this doesn't really loop forever. just think about it */
3653 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3654 if (!send_bitset[n]) {
3655 send_bitset[n] = true;
3661 /* none available, so resize and try again */
3663 send_bitset.resize (send_bitset.size() + 16, false);
3668 Session::next_return_id ()
3670 /* this doesn't really loop forever. just think about it */
3673 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3674 if (!return_bitset[n]) {
3675 return_bitset[n] = true;
3681 /* none available, so resize and try again */
3683 return_bitset.resize (return_bitset.size() + 16, false);
3688 Session::mark_send_id (uint32_t id)
3690 if (id >= send_bitset.size()) {
3691 send_bitset.resize (id+16, false);
3693 if (send_bitset[id]) {
3694 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3696 send_bitset[id] = true;
3700 Session::mark_return_id (uint32_t id)
3702 if (id >= return_bitset.size()) {
3703 return_bitset.resize (id+16, false);
3705 if (return_bitset[id]) {
3706 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3708 return_bitset[id] = true;
3712 Session::mark_insert_id (uint32_t id)
3714 if (id >= insert_bitset.size()) {
3715 insert_bitset.resize (id+16, false);
3717 if (insert_bitset[id]) {
3718 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3720 insert_bitset[id] = true;
3723 /* Named Selection management */
3725 boost::shared_ptr<NamedSelection>
3726 Session::named_selection_by_name (string name)
3728 Glib::Mutex::Lock lm (named_selection_lock);
3729 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3730 if ((*i)->name == name) {
3734 return boost::shared_ptr<NamedSelection>();
3738 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3741 Glib::Mutex::Lock lm (named_selection_lock);
3742 named_selections.insert (named_selections.begin(), named_selection);
3747 NamedSelectionAdded (); /* EMIT SIGNAL */
3751 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3753 bool removed = false;
3756 Glib::Mutex::Lock lm (named_selection_lock);
3758 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3760 if (i != named_selections.end()) {
3761 named_selections.erase (i);
3768 NamedSelectionRemoved (); /* EMIT SIGNAL */
3773 Session::reset_native_file_format ()
3775 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3777 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3778 (*i)->reset_write_sources (false);
3783 Session::route_name_unique (string n) const
3785 shared_ptr<RouteList> r = routes.reader ();
3787 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3788 if ((*i)->name() == n) {
3797 Session::route_name_internal (string n) const
3799 if (auditioner && auditioner->name() == n) {
3803 if (_click_io && _click_io->name() == n) {
3811 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3813 if (!force && howmany <= _npan_buffers) {
3817 if (_pan_automation_buffer) {
3819 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3820 delete [] _pan_automation_buffer[i];
3823 delete [] _pan_automation_buffer;
3826 _pan_automation_buffer = new pan_t*[howmany];
3828 for (uint32_t i = 0; i < howmany; ++i) {
3829 _pan_automation_buffer[i] = new pan_t[nframes];
3832 _npan_buffers = howmany;
3836 Session::freeze (InterThreadInfo& itt)
3838 shared_ptr<RouteList> r = routes.reader ();
3840 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3842 boost::shared_ptr<Track> t;
3844 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3845 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3855 boost::shared_ptr<Region>
3856 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3857 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3858 InterThreadInfo& itt, bool enable_processing)
3860 boost::shared_ptr<Region> result;
3861 boost::shared_ptr<Playlist> playlist;
3862 boost::shared_ptr<AudioFileSource> fsource;
3864 char buf[PATH_MAX+1];
3865 ChanCount nchans(track.audio_diskstream()->n_channels());
3867 nframes_t this_chunk;
3870 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3871 const string sound_dir = sdir.sound_path().to_string();
3872 nframes_t len = end - start;
3875 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3876 end, start) << endmsg;
3880 const nframes_t chunk_size = (256 * 1024)/4;
3882 // block all process callback handling
3884 block_processing ();
3886 /* call tree *MUST* hold route_lock */
3888 if ((playlist = track.diskstream()->playlist()) == 0) {
3892 /* external redirects will be a problem */
3894 if (track.has_external_redirects()) {
3898 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3900 for (x = 0; x < 99999; ++x) {
3901 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3902 if (access (buf, F_OK) != 0) {
3908 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3913 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3914 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3917 catch (failed_constructor& err) {
3918 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3922 srcs.push_back (fsource);
3925 /* XXX need to flush all redirects */
3930 /* create a set of reasonably-sized buffers */
3931 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3932 buffers.set_count(nchans);
3934 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3935 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3937 afs->prepare_for_peakfile_writes ();
3940 while (to_do && !itt.cancel) {
3942 this_chunk = min (to_do, chunk_size);
3944 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3949 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3950 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3953 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3959 start += this_chunk;
3960 to_do -= this_chunk;
3962 itt.progress = (float) (1.0 - ((double) to_do / len));
3971 xnow = localtime (&now);
3973 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3974 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3977 afs->update_header (position, *xnow, now);
3978 afs->flush_header ();
3982 /* construct a region to represent the bounced material */
3986 plist.add (Properties::start, 0);
3987 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3988 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3990 result = RegionFactory::create (srcs, plist);
3996 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3997 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4000 afs->mark_for_remove ();
4003 (*src)->drop_references ();
4007 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4008 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4011 afs->done_with_peakfile_writes ();
4015 unblock_processing ();
4021 Session::get_silent_buffers (ChanCount count)
4023 assert(_silent_buffers->available() >= count);
4024 _silent_buffers->set_count(count);
4026 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4027 for (size_t i= 0; i < count.get(*t); ++i) {
4028 _silent_buffers->get(*t, i).clear();
4032 return *_silent_buffers;
4036 Session::get_scratch_buffers (ChanCount count)
4038 if (count != ChanCount::ZERO) {
4039 assert(_scratch_buffers->available() >= count);
4040 _scratch_buffers->set_count(count);
4042 _scratch_buffers->set_count (_scratch_buffers->available());
4045 return *_scratch_buffers;
4049 Session::get_mix_buffers (ChanCount count)
4051 assert(_mix_buffers->available() >= count);
4052 _mix_buffers->set_count(count);
4053 return *_mix_buffers;
4057 Session::ntracks () const
4060 shared_ptr<RouteList> r = routes.reader ();
4062 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4063 if (boost::dynamic_pointer_cast<Track> (*i)) {
4072 Session::nbusses () const
4075 shared_ptr<RouteList> r = routes.reader ();
4077 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4078 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4087 Session::add_automation_list(AutomationList *al)
4089 automation_lists[al->id()] = al;
4093 Session::compute_initial_length ()
4095 return _engine.frame_rate() * 60 * 5;
4099 Session::sync_order_keys (std::string const & base)
4101 if (deletion_in_progress()) {
4105 if (!Config->get_sync_all_route_ordering()) {
4106 /* leave order keys as they are */
4110 boost::shared_ptr<RouteList> r = routes.reader ();
4112 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4113 (*i)->sync_order_keys (base);
4116 Route::SyncOrderKeys (base); // EMIT SIGNAL
4118 /* this might not do anything */
4120 set_remote_control_ids ();
4123 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4125 Session::have_rec_enabled_diskstream () const
4127 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4130 /** Update the state of our rec-enabled diskstreams flag */
4132 Session::update_have_rec_enabled_diskstream ()
4134 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4135 DiskstreamList::iterator i = dsl->begin ();
4136 while (i != dsl->end () && (*i)->record_enabled () == false) {
4140 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4142 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4144 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4145 RecordStateChanged (); /* EMIT SIGNAL */
4150 Session::listen_position_changed ()
4154 switch (Config->get_listen_position()) {
4155 case AfterFaderListen:
4159 case PreFaderListen:
4164 boost::shared_ptr<RouteList> r = routes.reader ();
4166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4167 (*i)->put_control_outs_at (p);
4172 Session::solo_control_mode_changed ()
4174 /* cancel all solo or all listen when solo control mode changes */
4176 if (Config->get_solo_control_is_listen_control()) {
4177 set_solo (routes.reader(), false);
4179 set_listen (routes.reader(), false);
4184 Session::route_group_changed ()
4186 RouteGroupChanged (); /* EMIT SIGNAL */
4190 Session::get_available_sync_options () const
4192 vector<SyncSource> ret;
4194 ret.push_back (JACK);
4197 ret.push_back (MTC);
4200 if (midi_clock_port()) {
4201 ret.push_back (MIDIClock);
4207 boost::shared_ptr<RouteList>
4208 Session::get_routes_with_regions_at (nframes64_t const p) const
4210 shared_ptr<RouteList> r = routes.reader ();
4211 shared_ptr<RouteList> rl (new RouteList);
4213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4214 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4219 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4224 boost::shared_ptr<Playlist> pl = ds->playlist ();
4229 if (pl->has_region_at (p)) {