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 */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
44 #include <pbd/file_utils.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/session_directory.h>
50 #include <ardour/session_metadata.h>
51 #include <ardour/utils.h>
52 #include <ardour/audio_diskstream.h>
53 #include <ardour/audioplaylist.h>
54 #include <ardour/audioregion.h>
55 #include <ardour/audiofilesource.h>
56 #include <ardour/midi_diskstream.h>
57 #include <ardour/midi_playlist.h>
58 #include <ardour/midi_region.h>
59 #include <ardour/smf_source.h>
60 #include <ardour/auditioner.h>
61 #include <ardour/recent_sessions.h>
62 #include <ardour/io_processor.h>
63 #include <ardour/send.h>
64 #include <ardour/processor.h>
65 #include <ardour/plugin_insert.h>
66 #include <ardour/port_insert.h>
67 #include <ardour/auto_bundle.h>
68 #include <ardour/slave.h>
69 #include <ardour/tempo.h>
70 #include <ardour/audio_track.h>
71 #include <ardour/midi_track.h>
72 #include <ardour/cycle_timer.h>
73 #include <ardour/named_selection.h>
74 #include <ardour/crossfade.h>
75 #include <ardour/playlist.h>
76 #include <ardour/click.h>
77 #include <ardour/data_type.h>
78 #include <ardour/buffer_set.h>
79 #include <ardour/source_factory.h>
80 #include <ardour/region_factory.h>
81 #include <ardour/filename_extensions.h>
82 #include <ardour/session_directory.h>
83 #include <ardour/tape_file_matcher.h>
84 #include <ardour/analyser.h>
87 #include <ardour/osc.h>
93 using namespace ARDOUR;
95 using boost::shared_ptr;
98 static const int CPU_CACHE_ALIGN = 64;
100 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
103 bool Session::_disable_all_loaded_plugins = false;
105 Session::compute_peak_t Session::compute_peak = 0;
106 Session::find_peaks_t Session::find_peaks = 0;
107 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
108 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
109 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
111 sigc::signal<void,std::string> Session::Dialog;
112 sigc::signal<int> Session::AskAboutPendingState;
113 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
114 sigc::signal<void> Session::SendFeedback;
116 sigc::signal<void> Session::SMPTEOffsetChanged;
117 sigc::signal<void> Session::StartTimeChanged;
118 sigc::signal<void> Session::EndTimeChanged;
119 sigc::signal<void> Session::AutoBindingOn;
120 sigc::signal<void> Session::AutoBindingOff;
121 sigc::signal<void, std::string, std::string> Session::Exported;
123 Session::Session (AudioEngine &eng,
124 const string& fullpath,
125 const string& snapshot_name,
129 _scratch_buffers(new BufferSet()),
130 _silent_buffers(new BufferSet()),
131 _mix_buffers(new BufferSet()),
132 _mmc_port (default_mmc_port),
133 _mtc_port (default_mtc_port),
134 _midi_port (default_midi_port),
135 _midi_clock_port (default_midi_clock_port),
136 _session_dir (new SessionDirectory(fullpath)),
137 pending_events (2048),
138 post_transport_work((PostTransportWork)0),
139 _send_smpte_update (false),
141 diskstreams (new DiskstreamList),
142 routes (new RouteList),
143 auditioner ((Auditioner*) 0),
144 _total_free_4k_blocks (0),
145 _bundle_xml_node (0),
148 _metadata (new SessionMetadata())
152 if (!eng.connected()) {
153 throw failed_constructor();
156 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
158 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
159 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
161 first_stage_init (fullpath, snapshot_name);
163 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
166 if (create (new_session, mix_template, compute_initial_length())) {
168 throw failed_constructor ();
172 if (second_stage_init (new_session)) {
174 throw failed_constructor ();
177 store_recent_sessions(_name, _path);
179 bool was_dirty = dirty();
181 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
183 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
186 DirtyChanged (); /* EMIT SIGNAL */
190 Session::Session (AudioEngine &eng,
192 string snapshot_name,
193 AutoConnectOption input_ac,
194 AutoConnectOption output_ac,
195 uint32_t control_out_channels,
196 uint32_t master_out_channels,
197 uint32_t requested_physical_in,
198 uint32_t requested_physical_out,
199 nframes_t initial_length)
202 _scratch_buffers(new BufferSet()),
203 _silent_buffers(new BufferSet()),
204 _mix_buffers(new BufferSet()),
205 _mmc_port (default_mmc_port),
206 _mtc_port (default_mtc_port),
207 _midi_port (default_midi_port),
208 _midi_clock_port (default_midi_clock_port),
209 _session_dir ( new SessionDirectory(fullpath)),
210 pending_events (2048),
211 post_transport_work((PostTransportWork)0),
212 _send_smpte_update (false),
214 diskstreams (new DiskstreamList),
215 routes (new RouteList),
216 _total_free_4k_blocks (0),
217 _bundle_xml_node (0),
223 if (!eng.connected()) {
224 throw failed_constructor();
227 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
229 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
230 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
232 if (n_physical_inputs) {
233 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
236 if (n_physical_outputs) {
237 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
240 first_stage_init (fullpath, snapshot_name);
242 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
245 if (create (new_session, string(), initial_length)) {
247 throw failed_constructor ();
252 /* set up Master Out and Control Out if necessary */
257 if (control_out_channels) {
258 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
259 r->set_remote_control_id (control_id++);
264 if (master_out_channels) {
265 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
266 r->set_remote_control_id (control_id);
270 /* prohibit auto-connect to master, because there isn't one */
271 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
275 add_routes (rl, false);
280 Config->set_input_auto_connect (input_ac);
281 Config->set_output_auto_connect (output_ac);
283 if (second_stage_init (new_session)) {
285 throw failed_constructor ();
288 store_recent_sessions (_name, _path);
290 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
292 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
303 /* if we got to here, leaving pending capture state around
307 remove_pending_capture_state ();
309 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
311 _engine.remove_session ();
313 GoingAway (); /* EMIT SIGNAL */
319 /* clear history so that no references to objects are held any more */
323 /* clear state tree so that no references to objects are held any more */
329 terminate_butler_thread ();
330 //terminate_midi_thread ();
332 if (click_data && click_data != default_click) {
333 delete [] click_data;
336 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
337 delete [] click_emphasis_data;
342 delete _scratch_buffers;
343 delete _silent_buffers;
346 AudioDiskstream::free_working_buffers();
348 Route::SyncOrderKeys.clear();
350 #undef TRACK_DESTRUCTION
351 #ifdef TRACK_DESTRUCTION
352 cerr << "delete named selections\n";
353 #endif /* TRACK_DESTRUCTION */
354 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
355 NamedSelectionList::iterator tmp;
364 #ifdef TRACK_DESTRUCTION
365 cerr << "delete playlists\n";
366 #endif /* TRACK_DESTRUCTION */
367 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
368 PlaylistList::iterator tmp;
373 (*i)->drop_references ();
378 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
379 PlaylistList::iterator tmp;
384 (*i)->drop_references ();
390 unused_playlists.clear ();
392 #ifdef TRACK_DESTRUCTION
393 cerr << "delete regions\n";
394 #endif /* TRACK_DESTRUCTION */
396 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
397 RegionList::iterator tmp;
402 i->second->drop_references ();
409 #ifdef TRACK_DESTRUCTION
410 cerr << "delete routes\n";
411 #endif /* TRACK_DESTRUCTION */
413 RCUWriter<RouteList> writer (routes);
414 boost::shared_ptr<RouteList> r = writer.get_copy ();
415 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
416 (*i)->drop_references ();
419 /* writer goes out of scope and updates master */
424 #ifdef TRACK_DESTRUCTION
425 cerr << "delete diskstreams\n";
426 #endif /* TRACK_DESTRUCTION */
428 RCUWriter<DiskstreamList> dwriter (diskstreams);
429 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
431 (*i)->drop_references ();
435 diskstreams.flush ();
437 #ifdef TRACK_DESTRUCTION
438 cerr << "delete audio sources\n";
439 #endif /* TRACK_DESTRUCTION */
440 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
441 SourceMap::iterator tmp;
446 i->second->drop_references ();
452 #ifdef TRACK_DESTRUCTION
453 cerr << "delete mix groups\n";
454 #endif /* TRACK_DESTRUCTION */
455 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
456 list<RouteGroup*>::iterator tmp;
466 #ifdef TRACK_DESTRUCTION
467 cerr << "delete edit groups\n";
468 #endif /* TRACK_DESTRUCTION */
469 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
470 list<RouteGroup*>::iterator tmp;
480 if (butler_mixdown_buffer) {
481 delete [] butler_mixdown_buffer;
484 if (butler_gain_buffer) {
485 delete [] butler_gain_buffer;
488 Crossfade::set_buffer_size (0);
496 Session::set_worst_io_latencies ()
498 _worst_output_latency = 0;
499 _worst_input_latency = 0;
501 if (!_engine.connected()) {
505 boost::shared_ptr<RouteList> r = routes.reader ();
507 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
508 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
509 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
514 Session::when_engine_running ()
516 string first_physical_output;
518 /* we don't want to run execute this again */
520 BootMessage (_("Set block size and sample rate"));
522 set_block_size (_engine.frames_per_cycle());
523 set_frame_rate (_engine.frame_rate());
525 BootMessage (_("Using configuration"));
527 Config->map_parameters (mem_fun (*this, &Session::config_changed));
529 /* every time we reconnect, recompute worst case output latencies */
531 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
533 if (synced_to_jack()) {
534 _engine.transport_stop ();
537 if (Config->get_jack_time_master()) {
538 _engine.transport_locate (_transport_frame);
546 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
548 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
550 /* existing state for Click */
552 if (_click_io->set_state (*child->children().front()) == 0) {
554 _clicking = Config->get_clicking ();
558 error << _("could not setup Click I/O") << endmsg;
564 /* default state for Click */
566 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
568 if (first_physical_output.length()) {
569 if (_click_io->add_output_port (first_physical_output, this)) {
570 // relax, even though its an error
572 _clicking = Config->get_clicking ();
578 catch (failed_constructor& err) {
579 error << _("cannot setup Click I/O") << endmsg;
582 BootMessage (_("Compute I/O Latencies"));
584 set_worst_io_latencies ();
587 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
590 /* Create a set of Bundle objects that map
591 to the physical outputs currently available
594 BootMessage (_("Set up standard connections"));
598 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
600 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
602 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
604 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
609 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
611 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
613 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
615 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
622 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
624 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
626 shared_ptr<AutoBundle> c (new AutoBundle (buf, true));
628 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
629 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
634 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
636 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
638 shared_ptr<AutoBundle> c (new AutoBundle (buf, false));
640 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
641 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
650 /* create master/control ports */
655 /* force the master to ignore any later call to this */
657 if (_master_out->pending_state_node) {
658 _master_out->ports_became_legal();
661 /* no panner resets till we are through */
663 _master_out->defer_pan_reset ();
665 while (_master_out->n_inputs().n_audio()
666 < _master_out->input_maximum().n_audio()) {
667 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
668 error << _("cannot setup master inputs")
674 while (_master_out->n_outputs().n_audio()
675 < _master_out->output_maximum().n_audio()) {
676 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
677 error << _("cannot setup master outputs")
684 _master_out->allow_pan_reset ();
688 shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true));
690 c->set_channels (_master_out->n_inputs().n_total());
691 for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) {
692 c->set_port (n, _master_out->input(n)->name());
697 BootMessage (_("Setup signal flow and plugins"));
701 /* catch up on send+insert cnts */
703 BootMessage (_("Catch up with send/insert state"));
707 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
710 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
711 if (id > insert_cnt) {
719 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
722 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
730 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
732 /* hook us up to the engine */
734 BootMessage (_("Connect to engine"));
736 _engine.set_session (this);
741 BootMessage (_("OSC startup"));
743 osc->set_session (*this);
749 Session::hookup_io ()
751 /* stop graph reordering notifications from
752 causing resorts, etc.
755 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
758 if (auditioner == 0) {
760 /* we delay creating the auditioner till now because
761 it makes its own connections to ports.
762 the engine has to be running for this to work.
766 auditioner.reset (new Auditioner (*this));
769 catch (failed_constructor& err) {
770 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
774 /* Tell all IO objects to create their ports */
780 vector<string> cports;
782 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
783 if (_control_out->add_input_port ("", this)) {
784 error << _("cannot setup control inputs")
790 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
791 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
792 error << _("cannot set up master outputs")
800 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
802 for (n = 0; n < ni; ++n) {
803 cports.push_back (_control_out->input(n)->name());
806 boost::shared_ptr<RouteList> r = routes.reader ();
808 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
809 (*x)->set_control_outs (cports);
813 /* load bundles, which we may have postponed earlier on */
814 if (_bundle_xml_node) {
815 load_bundles (*_bundle_xml_node);
816 delete _bundle_xml_node;
819 /* Tell all IO objects to connect themselves together */
821 IO::enable_connecting ();
823 /* Now reset all panners */
825 IO::reset_panners ();
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);
834 /* now handle the whole enchilada as if it was one
840 /* update mixer solo state */
846 Session::playlist_length_changed ()
848 /* we can't just increase end_location->end() if pl->get_maximum_extent()
849 if larger. if the playlist used to be the longest playlist,
850 and its now shorter, we have to decrease end_location->end(). hence,
851 we have to iterate over all diskstreams and check the
852 playlists currently in use.
858 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
860 boost::shared_ptr<Playlist> playlist;
862 if ((playlist = dstream->playlist()) != 0) {
863 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
866 /* see comment in playlist_length_changed () */
871 Session::record_enabling_legal () const
873 /* this used to be in here, but survey says.... we don't need to restrict it */
874 // if (record_status() == Recording) {
878 if (Config->get_all_safe()) {
885 Session::reset_input_monitor_state ()
887 if (transport_rolling()) {
889 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
891 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
892 if ((*i)->record_enabled ()) {
893 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
894 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
898 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
900 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
901 if ((*i)->record_enabled ()) {
902 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
903 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
910 Session::auto_punch_start_changed (Location* location)
912 replace_event (Event::PunchIn, location->start());
914 if (get_record_enabled() && Config->get_punch_in()) {
915 /* capture start has been changed, so save new pending state */
916 save_state ("", true);
921 Session::auto_punch_end_changed (Location* location)
923 nframes_t when_to_stop = location->end();
924 // when_to_stop += _worst_output_latency + _worst_input_latency;
925 replace_event (Event::PunchOut, when_to_stop);
929 Session::auto_punch_changed (Location* location)
931 nframes_t when_to_stop = location->end();
933 replace_event (Event::PunchIn, location->start());
934 //when_to_stop += _worst_output_latency + _worst_input_latency;
935 replace_event (Event::PunchOut, when_to_stop);
939 Session::auto_loop_changed (Location* location)
941 replace_event (Event::AutoLoop, location->end(), location->start());
943 if (transport_rolling() && play_loop) {
945 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
947 if (_transport_frame > location->end()) {
948 // relocate to beginning of loop
949 clear_events (Event::LocateRoll);
951 request_locate (location->start(), true);
954 else if (Config->get_seamless_loop() && !loop_changing) {
956 // schedule a locate-roll to refill the diskstreams at the
958 loop_changing = true;
960 if (location->end() > last_loopend) {
961 clear_events (Event::LocateRoll);
962 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
969 last_loopend = location->end();
973 Session::set_auto_punch_location (Location* location)
977 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
978 auto_punch_start_changed_connection.disconnect();
979 auto_punch_end_changed_connection.disconnect();
980 auto_punch_changed_connection.disconnect();
981 existing->set_auto_punch (false, this);
982 remove_event (existing->start(), Event::PunchIn);
983 clear_events (Event::PunchOut);
984 auto_punch_location_changed (0);
993 if (location->end() <= location->start()) {
994 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
998 auto_punch_start_changed_connection.disconnect();
999 auto_punch_end_changed_connection.disconnect();
1000 auto_punch_changed_connection.disconnect();
1002 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1003 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1004 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1006 location->set_auto_punch (true, this);
1009 auto_punch_changed (location);
1011 auto_punch_location_changed (location);
1015 Session::set_auto_loop_location (Location* location)
1019 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1020 auto_loop_start_changed_connection.disconnect();
1021 auto_loop_end_changed_connection.disconnect();
1022 auto_loop_changed_connection.disconnect();
1023 existing->set_auto_loop (false, this);
1024 remove_event (existing->end(), Event::AutoLoop);
1025 auto_loop_location_changed (0);
1030 if (location == 0) {
1034 if (location->end() <= location->start()) {
1035 error << _("Session: you can't use a mark for auto loop") << endmsg;
1039 last_loopend = location->end();
1041 auto_loop_start_changed_connection.disconnect();
1042 auto_loop_end_changed_connection.disconnect();
1043 auto_loop_changed_connection.disconnect();
1045 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1046 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1047 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
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* ignored)
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);
1154 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1155 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1157 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1158 if ((*i)->record_enabled ()) {
1159 (*i)->monitor_input (false);
1164 RecordStateChanged (); /* emit signal */
1167 remove_pending_capture_state ();
1173 Session::step_back_from_record ()
1175 /* XXX really atomic compare+swap here */
1176 if (g_atomic_int_get (&_record_status) == Recording) {
1177 g_atomic_int_set (&_record_status, Enabled);
1179 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1180 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1182 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1183 if ((*i)->record_enabled ()) {
1184 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1185 (*i)->monitor_input (false);
1193 Session::maybe_enable_record ()
1195 g_atomic_int_set (&_record_status, Enabled);
1197 /* this function is currently called from somewhere other than an RT thread.
1198 this save_state() call therefore doesn't impact anything.
1201 save_state ("", true);
1203 if (_transport_speed) {
1204 if (!Config->get_punch_in()) {
1208 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1209 RecordStateChanged (); /* EMIT SIGNAL */
1216 Session::audible_frame () const
1222 /* the first of these two possible settings for "offset"
1223 mean that the audible frame is stationary until
1224 audio emerges from the latency compensation
1227 the second means that the audible frame is stationary
1228 until audio would emerge from a physical port
1229 in the absence of any plugin latency compensation
1232 offset = _worst_output_latency;
1234 if (offset > current_block_size) {
1235 offset -= current_block_size;
1237 /* XXX is this correct? if we have no external
1238 physical connections and everything is internal
1239 then surely this is zero? still, how
1240 likely is that anyway?
1242 offset = current_block_size;
1245 if (synced_to_jack()) {
1246 tf = _engine.transport_frame();
1248 tf = _transport_frame;
1251 if (_transport_speed == 0) {
1261 if (!non_realtime_work_pending()) {
1265 /* take latency into account */
1274 Session::set_frame_rate (nframes_t frames_per_second)
1276 /** \fn void Session::set_frame_size(nframes_t)
1277 the AudioEngine object that calls this guarantees
1278 that it will not be called while we are also in
1279 ::process(). Its fine to do things that block
1283 _base_frame_rate = frames_per_second;
1287 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1291 // XXX we need some equivalent to this, somehow
1292 // SndFileSource::setup_standard_crossfades (frames_per_second);
1296 /* XXX need to reset/reinstantiate all LADSPA plugins */
1300 Session::set_block_size (nframes_t nframes)
1302 /* the AudioEngine guarantees
1303 that it will not be called while we are also in
1304 ::process(). It is therefore fine to do things that block
1310 current_block_size = nframes;
1312 ensure_buffers(_scratch_buffers->available());
1314 if (_gain_automation_buffer) {
1315 delete [] _gain_automation_buffer;
1317 _gain_automation_buffer = new gain_t[nframes];
1319 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1321 boost::shared_ptr<RouteList> r = routes.reader ();
1323 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1324 (*i)->set_block_size (nframes);
1327 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1328 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1329 (*i)->set_block_size (nframes);
1332 set_worst_io_latencies ();
1337 Session::set_default_fade (float steepness, float fade_msecs)
1340 nframes_t fade_frames;
1342 /* Don't allow fade of less 1 frame */
1344 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1351 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1355 default_fade_msecs = fade_msecs;
1356 default_fade_steepness = steepness;
1359 // jlc, WTF is this!
1360 Glib::RWLock::ReaderLock lm (route_lock);
1361 AudioRegion::set_default_fade (steepness, fade_frames);
1366 /* XXX have to do this at some point */
1367 /* foreach region using default fade, reset, then
1368 refill_all_diskstream_buffers ();
1373 struct RouteSorter {
1374 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1375 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1377 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1380 if (r1->fed_by.empty()) {
1381 if (r2->fed_by.empty()) {
1382 /* no ardour-based connections inbound to either route. just use signal order */
1383 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1385 /* r2 has connections, r1 does not; run r1 early */
1389 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1396 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1398 shared_ptr<Route> r2;
1400 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1401 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1405 /* make a copy of the existing list of routes that feed r1 */
1407 set<shared_ptr<Route> > existing = r1->fed_by;
1409 /* for each route that feeds r1, recurse, marking it as feeding
1413 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1416 /* r2 is a route that feeds r1 which somehow feeds base. mark
1417 base as being fed by r2
1420 rbase->fed_by.insert (r2);
1424 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1428 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1432 /* now recurse, so that we can mark base as being fed by
1433 all routes that feed r2
1436 trace_terminal (r2, rbase);
1443 Session::resort_routes ()
1445 /* don't do anything here with signals emitted
1446 by Routes while we are being destroyed.
1449 if (_state_of_the_state & Deletion) {
1456 RCUWriter<RouteList> writer (routes);
1457 shared_ptr<RouteList> r = writer.get_copy ();
1458 resort_routes_using (r);
1459 /* writer goes out of scope and forces update */
1464 Session::resort_routes_using (shared_ptr<RouteList> r)
1466 RouteList::iterator i, j;
1468 for (i = r->begin(); i != r->end(); ++i) {
1470 (*i)->fed_by.clear ();
1472 for (j = r->begin(); j != r->end(); ++j) {
1474 /* although routes can feed themselves, it will
1475 cause an endless recursive descent if we
1476 detect it. so don't bother checking for
1484 if ((*j)->feeds (*i)) {
1485 (*i)->fed_by.insert (*j);
1490 for (i = r->begin(); i != r->end(); ++i) {
1491 trace_terminal (*i, *i);
1498 cerr << "finished route resort\n";
1500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1508 list<boost::shared_ptr<MidiTrack> >
1509 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1511 char track_name[32];
1512 uint32_t track_id = 0;
1515 RouteList new_routes;
1516 list<boost::shared_ptr<MidiTrack> > ret;
1517 //uint32_t control_id;
1519 // FIXME: need physical I/O and autoconnect stuff for MIDI
1521 /* count existing midi tracks */
1524 shared_ptr<RouteList> r = routes.reader ();
1526 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1527 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1528 if (!(*i)->is_hidden()) {
1530 //channels_used += (*i)->n_inputs().n_midi();
1537 vector<string> physinputs;
1538 vector<string> physoutputs;
1540 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1541 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1542 uint32_t nphysical_in;
1543 uint32_t nphysical_out;
1544 control_id = ntracks() + nbusses();
1549 /* check for duplicate route names, since we might have pre-existing
1550 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1551 save, close,restart,add new route - first named route is now
1559 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1561 if (route_by_name (track_name) == 0) {
1565 } while (track_id < (UINT_MAX-1));
1568 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1569 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1574 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1575 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1581 shared_ptr<MidiTrack> track;
1584 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1586 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1587 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1593 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1597 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1598 port = physinputs[(channels_used+x)%nphysical_in];
1601 if (port.length() && track->connect_input (track->input (x), port, this)) {
1607 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1611 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1612 port = physoutputs[(channels_used+x)%nphysical_out];
1613 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1615 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1619 if (port.length() && track->connect_output (track->output (x), port, this)) {
1624 channels_used += track->n_inputs ().n_midi();
1628 track->midi_diskstream()->non_realtime_input_change();
1630 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1631 //track->set_remote_control_id (control_id);
1633 new_routes.push_back (track);
1634 ret.push_back (track);
1637 catch (failed_constructor &err) {
1638 error << _("Session: could not create new midi track.") << endmsg;
1641 /* we need to get rid of this, since the track failed to be created */
1642 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1645 RCUWriter<DiskstreamList> writer (diskstreams);
1646 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1647 ds->remove (track->midi_diskstream());
1654 catch (AudioEngine::PortRegistrationFailure& pfe) {
1656 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1659 /* we need to get rid of this, since the track failed to be created */
1660 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1663 RCUWriter<DiskstreamList> writer (diskstreams);
1664 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1665 ds->remove (track->midi_diskstream());
1676 if (!new_routes.empty()) {
1677 add_routes (new_routes, false);
1678 save_state (_current_snapshot_name);
1684 list<boost::shared_ptr<AudioTrack> >
1685 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1687 char track_name[32];
1688 uint32_t track_id = 0;
1690 uint32_t channels_used = 0;
1692 RouteList new_routes;
1693 list<boost::shared_ptr<AudioTrack> > ret;
1694 uint32_t control_id;
1696 /* count existing audio tracks */
1699 shared_ptr<RouteList> r = routes.reader ();
1701 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1702 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1703 if (!(*i)->is_hidden()) {
1705 channels_used += (*i)->n_inputs().n_audio();
1711 vector<string> physinputs;
1712 vector<string> physoutputs;
1713 uint32_t nphysical_in;
1714 uint32_t nphysical_out;
1716 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1717 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1718 control_id = ntracks() + nbusses() + 1;
1722 /* check for duplicate route names, since we might have pre-existing
1723 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1724 save, close,restart,add new route - first named route is now
1732 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1734 if (route_by_name (track_name) == 0) {
1738 } while (track_id < (UINT_MAX-1));
1740 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1741 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1746 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1747 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1752 shared_ptr<AudioTrack> track;
1755 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1757 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1758 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1759 input_channels, output_channels)
1765 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1769 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1770 port = physinputs[(channels_used+x)%nphysical_in];
1773 if (port.length() && track->connect_input (track->input (x), port, this)) {
1779 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1783 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1784 port = physoutputs[(channels_used+x)%nphysical_out];
1785 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1787 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1791 if (port.length() && track->connect_output (track->output (x), port, this)) {
1796 channels_used += track->n_inputs ().n_audio();
1798 track->audio_diskstream()->non_realtime_input_change();
1800 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1801 track->set_remote_control_id (control_id);
1804 new_routes.push_back (track);
1805 ret.push_back (track);
1808 catch (failed_constructor &err) {
1809 error << _("Session: could not create new audio track.") << endmsg;
1812 /* we need to get rid of this, since the track failed to be created */
1813 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1816 RCUWriter<DiskstreamList> writer (diskstreams);
1817 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1818 ds->remove (track->audio_diskstream());
1825 catch (AudioEngine::PortRegistrationFailure& pfe) {
1827 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;
1830 /* we need to get rid of this, since the track failed to be created */
1831 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1834 RCUWriter<DiskstreamList> writer (diskstreams);
1835 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1836 ds->remove (track->audio_diskstream());
1847 if (!new_routes.empty()) {
1848 add_routes (new_routes, true);
1855 Session::set_remote_control_ids ()
1857 RemoteModel m = Config->get_remote_model();
1859 shared_ptr<RouteList> r = routes.reader ();
1861 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1862 if ( MixerOrdered == m) {
1863 long order = (*i)->order_key(N_("signal"));
1864 (*i)->set_remote_control_id( order+1 );
1865 } else if ( EditorOrdered == m) {
1866 long order = (*i)->order_key(N_("editor"));
1867 (*i)->set_remote_control_id( order+1 );
1868 } else if ( UserOrdered == m) {
1869 //do nothing ... only changes to remote id's are initiated by user
1876 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1879 uint32_t bus_id = 1;
1883 uint32_t control_id;
1885 /* count existing audio busses */
1888 shared_ptr<RouteList> r = routes.reader ();
1890 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1891 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1892 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1899 vector<string> physinputs;
1900 vector<string> physoutputs;
1902 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1903 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1904 control_id = ntracks() + nbusses() + 1;
1909 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1913 if (route_by_name (bus_name) == 0) {
1917 } while (bus_id < (UINT_MAX-1));
1920 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1922 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1923 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1924 input_channels, output_channels)
1929 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1933 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1934 port = physinputs[((n+x)%n_physical_inputs)];
1937 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1942 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1946 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1947 port = physoutputs[((n+x)%n_physical_outputs)];
1948 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1950 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1954 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1959 bus->set_remote_control_id (control_id);
1962 ret.push_back (bus);
1966 catch (failed_constructor &err) {
1967 error << _("Session: could not create new audio route.") << endmsg;
1971 catch (AudioEngine::PortRegistrationFailure& pfe) {
1972 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;
1982 add_routes (ret, true);
1990 Session::add_routes (RouteList& new_routes, bool save)
1993 RCUWriter<RouteList> writer (routes);
1994 shared_ptr<RouteList> r = writer.get_copy ();
1995 r->insert (r->end(), new_routes.begin(), new_routes.end());
1996 resort_routes_using (r);
1999 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2001 boost::weak_ptr<Route> wpr (*x);
2003 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2004 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2005 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2006 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2008 if ((*x)->is_master()) {
2012 if ((*x)->is_control()) {
2013 _control_out = (*x);
2016 add_bundle ((*x)->bundle_for_inputs());
2017 add_bundle ((*x)->bundle_for_outputs());
2020 if (_control_out && IO::connecting_legal) {
2022 vector<string> cports;
2023 uint32_t ni = _control_out->n_inputs().n_audio();
2025 for (uint32_t n = 0; n < ni; ++n) {
2026 cports.push_back (_control_out->input(n)->name());
2029 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2030 (*x)->set_control_outs (cports);
2037 save_state (_current_snapshot_name);
2040 RouteAdded (new_routes); /* EMIT SIGNAL */
2044 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2046 /* need to do this in case we're rolling at the time, to prevent false underruns */
2047 dstream->do_refill_with_alloc ();
2049 dstream->set_block_size (current_block_size);
2052 RCUWriter<DiskstreamList> writer (diskstreams);
2053 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2054 ds->push_back (dstream);
2055 /* writer goes out of scope, copies ds back to main */
2058 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2059 /* this will connect to future changes, and check the current length */
2060 diskstream_playlist_changed (dstream);
2062 dstream->prepare ();
2067 Session::remove_route (shared_ptr<Route> route)
2070 RCUWriter<RouteList> writer (routes);
2071 shared_ptr<RouteList> rs = writer.get_copy ();
2075 /* deleting the master out seems like a dumb
2076 idea, but its more of a UI policy issue
2080 if (route == _master_out) {
2081 _master_out = shared_ptr<Route> ();
2084 if (route == _control_out) {
2085 _control_out = shared_ptr<Route> ();
2087 /* cancel control outs for all routes */
2089 vector<string> empty;
2091 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2092 (*r)->set_control_outs (empty);
2096 update_route_solo_state ();
2098 /* writer goes out of scope, forces route list update */
2102 boost::shared_ptr<Diskstream> ds;
2104 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2105 ds = t->diskstream();
2111 RCUWriter<DiskstreamList> dsl (diskstreams);
2112 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2117 find_current_end ();
2119 // We need to disconnect the routes inputs and outputs
2121 route->disconnect_inputs (0);
2122 route->disconnect_outputs (0);
2124 update_latency_compensation (false, false);
2127 /* get rid of it from the dead wood collection in the route list manager */
2129 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2133 /* try to cause everyone to drop their references */
2135 route->drop_references ();
2137 /* save the new state of the world */
2139 if (save_state (_current_snapshot_name)) {
2140 save_history (_current_snapshot_name);
2145 Session::route_mute_changed (void* src)
2151 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2153 if (solo_update_disabled) {
2159 boost::shared_ptr<Route> route = wpr.lock ();
2162 /* should not happen */
2163 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2167 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2169 shared_ptr<RouteList> r = routes.reader ();
2171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2173 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2177 /* don't mess with busses */
2179 if (dynamic_cast<Track*>((*i).get()) == 0) {
2185 /* don't mess with tracks */
2187 if (dynamic_cast<Track*>((*i).get()) != 0) {
2192 if ((*i) != route &&
2193 ((*i)->mix_group () == 0 ||
2194 (*i)->mix_group () != route->mix_group () ||
2195 !route->mix_group ()->is_active())) {
2197 if ((*i)->soloed()) {
2199 /* if its already soloed, and solo latching is enabled,
2200 then leave it as it is.
2203 if (Config->get_solo_latched()) {
2210 solo_update_disabled = true;
2211 (*i)->set_solo (false, src);
2212 solo_update_disabled = false;
2216 bool something_soloed = false;
2217 bool same_thing_soloed = false;
2218 bool signal = false;
2220 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2221 if ((*i)->soloed()) {
2222 something_soloed = true;
2223 if (dynamic_cast<Track*>((*i).get())) {
2225 same_thing_soloed = true;
2230 same_thing_soloed = true;
2238 if (something_soloed != currently_soloing) {
2240 currently_soloing = something_soloed;
2243 modify_solo_mute (is_track, same_thing_soloed);
2246 SoloActive (currently_soloing); /* EMIT SIGNAL */
2249 SoloChanged (); /* EMIT SIGNAL */
2255 Session::update_route_solo_state ()
2258 bool is_track = false;
2259 bool signal = false;
2261 /* caller must hold RouteLock */
2263 /* this is where we actually implement solo by changing
2264 the solo mute setting of each track.
2267 shared_ptr<RouteList> r = routes.reader ();
2269 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2270 if ((*i)->soloed()) {
2272 if (dynamic_cast<Track*>((*i).get())) {
2279 if (mute != currently_soloing) {
2281 currently_soloing = mute;
2284 if (!is_track && !mute) {
2286 /* nothing is soloed */
2288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 (*i)->set_solo_mute (false);
2299 modify_solo_mute (is_track, mute);
2302 SoloActive (currently_soloing);
2307 Session::modify_solo_mute (bool is_track, bool mute)
2309 shared_ptr<RouteList> r = routes.reader ();
2311 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2315 /* only alter track solo mute */
2317 if (dynamic_cast<Track*>((*i).get())) {
2318 if ((*i)->soloed()) {
2319 (*i)->set_solo_mute (!mute);
2321 (*i)->set_solo_mute (mute);
2327 /* only alter bus solo mute */
2329 if (!dynamic_cast<Track*>((*i).get())) {
2331 if ((*i)->soloed()) {
2333 (*i)->set_solo_mute (false);
2337 /* don't mute master or control outs
2338 in response to another bus solo
2341 if ((*i) != _master_out &&
2342 (*i) != _control_out) {
2343 (*i)->set_solo_mute (mute);
2354 Session::catch_up_on_solo ()
2356 /* this is called after set_state() to catch the full solo
2357 state, which can't be correctly determined on a per-route
2358 basis, but needs the global overview that only the session
2361 update_route_solo_state();
2365 Session::route_by_name (string name)
2367 shared_ptr<RouteList> r = routes.reader ();
2369 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2370 if ((*i)->name() == name) {
2375 return shared_ptr<Route> ((Route*) 0);
2379 Session::route_by_id (PBD::ID id)
2381 shared_ptr<RouteList> r = routes.reader ();
2383 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2384 if ((*i)->id() == id) {
2389 return shared_ptr<Route> ((Route*) 0);
2393 Session::route_by_remote_id (uint32_t id)
2395 shared_ptr<RouteList> r = routes.reader ();
2397 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2398 if ((*i)->remote_control_id() == id) {
2403 return shared_ptr<Route> ((Route*) 0);
2407 Session::find_current_end ()
2409 if (_state_of_the_state & Loading) {
2413 nframes_t max = get_maximum_extent ();
2415 if (max > end_location->end()) {
2416 end_location->set_end (max);
2418 DurationChanged(); /* EMIT SIGNAL */
2423 Session::get_maximum_extent () const
2428 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2430 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2431 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2433 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2434 if ((me = pl->get_maximum_extent()) > max) {
2442 boost::shared_ptr<Diskstream>
2443 Session::diskstream_by_name (string name)
2445 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2447 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2448 if ((*i)->name() == name) {
2453 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2456 boost::shared_ptr<Diskstream>
2457 Session::diskstream_by_id (const PBD::ID& id)
2459 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2461 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2462 if ((*i)->id() == id) {
2467 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2470 /* Region management */
2473 Session::new_region_name (string old)
2475 string::size_type last_period;
2477 string::size_type len = old.length() + 64;
2480 if ((last_period = old.find_last_of ('.')) == string::npos) {
2482 /* no period present - add one explicitly */
2485 last_period = old.length() - 1;
2490 number = atoi (old.substr (last_period+1).c_str());
2494 while (number < (UINT_MAX-1)) {
2496 RegionList::const_iterator i;
2501 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2504 for (i = regions.begin(); i != regions.end(); ++i) {
2505 if (i->second->name() == sbuf) {
2510 if (i == regions.end()) {
2515 if (number != (UINT_MAX-1)) {
2519 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2524 Session::region_name (string& result, string base, bool newlevel)
2529 assert(base.find("/") == string::npos);
2533 Glib::Mutex::Lock lm (region_lock);
2535 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2544 string::size_type pos;
2546 pos = base.find_last_of ('.');
2548 /* pos may be npos, but then we just use entire base */
2550 subbase = base.substr (0, pos);
2555 Glib::Mutex::Lock lm (region_lock);
2557 map<string,uint32_t>::iterator x;
2561 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2563 region_name_map[subbase] = 1;
2566 snprintf (buf, sizeof (buf), ".%d", x->second);
2577 Session::add_region (boost::shared_ptr<Region> region)
2579 vector<boost::shared_ptr<Region> > v;
2580 v.push_back (region);
2585 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2590 Glib::Mutex::Lock lm (region_lock);
2592 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2594 boost::shared_ptr<Region> region = *ii;
2598 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2602 RegionList::iterator x;
2604 for (x = regions.begin(); x != regions.end(); ++x) {
2606 if (region->region_list_equivalent (x->second)) {
2611 if (x == regions.end()) {
2613 pair<RegionList::key_type,RegionList::mapped_type> entry;
2615 entry.first = region->id();
2616 entry.second = region;
2618 pair<RegionList::iterator,bool> x = regions.insert (entry);
2630 /* mark dirty because something has changed even if we didn't
2631 add the region to the region list.
2638 vector<boost::weak_ptr<Region> > v;
2639 boost::shared_ptr<Region> first_r;
2641 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2643 boost::shared_ptr<Region> region = *ii;
2647 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2650 v.push_back (region);
2657 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2658 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2660 update_region_name_map (region);
2664 RegionsAdded (v); /* EMIT SIGNAL */
2670 Session::update_region_name_map (boost::shared_ptr<Region> region)
2672 string::size_type last_period = region->name().find_last_of ('.');
2674 if (last_period != string::npos && last_period < region->name().length() - 1) {
2676 string base = region->name().substr (0, last_period);
2677 string number = region->name().substr (last_period+1);
2678 map<string,uint32_t>::iterator x;
2680 /* note that if there is no number, we get zero from atoi,
2684 region_name_map[base] = atoi (number);
2689 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2691 boost::shared_ptr<Region> region (weak_region.lock ());
2697 if (what_changed & Region::HiddenChanged) {
2698 /* relay hidden changes */
2699 RegionHiddenChange (region);
2702 if (what_changed & NameChanged) {
2703 update_region_name_map (region);
2708 Session::remove_region (boost::weak_ptr<Region> weak_region)
2710 RegionList::iterator i;
2711 boost::shared_ptr<Region> region (weak_region.lock ());
2717 bool removed = false;
2720 Glib::Mutex::Lock lm (region_lock);
2722 if ((i = regions.find (region->id())) != regions.end()) {
2728 /* mark dirty because something has changed even if we didn't
2729 remove the region from the region list.
2735 RegionRemoved(region); /* EMIT SIGNAL */
2739 boost::shared_ptr<Region>
2740 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2742 RegionList::iterator i;
2743 boost::shared_ptr<Region> region;
2745 Glib::Mutex::Lock lm (region_lock);
2747 for (i = regions.begin(); i != regions.end(); ++i) {
2751 if (region->whole_file()) {
2753 if (child->source_equivalent (region)) {
2759 return boost::shared_ptr<Region> ();
2763 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2765 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2766 (*i)->get_region_list_equivalent_regions (region, result);
2770 Session::destroy_region (boost::shared_ptr<Region> region)
2772 vector<boost::shared_ptr<Source> > srcs;
2775 if (region->playlist()) {
2776 region->playlist()->destroy_region (region);
2779 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2780 srcs.push_back (region->source (n));
2784 region->drop_references ();
2786 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2788 (*i)->mark_for_remove ();
2789 (*i)->drop_references ();
2791 cerr << "source was not used by any playlist\n";
2798 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2800 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2801 destroy_region (*i);
2807 Session::remove_last_capture ()
2809 list<boost::shared_ptr<Region> > r;
2811 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2813 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2814 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2817 r.insert (r.end(), l.begin(), l.end());
2822 destroy_regions (r);
2824 save_state (_current_snapshot_name);
2830 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2836 /* Source Management */
2838 Session::add_source (boost::shared_ptr<Source> source)
2840 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2841 pair<SourceMap::iterator,bool> result;
2843 entry.first = source->id();
2844 entry.second = source;
2847 Glib::Mutex::Lock lm (source_lock);
2848 result = sources.insert (entry);
2851 if (result.second) {
2852 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2856 boost::shared_ptr<AudioFileSource> afs;
2858 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2859 if (Config->get_auto_analyse_audio()) {
2860 Analyser::queue_source_for_analysis (source, false);
2866 Session::remove_source (boost::weak_ptr<Source> src)
2868 SourceMap::iterator i;
2869 boost::shared_ptr<Source> source = src.lock();
2876 Glib::Mutex::Lock lm (source_lock);
2878 if ((i = sources.find (source->id())) != sources.end()) {
2883 if (!_state_of_the_state & InCleanup) {
2885 /* save state so we don't end up with a session file
2886 referring to non-existent sources.
2889 save_state (_current_snapshot_name);
2893 boost::shared_ptr<Source>
2894 Session::source_by_id (const PBD::ID& id)
2896 Glib::Mutex::Lock lm (source_lock);
2897 SourceMap::iterator i;
2898 boost::shared_ptr<Source> source;
2900 if ((i = sources.find (id)) != sources.end()) {
2908 boost::shared_ptr<Source>
2909 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2911 Glib::Mutex::Lock lm (source_lock);
2913 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2914 cerr << "comparing " << path << " with " << i->second->name() << endl;
2915 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2917 if (afs && afs->path() == path && chn == afs->channel()) {
2922 return boost::shared_ptr<Source>();
2926 Session::peak_path (Glib::ustring base) const
2928 sys::path peakfile_path(_session_dir->peak_path());
2929 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2930 return peakfile_path.to_string();
2934 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2937 string old_basename = PBD::basename_nosuffix (oldname);
2938 string new_legalized = legalize_for_path (newname);
2940 /* note: we know (or assume) the old path is already valid */
2944 /* destructive file sources have a name of the form:
2946 /path/to/Tnnnn-NAME(%[LR])?.wav
2948 the task here is to replace NAME with the new name.
2951 /* find last slash */
2955 string::size_type slash;
2956 string::size_type dash;
2958 if ((slash = path.find_last_of ('/')) == string::npos) {
2962 dir = path.substr (0, slash+1);
2964 /* '-' is not a legal character for the NAME part of the path */
2966 if ((dash = path.find_last_of ('-')) == string::npos) {
2970 prefix = path.substr (slash+1, dash-(slash+1));
2975 path += new_legalized;
2976 path += ".wav"; /* XXX gag me with a spoon */
2980 /* non-destructive file sources have a name of the form:
2982 /path/to/NAME-nnnnn(%[LR])?.wav
2984 the task here is to replace NAME with the new name.
2989 string::size_type slash;
2990 string::size_type dash;
2991 string::size_type postfix;
2993 /* find last slash */
2995 if ((slash = path.find_last_of ('/')) == string::npos) {
2999 dir = path.substr (0, slash+1);
3001 /* '-' is not a legal character for the NAME part of the path */
3003 if ((dash = path.find_last_of ('-')) == string::npos) {
3007 suffix = path.substr (dash+1);
3009 // Suffix is now everything after the dash. Now we need to eliminate
3010 // the nnnnn part, which is done by either finding a '%' or a '.'
3012 postfix = suffix.find_last_of ("%");
3013 if (postfix == string::npos) {
3014 postfix = suffix.find_last_of ('.');
3017 if (postfix != string::npos) {
3018 suffix = suffix.substr (postfix);
3020 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3024 const uint32_t limit = 10000;
3025 char buf[PATH_MAX+1];
3027 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3029 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3031 if (access (buf, F_OK) != 0) {
3039 error << "FATAL ERROR! Could not find a " << endl;
3048 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3052 char buf[PATH_MAX+1];
3053 const uint32_t limit = 10000;
3057 legalized = legalize_for_path (name);
3059 /* find a "version" of the file name that doesn't exist in
3060 any of the possible directories.
3063 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3065 vector<space_and_path>::iterator i;
3066 uint32_t existing = 0;
3068 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3070 SessionDirectory sdir((*i).path);
3072 spath = sdir.sound_path().to_string();
3076 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3077 } else if (nchan == 2) {
3079 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3081 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3083 } else if (nchan < 26) {
3084 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3086 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3095 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3096 } else if (nchan == 2) {
3098 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3100 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3102 } else if (nchan < 26) {
3103 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3105 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3109 if (sys::exists(buf)) {
3115 if (existing == 0) {
3120 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3122 throw failed_constructor();
3126 /* we now have a unique name for the file, but figure out where to
3132 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3134 spath = sdir.sound_path().to_string();
3137 string::size_type pos = foo.find_last_of ('/');
3139 if (pos == string::npos) {
3142 spath += foo.substr (pos + 1);
3148 boost::shared_ptr<AudioFileSource>
3149 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3151 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3152 return boost::dynamic_pointer_cast<AudioFileSource> (
3153 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3156 // FIXME: _terrible_ code duplication
3158 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3161 string old_basename = PBD::basename_nosuffix (oldname);
3162 string new_legalized = legalize_for_path (newname);
3164 /* note: we know (or assume) the old path is already valid */
3168 /* destructive file sources have a name of the form:
3170 /path/to/Tnnnn-NAME(%[LR])?.wav
3172 the task here is to replace NAME with the new name.
3175 /* find last slash */
3179 string::size_type slash;
3180 string::size_type dash;
3182 if ((slash = path.find_last_of ('/')) == string::npos) {
3186 dir = path.substr (0, slash+1);
3188 /* '-' is not a legal character for the NAME part of the path */
3190 if ((dash = path.find_last_of ('-')) == string::npos) {
3194 prefix = path.substr (slash+1, dash-(slash+1));
3199 path += new_legalized;
3200 path += ".mid"; /* XXX gag me with a spoon */
3204 /* non-destructive file sources have a name of the form:
3206 /path/to/NAME-nnnnn(%[LR])?.wav
3208 the task here is to replace NAME with the new name.
3213 string::size_type slash;
3214 string::size_type dash;
3215 string::size_type postfix;
3217 /* find last slash */
3219 if ((slash = path.find_last_of ('/')) == string::npos) {
3223 dir = path.substr (0, slash+1);
3225 /* '-' is not a legal character for the NAME part of the path */
3227 if ((dash = path.find_last_of ('-')) == string::npos) {
3231 suffix = path.substr (dash+1);
3233 // Suffix is now everything after the dash. Now we need to eliminate
3234 // the nnnnn part, which is done by either finding a '%' or a '.'
3236 postfix = suffix.find_last_of ("%");
3237 if (postfix == string::npos) {
3238 postfix = suffix.find_last_of ('.');
3241 if (postfix != string::npos) {
3242 suffix = suffix.substr (postfix);
3244 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3248 const uint32_t limit = 10000;
3249 char buf[PATH_MAX+1];
3251 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3253 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3255 if (access (buf, F_OK) != 0) {
3263 error << "FATAL ERROR! Could not find a " << endl;
3272 Session::midi_path_from_name (string name)
3276 char buf[PATH_MAX+1];
3277 const uint32_t limit = 10000;
3281 legalized = legalize_for_path (name);
3283 /* find a "version" of the file name that doesn't exist in
3284 any of the possible directories.
3287 for (cnt = 1; cnt <= limit; ++cnt) {
3289 vector<space_and_path>::iterator i;
3290 uint32_t existing = 0;
3292 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3294 SessionDirectory sdir((*i).path);
3296 sys::path p = sdir.midi_path();
3300 spath = p.to_string();
3302 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3304 if (sys::exists (buf)) {
3309 if (existing == 0) {
3314 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3315 throw failed_constructor();
3319 /* we now have a unique name for the file, but figure out where to
3325 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3327 spath = sdir.midi_path().to_string();
3330 string::size_type pos = foo.find_last_of ('/');
3332 if (pos == string::npos) {
3335 spath += foo.substr (pos + 1);
3341 boost::shared_ptr<MidiSource>
3342 Session::create_midi_source_for_session (MidiDiskstream& ds)
3344 string mpath = midi_path_from_name (ds.name());
3346 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3350 /* Playlist management */
3352 boost::shared_ptr<Playlist>
3353 Session::playlist_by_name (string name)
3355 Glib::Mutex::Lock lm (playlist_lock);
3356 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3357 if ((*i)->name() == name) {
3361 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3362 if ((*i)->name() == name) {
3367 return boost::shared_ptr<Playlist>();
3371 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3373 if (playlist->hidden()) {
3378 Glib::Mutex::Lock lm (playlist_lock);
3379 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3380 playlists.insert (playlists.begin(), playlist);
3381 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3382 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3388 PlaylistAdded (playlist); /* EMIT SIGNAL */
3392 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3395 Glib::Mutex::Lock lm (playlist_lock);
3396 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3399 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3406 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3408 boost::shared_ptr<Playlist> pl(wpl.lock());
3414 PlaylistList::iterator x;
3417 /* its not supposed to be visible */
3422 Glib::Mutex::Lock lm (playlist_lock);
3426 unused_playlists.insert (pl);
3428 if ((x = playlists.find (pl)) != playlists.end()) {
3429 playlists.erase (x);
3435 playlists.insert (pl);
3437 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3438 unused_playlists.erase (x);
3445 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3447 if (_state_of_the_state & Deletion) {
3451 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3458 Glib::Mutex::Lock lm (playlist_lock);
3460 PlaylistList::iterator i;
3462 i = find (playlists.begin(), playlists.end(), playlist);
3463 if (i != playlists.end()) {
3464 playlists.erase (i);
3467 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3468 if (i != unused_playlists.end()) {
3469 unused_playlists.erase (i);
3476 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3480 Session::set_audition (boost::shared_ptr<Region> r)
3482 pending_audition_region = r;
3483 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3484 schedule_butler_transport_work ();
3488 Session::audition_playlist ()
3490 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3491 ev->region.reset ();
3496 Session::non_realtime_set_audition ()
3498 if (!pending_audition_region) {
3499 auditioner->audition_current_playlist ();
3501 auditioner->audition_region (pending_audition_region);
3502 pending_audition_region.reset ();
3504 AuditionActive (true); /* EMIT SIGNAL */
3508 Session::audition_region (boost::shared_ptr<Region> r)
3510 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3516 Session::cancel_audition ()
3518 if (auditioner->active()) {
3519 auditioner->cancel_audition ();
3520 AuditionActive (false); /* EMIT SIGNAL */
3525 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3527 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3531 Session::remove_empty_sounds ()
3533 vector<string> audio_filenames;
3535 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3537 Glib::Mutex::Lock lm (source_lock);
3539 TapeFileMatcher tape_file_matcher;
3541 remove_if (audio_filenames.begin(), audio_filenames.end(),
3542 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3544 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3546 sys::path audio_file_path (_session_dir->sound_path());
3548 audio_file_path /= *i;
3550 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3554 sys::remove (audio_file_path);
3555 const string peakfile = peak_path (audio_file_path.to_string());
3556 sys::remove (peakfile);
3558 catch (const sys::filesystem_error& err)
3560 error << err.what() << endmsg;
3567 Session::is_auditioning () const
3569 /* can be called before we have an auditioner object */
3571 return auditioner->active();
3578 Session::set_all_solo (bool yn)
3580 shared_ptr<RouteList> r = routes.reader ();
3582 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3583 if (!(*i)->is_hidden()) {
3584 (*i)->set_solo (yn, this);
3592 Session::set_all_mute (bool yn)
3594 shared_ptr<RouteList> r = routes.reader ();
3596 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3597 if (!(*i)->is_hidden()) {
3598 (*i)->set_mute (yn, this);
3606 Session::n_diskstreams () const
3610 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3612 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3613 if (!(*i)->hidden()) {
3621 Session::graph_reordered ()
3623 /* don't do this stuff if we are setting up connections
3624 from a set_state() call or creating new tracks.
3627 if (_state_of_the_state & InitialConnecting) {
3631 /* every track/bus asked for this to be handled but it was deferred because
3632 we were connecting. do it now.
3635 request_input_change_handling ();
3639 /* force all diskstreams to update their capture offset values to
3640 reflect any changes in latencies within the graph.
3643 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3645 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3646 (*i)->set_capture_offset ();
3651 Session::record_disenable_all ()
3653 record_enable_change_all (false);
3657 Session::record_enable_all ()
3659 record_enable_change_all (true);
3663 Session::record_enable_change_all (bool yn)
3665 shared_ptr<RouteList> r = routes.reader ();
3667 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3670 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3671 at->set_record_enable (yn, this);
3675 /* since we don't keep rec-enable state, don't mark session dirty */
3679 Session::add_processor (Processor* processor)
3682 PortInsert* port_insert;
3683 PluginInsert* plugin_insert;
3685 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3686 _port_inserts.insert (_port_inserts.begin(), port_insert);
3687 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3688 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3689 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3690 _sends.insert (_sends.begin(), send);
3692 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3696 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3702 Session::remove_processor (Processor* processor)
3705 PortInsert* port_insert;
3706 PluginInsert* plugin_insert;
3708 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3709 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3710 if (x != _port_inserts.end()) {
3711 insert_bitset[port_insert->bit_slot()] = false;
3712 _port_inserts.erase (x);
3714 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3715 _plugin_inserts.remove (plugin_insert);
3716 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3717 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3718 if (x != _sends.end()) {
3719 send_bitset[send->bit_slot()] = false;
3723 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3731 Session::available_capture_duration ()
3733 float sample_bytes_on_disk = 4.0; // keep gcc happy
3735 switch (Config->get_native_file_data_format()) {
3737 sample_bytes_on_disk = 4.0;
3741 sample_bytes_on_disk = 3.0;
3745 sample_bytes_on_disk = 2.0;
3749 /* impossible, but keep some gcc versions happy */
3750 fatal << string_compose (_("programming error: %1"),
3751 X_("illegal native file data format"))
3756 double scale = 4096.0 / sample_bytes_on_disk;
3758 if (_total_free_4k_blocks * scale > (double) max_frames) {
3762 return (nframes_t) floor (_total_free_4k_blocks * scale);
3766 Session::add_bundle (shared_ptr<Bundle> bundle)
3769 Glib::Mutex::Lock guard (bundle_lock);
3770 _bundles.push_back (bundle);
3773 BundleAdded (bundle); /* EMIT SIGNAL */
3779 Session::remove_bundle (shared_ptr<Bundle> bundle)
3781 bool removed = false;
3784 Glib::Mutex::Lock guard (bundle_lock);
3785 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3787 if (i != _bundles.end()) {
3794 BundleRemoved (bundle); /* EMIT SIGNAL */
3801 Session::bundle_by_name (string name) const
3803 Glib::Mutex::Lock lm (bundle_lock);
3805 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3806 if ((*i)->name() == name) {
3811 return boost::shared_ptr<Bundle> ();
3815 Session::tempo_map_changed (Change ignored)
3819 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3820 (*i)->update_after_tempo_map_change ();
3823 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3824 (*i)->update_after_tempo_map_change ();
3830 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3831 * the given count with the current block size.
3834 Session::ensure_buffers (ChanCount howmany)
3836 if (current_block_size == 0)
3837 return; // too early? (is this ok?)
3839 // We need at least 2 MIDI scratch buffers to mix/merge
3840 if (howmany.n_midi() < 2)
3841 howmany.set_midi(2);
3843 // FIXME: JACK needs to tell us maximum MIDI buffer size
3844 // Using nasty assumption (max # events == nframes) for now
3845 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3846 _mix_buffers->ensure_buffers(howmany, current_block_size);
3847 _silent_buffers->ensure_buffers(howmany, current_block_size);
3849 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3853 Session::next_insert_id ()
3855 /* this doesn't really loop forever. just think about it */
3858 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3859 if (!insert_bitset[n]) {
3860 insert_bitset[n] = true;
3866 /* none available, so resize and try again */
3868 insert_bitset.resize (insert_bitset.size() + 16, false);
3873 Session::next_send_id ()
3875 /* this doesn't really loop forever. just think about it */
3878 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3879 if (!send_bitset[n]) {
3880 send_bitset[n] = true;
3886 /* none available, so resize and try again */
3888 send_bitset.resize (send_bitset.size() + 16, false);
3893 Session::mark_send_id (uint32_t id)
3895 if (id >= send_bitset.size()) {
3896 send_bitset.resize (id+16, false);
3898 if (send_bitset[id]) {
3899 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3901 send_bitset[id] = true;
3905 Session::mark_insert_id (uint32_t id)
3907 if (id >= insert_bitset.size()) {
3908 insert_bitset.resize (id+16, false);
3910 if (insert_bitset[id]) {
3911 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3913 insert_bitset[id] = true;
3916 /* Named Selection management */
3919 Session::named_selection_by_name (string name)
3921 Glib::Mutex::Lock lm (named_selection_lock);
3922 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3923 if ((*i)->name == name) {
3931 Session::add_named_selection (NamedSelection* named_selection)
3934 Glib::Mutex::Lock lm (named_selection_lock);
3935 named_selections.insert (named_selections.begin(), named_selection);
3938 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3944 NamedSelectionAdded (); /* EMIT SIGNAL */
3948 Session::remove_named_selection (NamedSelection* named_selection)
3950 bool removed = false;
3953 Glib::Mutex::Lock lm (named_selection_lock);
3955 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3957 if (i != named_selections.end()) {
3959 named_selections.erase (i);
3966 NamedSelectionRemoved (); /* EMIT SIGNAL */
3971 Session::reset_native_file_format ()
3973 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3975 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3976 (*i)->reset_write_sources (false);
3981 Session::route_name_unique (string n) const
3983 shared_ptr<RouteList> r = routes.reader ();
3985 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3986 if ((*i)->name() == n) {
3995 Session::n_playlists () const
3997 Glib::Mutex::Lock lm (playlist_lock);
3998 return playlists.size();
4002 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4004 if (!force && howmany <= _npan_buffers) {
4008 if (_pan_automation_buffer) {
4010 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4011 delete [] _pan_automation_buffer[i];
4014 delete [] _pan_automation_buffer;
4017 _pan_automation_buffer = new pan_t*[howmany];
4019 for (uint32_t i = 0; i < howmany; ++i) {
4020 _pan_automation_buffer[i] = new pan_t[nframes];
4023 _npan_buffers = howmany;
4027 Session::freeze (InterThreadInfo& itt)
4029 shared_ptr<RouteList> r = routes.reader ();
4031 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4035 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4036 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4046 boost::shared_ptr<Region>
4047 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4048 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4050 boost::shared_ptr<Region> result;
4051 boost::shared_ptr<Playlist> playlist;
4052 boost::shared_ptr<AudioFileSource> fsource;
4054 char buf[PATH_MAX+1];
4055 ChanCount nchans(track.audio_diskstream()->n_channels());
4057 nframes_t this_chunk;
4060 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4061 const string sound_dir = sdir.sound_path().to_string();
4062 nframes_t len = end - start;
4065 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4066 end, start) << endmsg;
4070 // any bigger than this seems to cause stack overflows in called functions
4071 const nframes_t chunk_size = (128 * 1024)/4;
4073 g_atomic_int_set (&processing_prohibited, 1);
4075 /* call tree *MUST* hold route_lock */
4077 if ((playlist = track.diskstream()->playlist()) == 0) {
4081 /* external redirects will be a problem */
4083 if (track.has_external_redirects()) {
4087 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4089 for (x = 0; x < 99999; ++x) {
4090 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4091 if (access (buf, F_OK) != 0) {
4097 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4102 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4103 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4106 catch (failed_constructor& err) {
4107 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4111 srcs.push_back (fsource);
4114 /* XXX need to flush all redirects */
4119 /* create a set of reasonably-sized buffers */
4120 buffers.ensure_buffers(nchans, chunk_size);
4121 buffers.set_count(nchans);
4123 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4124 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4126 afs->prepare_for_peakfile_writes ();
4129 while (to_do && !itt.cancel) {
4131 this_chunk = min (to_do, chunk_size);
4133 if (track.export_stuff (buffers, start, this_chunk)) {
4138 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4139 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4142 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4148 start += this_chunk;
4149 to_do -= this_chunk;
4151 itt.progress = (float) (1.0 - ((double) to_do / len));
4160 xnow = localtime (&now);
4162 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4163 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4166 afs->update_header (position, *xnow, now);
4167 afs->flush_header ();
4171 /* construct a region to represent the bounced material */
4173 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4174 region_name_from_path (srcs.front()->name(), true));
4179 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4180 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4183 afs->mark_for_remove ();
4186 (*src)->drop_references ();
4190 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4191 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4194 afs->done_with_peakfile_writes ();
4198 g_atomic_int_set (&processing_prohibited, 0);
4204 Session::get_silent_buffers (ChanCount count)
4206 assert(_silent_buffers->available() >= count);
4207 _silent_buffers->set_count(count);
4209 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4210 for (size_t i= 0; i < count.get(*t); ++i) {
4211 _silent_buffers->get(*t, i).clear();
4215 return *_silent_buffers;
4219 Session::get_scratch_buffers (ChanCount count)
4221 assert(_scratch_buffers->available() >= count);
4222 _scratch_buffers->set_count(count);
4223 return *_scratch_buffers;
4227 Session::get_mix_buffers (ChanCount count)
4229 assert(_mix_buffers->available() >= count);
4230 _mix_buffers->set_count(count);
4231 return *_mix_buffers;
4235 Session::ntracks () const
4238 shared_ptr<RouteList> r = routes.reader ();
4240 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4241 if (dynamic_cast<Track*> ((*i).get())) {
4250 Session::nbusses () const
4253 shared_ptr<RouteList> r = routes.reader ();
4255 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4256 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4265 Session::add_automation_list(AutomationList *al)
4267 automation_lists[al->id()] = al;
4271 Session::compute_initial_length ()
4273 return _engine.frame_rate() * 60 * 5;
4277 Session::sync_order_keys ()
4279 if (!Config->get_sync_all_route_ordering()) {
4280 /* leave order keys as they are */
4284 boost::shared_ptr<RouteList> r = routes.reader ();
4286 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4287 (*i)->sync_order_keys ();
4290 Route::SyncOrderKeys (); // EMIT SIGNAL
4294 Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
4296 Glib::Mutex::Lock lm (bundle_lock);
4297 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {