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/slave.h>
68 #include <ardour/tempo.h>
69 #include <ardour/audio_track.h>
70 #include <ardour/midi_track.h>
71 #include <ardour/cycle_timer.h>
72 #include <ardour/named_selection.h>
73 #include <ardour/crossfade.h>
74 #include <ardour/playlist.h>
75 #include <ardour/click.h>
76 #include <ardour/data_type.h>
77 #include <ardour/buffer_set.h>
78 #include <ardour/source_factory.h>
79 #include <ardour/region_factory.h>
80 #include <ardour/filename_extensions.h>
81 #include <ardour/session_directory.h>
82 #include <ardour/tape_file_matcher.h>
83 #include <ardour/analyser.h>
84 #include <ardour/audio_buffer.h>
85 #include <ardour/bundle.h>
90 using namespace ARDOUR;
92 using boost::shared_ptr;
95 static const int CPU_CACHE_ALIGN = 64;
97 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
100 bool Session::_disable_all_loaded_plugins = false;
102 sigc::signal<void,std::string> Session::Dialog;
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
105 sigc::signal<void> Session::SendFeedback;
107 sigc::signal<void> Session::SMPTEOffsetChanged;
108 sigc::signal<void> Session::StartTimeChanged;
109 sigc::signal<void> Session::EndTimeChanged;
110 sigc::signal<void> Session::AutoBindingOn;
111 sigc::signal<void> Session::AutoBindingOff;
112 sigc::signal<void, std::string, std::string> Session::Exported;
114 Session::Session (AudioEngine &eng,
115 const string& fullpath,
116 const string& snapshot_name,
120 _scratch_buffers(new BufferSet()),
121 _silent_buffers(new BufferSet()),
122 _mix_buffers(new BufferSet()),
124 _mmc_port (default_mmc_port),
125 _mtc_port (default_mtc_port),
126 _midi_port (default_midi_port),
127 _midi_clock_port (default_midi_clock_port),
128 _session_dir (new SessionDirectory(fullpath)),
129 pending_events (2048),
131 butler_mixdown_buffer (0),
132 butler_gain_buffer (0),
133 post_transport_work((PostTransportWork)0),
134 _send_smpte_update (false),
135 midi_thread (pthread_t (0)),
136 midi_requests (128), // the size of this should match the midi request pool size
137 diskstreams (new DiskstreamList),
138 routes (new RouteList),
139 auditioner ((Auditioner*) 0),
140 _total_free_4k_blocks (0),
141 _bundle_xml_node (0),
144 click_emphasis_data (0),
146 _metadata (new SessionMetadata())
151 if (!eng.connected()) {
152 throw failed_constructor();
155 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
157 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
158 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
160 first_stage_init (fullpath, snapshot_name);
162 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
165 if (create (new_session, mix_template, compute_initial_length())) {
167 throw failed_constructor ();
171 if (second_stage_init (new_session)) {
173 throw failed_constructor ();
176 store_recent_sessions(_name, _path);
178 bool was_dirty = dirty();
180 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
182 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
185 DirtyChanged (); /* EMIT SIGNAL */
189 Session::Session (AudioEngine &eng,
191 string snapshot_name,
192 AutoConnectOption input_ac,
193 AutoConnectOption output_ac,
194 uint32_t control_out_channels,
195 uint32_t master_out_channels,
196 uint32_t requested_physical_in,
197 uint32_t requested_physical_out,
198 nframes_t initial_length)
201 _scratch_buffers(new BufferSet()),
202 _silent_buffers(new BufferSet()),
203 _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),
212 butler_mixdown_buffer (0),
213 butler_gain_buffer (0),
214 post_transport_work((PostTransportWork)0),
215 _send_smpte_update (false),
216 midi_thread (pthread_t (0)),
218 diskstreams (new DiskstreamList),
219 routes (new RouteList),
220 auditioner ((Auditioner *) 0),
221 _total_free_4k_blocks (0),
222 _bundle_xml_node (0),
223 _click_io ((IO *) 0),
225 click_emphasis_data (0),
227 _metadata (new SessionMetadata())
231 if (!eng.connected()) {
232 throw failed_constructor();
235 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
237 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
238 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
240 if (n_physical_inputs) {
241 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
244 if (n_physical_outputs) {
245 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
248 first_stage_init (fullpath, snapshot_name);
250 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
253 if (create (new_session, string(), initial_length)) {
255 throw failed_constructor ();
260 /* set up Master Out and Control Out if necessary */
265 if (control_out_channels) {
266 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
267 r->set_remote_control_id (control_id++);
272 if (master_out_channels) {
273 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
274 r->set_remote_control_id (control_id);
278 /* prohibit auto-connect to master, because there isn't one */
279 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
283 add_routes (rl, false);
288 Config->set_input_auto_connect (input_ac);
289 Config->set_output_auto_connect (output_ac);
291 if (second_stage_init (new_session)) {
293 throw failed_constructor ();
296 store_recent_sessions (_name, _path);
298 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
300 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
311 /* if we got to here, leaving pending capture state around
315 remove_pending_capture_state ();
317 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
319 _engine.remove_session ();
321 GoingAway (); /* EMIT SIGNAL */
327 /* clear history so that no references to objects are held any more */
331 /* clear state tree so that no references to objects are held any more */
335 terminate_butler_thread ();
336 //terminate_midi_thread ();
338 if (click_data != default_click) {
339 delete [] click_data;
342 if (click_emphasis_data != default_click_emphasis) {
343 delete [] click_emphasis_data;
348 delete _scratch_buffers;
349 delete _silent_buffers;
352 AudioDiskstream::free_working_buffers();
354 Route::SyncOrderKeys.clear();
356 #undef TRACK_DESTRUCTION
357 #ifdef TRACK_DESTRUCTION
358 cerr << "delete named selections\n";
359 #endif /* TRACK_DESTRUCTION */
360 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
361 NamedSelectionList::iterator tmp;
370 #ifdef TRACK_DESTRUCTION
371 cerr << "delete playlists\n";
372 #endif /* TRACK_DESTRUCTION */
373 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
374 PlaylistList::iterator tmp;
379 (*i)->drop_references ();
384 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
385 PlaylistList::iterator tmp;
390 (*i)->drop_references ();
396 unused_playlists.clear ();
398 #ifdef TRACK_DESTRUCTION
399 cerr << "delete regions\n";
400 #endif /* TRACK_DESTRUCTION */
402 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
403 RegionList::iterator tmp;
408 i->second->drop_references ();
415 #ifdef TRACK_DESTRUCTION
416 cerr << "delete routes\n";
417 #endif /* TRACK_DESTRUCTION */
419 RCUWriter<RouteList> writer (routes);
420 boost::shared_ptr<RouteList> r = writer.get_copy ();
421 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
422 (*i)->drop_references ();
425 /* writer goes out of scope and updates master */
430 #ifdef TRACK_DESTRUCTION
431 cerr << "delete diskstreams\n";
432 #endif /* TRACK_DESTRUCTION */
434 RCUWriter<DiskstreamList> dwriter (diskstreams);
435 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
436 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
437 (*i)->drop_references ();
441 diskstreams.flush ();
443 #ifdef TRACK_DESTRUCTION
444 cerr << "delete audio sources\n";
445 #endif /* TRACK_DESTRUCTION */
446 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
447 SourceMap::iterator tmp;
452 i->second->drop_references ();
458 #ifdef TRACK_DESTRUCTION
459 cerr << "delete mix groups\n";
460 #endif /* TRACK_DESTRUCTION */
461 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
462 list<RouteGroup*>::iterator tmp;
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete edit groups\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
476 list<RouteGroup*>::iterator tmp;
486 delete [] butler_mixdown_buffer;
487 delete [] butler_gain_buffer;
489 Crossfade::set_buffer_size (0);
495 Session::set_worst_io_latencies ()
497 _worst_output_latency = 0;
498 _worst_input_latency = 0;
500 if (!_engine.connected()) {
504 boost::shared_ptr<RouteList> r = routes.reader ();
506 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
507 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
508 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
513 Session::when_engine_running ()
515 string first_physical_output;
517 /* we don't want to run execute this again */
519 BootMessage (_("Set block size and sample rate"));
521 set_block_size (_engine.frames_per_cycle());
522 set_frame_rate (_engine.frame_rate());
524 BootMessage (_("Using configuration"));
526 Config->map_parameters (mem_fun (*this, &Session::config_changed));
528 /* every time we reconnect, recompute worst case output latencies */
530 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
532 if (synced_to_jack()) {
533 _engine.transport_stop ();
536 if (Config->get_jack_time_master()) {
537 _engine.transport_locate (_transport_frame);
545 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
547 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
549 /* existing state for Click */
551 if (_click_io->set_state (*child->children().front()) == 0) {
553 _clicking = Config->get_clicking ();
557 error << _("could not setup Click I/O") << endmsg;
563 /* default state for Click */
565 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
567 if (first_physical_output.length()) {
568 if (_click_io->add_output_port (first_physical_output, this)) {
569 // relax, even though its an error
571 _clicking = Config->get_clicking ();
577 catch (failed_constructor& err) {
578 error << _("cannot setup Click I/O") << endmsg;
581 BootMessage (_("Compute I/O Latencies"));
583 set_worst_io_latencies ();
586 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
589 BootMessage (_("Set up standard connections"));
591 /* Create a set of Bundle objects that map
592 to the physical I/O currently available */
594 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
596 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
598 shared_ptr<Bundle> c (new Bundle (buf, true));
599 c->add_channel (_("mono"));
600 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
605 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
607 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
609 shared_ptr<Bundle> c (new Bundle (buf, false));
610 c->add_channel (_("mono"));
611 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
618 /* create master/control ports */
623 /* force the master to ignore any later call to this */
625 if (_master_out->pending_state_node) {
626 _master_out->ports_became_legal();
629 /* no panner resets till we are through */
631 _master_out->defer_pan_reset ();
633 while (_master_out->n_inputs().n_audio()
634 < _master_out->input_maximum().n_audio()) {
635 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
636 error << _("cannot setup master inputs")
642 while (_master_out->n_outputs().n_audio()
643 < _master_out->output_maximum().n_audio()) {
644 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
645 error << _("cannot setup master outputs")
652 _master_out->allow_pan_reset ();
657 BootMessage (_("Setup signal flow and plugins"));
661 /* catch up on send+insert cnts */
663 BootMessage (_("Catch up with send/insert state"));
667 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
670 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
671 if (id > insert_cnt) {
679 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
682 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
690 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
692 /* hook us up to the engine */
694 BootMessage (_("Connect to engine"));
696 _engine.set_session (this);
700 Session::hookup_io ()
702 /* stop graph reordering notifications from
703 causing resorts, etc.
706 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
709 if (auditioner == 0) {
711 /* we delay creating the auditioner till now because
712 it makes its own connections to ports.
713 the engine has to be running for this to work.
717 auditioner.reset (new Auditioner (*this));
720 catch (failed_constructor& err) {
721 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
725 /* Tell all IO objects to create their ports */
731 vector<string> cports;
733 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
734 if (_control_out->add_input_port ("", this)) {
735 error << _("cannot setup control inputs")
741 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
742 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
743 error << _("cannot set up master outputs")
751 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
753 for (n = 0; n < ni; ++n) {
754 cports.push_back (_control_out->input(n)->name());
757 boost::shared_ptr<RouteList> r = routes.reader ();
759 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
760 (*x)->set_control_outs (cports);
764 /* load bundles, which we may have postponed earlier on */
765 if (_bundle_xml_node) {
766 load_bundles (*_bundle_xml_node);
767 delete _bundle_xml_node;
770 /* Tell all IO objects to connect themselves together */
772 IO::enable_connecting ();
774 /* Now reset all panners */
776 IO::reset_panners ();
778 /* Anyone who cares about input state, wake up and do something */
780 IOConnectionsComplete (); /* EMIT SIGNAL */
782 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
785 /* now handle the whole enchilada as if it was one
791 /* update mixer solo state */
797 Session::playlist_length_changed ()
799 /* we can't just increase end_location->end() if pl->get_maximum_extent()
800 if larger. if the playlist used to be the longest playlist,
801 and its now shorter, we have to decrease end_location->end(). hence,
802 we have to iterate over all diskstreams and check the
803 playlists currently in use.
809 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
811 boost::shared_ptr<Playlist> playlist;
813 if ((playlist = dstream->playlist()) != 0) {
814 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
817 /* see comment in playlist_length_changed () */
822 Session::record_enabling_legal () const
824 /* this used to be in here, but survey says.... we don't need to restrict it */
825 // if (record_status() == Recording) {
829 if (Config->get_all_safe()) {
836 Session::reset_input_monitor_state ()
838 if (transport_rolling()) {
840 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
842 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
843 if ((*i)->record_enabled ()) {
844 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
845 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
849 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
851 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
852 if ((*i)->record_enabled ()) {
853 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
854 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
861 Session::auto_punch_start_changed (Location* location)
863 replace_event (Event::PunchIn, location->start());
865 if (get_record_enabled() && Config->get_punch_in()) {
866 /* capture start has been changed, so save new pending state */
867 save_state ("", true);
872 Session::auto_punch_end_changed (Location* location)
874 nframes_t when_to_stop = location->end();
875 // when_to_stop += _worst_output_latency + _worst_input_latency;
876 replace_event (Event::PunchOut, when_to_stop);
880 Session::auto_punch_changed (Location* location)
882 nframes_t when_to_stop = location->end();
884 replace_event (Event::PunchIn, location->start());
885 //when_to_stop += _worst_output_latency + _worst_input_latency;
886 replace_event (Event::PunchOut, when_to_stop);
890 Session::auto_loop_changed (Location* location)
892 replace_event (Event::AutoLoop, location->end(), location->start());
894 if (transport_rolling() && play_loop) {
896 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
898 if (_transport_frame > location->end()) {
899 // relocate to beginning of loop
900 clear_events (Event::LocateRoll);
902 request_locate (location->start(), true);
905 else if (Config->get_seamless_loop() && !loop_changing) {
907 // schedule a locate-roll to refill the diskstreams at the
909 loop_changing = true;
911 if (location->end() > last_loopend) {
912 clear_events (Event::LocateRoll);
913 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
920 last_loopend = location->end();
924 Session::set_auto_punch_location (Location* location)
928 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
929 auto_punch_start_changed_connection.disconnect();
930 auto_punch_end_changed_connection.disconnect();
931 auto_punch_changed_connection.disconnect();
932 existing->set_auto_punch (false, this);
933 remove_event (existing->start(), Event::PunchIn);
934 clear_events (Event::PunchOut);
935 auto_punch_location_changed (0);
944 if (location->end() <= location->start()) {
945 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
949 auto_punch_start_changed_connection.disconnect();
950 auto_punch_end_changed_connection.disconnect();
951 auto_punch_changed_connection.disconnect();
953 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
954 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
955 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
957 location->set_auto_punch (true, this);
960 auto_punch_changed (location);
962 auto_punch_location_changed (location);
966 Session::set_auto_loop_location (Location* location)
970 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
971 auto_loop_start_changed_connection.disconnect();
972 auto_loop_end_changed_connection.disconnect();
973 auto_loop_changed_connection.disconnect();
974 existing->set_auto_loop (false, this);
975 remove_event (existing->end(), Event::AutoLoop);
976 auto_loop_location_changed (0);
985 if (location->end() <= location->start()) {
986 error << _("Session: you can't use a mark for auto loop") << endmsg;
990 last_loopend = location->end();
992 auto_loop_start_changed_connection.disconnect();
993 auto_loop_end_changed_connection.disconnect();
994 auto_loop_changed_connection.disconnect();
996 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
997 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
998 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1000 location->set_auto_loop (true, this);
1002 /* take care of our stuff first */
1004 auto_loop_changed (location);
1006 /* now tell everyone else */
1008 auto_loop_location_changed (location);
1012 Session::locations_added (Location* ignored)
1018 Session::locations_changed ()
1020 _locations.apply (*this, &Session::handle_locations_changed);
1024 Session::handle_locations_changed (Locations::LocationList& locations)
1026 Locations::LocationList::iterator i;
1028 bool set_loop = false;
1029 bool set_punch = false;
1031 for (i = locations.begin(); i != locations.end(); ++i) {
1035 if (location->is_auto_punch()) {
1036 set_auto_punch_location (location);
1039 if (location->is_auto_loop()) {
1040 set_auto_loop_location (location);
1044 if (location->is_start()) {
1045 start_location = location;
1047 if (location->is_end()) {
1048 end_location = location;
1053 set_auto_loop_location (0);
1056 set_auto_punch_location (0);
1063 Session::enable_record ()
1065 /* XXX really atomic compare+swap here */
1066 if (g_atomic_int_get (&_record_status) != Recording) {
1067 g_atomic_int_set (&_record_status, Recording);
1068 _last_record_location = _transport_frame;
1069 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1071 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1072 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1073 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1074 if ((*i)->record_enabled ()) {
1075 (*i)->monitor_input (true);
1080 RecordStateChanged ();
1085 Session::disable_record (bool rt_context, bool force)
1089 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1091 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1092 g_atomic_int_set (&_record_status, Disabled);
1094 if (rs == Recording) {
1095 g_atomic_int_set (&_record_status, Enabled);
1099 // FIXME: timestamp correct? [DR]
1100 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1101 // does this /need/ to be sent in all cases?
1103 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1105 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1106 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1108 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1109 if ((*i)->record_enabled ()) {
1110 (*i)->monitor_input (false);
1115 RecordStateChanged (); /* emit signal */
1118 remove_pending_capture_state ();
1124 Session::step_back_from_record ()
1126 /* XXX really atomic compare+swap here */
1127 if (g_atomic_int_get (&_record_status) == Recording) {
1128 g_atomic_int_set (&_record_status, Enabled);
1130 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1131 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1133 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1134 if ((*i)->record_enabled ()) {
1135 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1136 (*i)->monitor_input (false);
1144 Session::maybe_enable_record ()
1146 g_atomic_int_set (&_record_status, Enabled);
1148 /* this function is currently called from somewhere other than an RT thread.
1149 this save_state() call therefore doesn't impact anything.
1152 save_state ("", true);
1154 if (_transport_speed) {
1155 if (!Config->get_punch_in()) {
1159 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1160 RecordStateChanged (); /* EMIT SIGNAL */
1167 Session::audible_frame () const
1173 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1174 return last_stop_frame;
1177 /* the first of these two possible settings for "offset"
1178 mean that the audible frame is stationary until
1179 audio emerges from the latency compensation
1182 the second means that the audible frame is stationary
1183 until audio would emerge from a physical port
1184 in the absence of any plugin latency compensation
1187 offset = _worst_output_latency;
1189 if (offset > current_block_size) {
1190 offset -= current_block_size;
1192 /* XXX is this correct? if we have no external
1193 physical connections and everything is internal
1194 then surely this is zero? still, how
1195 likely is that anyway?
1197 offset = current_block_size;
1200 if (synced_to_jack()) {
1201 tf = _engine.transport_frame();
1203 tf = _transport_frame;
1208 if (!non_realtime_work_pending()) {
1212 /* check to see if we have passed the first guaranteed
1213 audible frame past our last stopping position. if not,
1214 the return that last stopping point because in terms
1215 of audible frames, we have not moved yet.
1218 if (_transport_speed > 0.0f) {
1220 if (!play_loop || !have_looped) {
1221 if (tf < last_stop_frame + offset) {
1222 return last_stop_frame;
1231 } else if (_transport_speed < 0.0f) {
1233 /* XXX wot? no backward looping? */
1235 if (tf > last_stop_frame - offset) {
1236 return last_stop_frame;
1248 Session::set_frame_rate (nframes_t frames_per_second)
1250 /** \fn void Session::set_frame_size(nframes_t)
1251 the AudioEngine object that calls this guarantees
1252 that it will not be called while we are also in
1253 ::process(). Its fine to do things that block
1257 _base_frame_rate = frames_per_second;
1261 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1265 // XXX we need some equivalent to this, somehow
1266 // SndFileSource::setup_standard_crossfades (frames_per_second);
1270 /* XXX need to reset/reinstantiate all LADSPA plugins */
1274 Session::set_block_size (nframes_t nframes)
1276 /* the AudioEngine guarantees
1277 that it will not be called while we are also in
1278 ::process(). It is therefore fine to do things that block
1284 current_block_size = nframes;
1286 ensure_buffers(_scratch_buffers->available());
1288 delete [] _gain_automation_buffer;
1289 _gain_automation_buffer = new gain_t[nframes];
1291 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1293 boost::shared_ptr<RouteList> r = routes.reader ();
1295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1296 (*i)->set_block_size (nframes);
1299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1300 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1301 (*i)->set_block_size (nframes);
1304 set_worst_io_latencies ();
1309 Session::set_default_fade (float steepness, float fade_msecs)
1312 nframes_t fade_frames;
1314 /* Don't allow fade of less 1 frame */
1316 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1323 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1327 default_fade_msecs = fade_msecs;
1328 default_fade_steepness = steepness;
1331 // jlc, WTF is this!
1332 Glib::RWLock::ReaderLock lm (route_lock);
1333 AudioRegion::set_default_fade (steepness, fade_frames);
1338 /* XXX have to do this at some point */
1339 /* foreach region using default fade, reset, then
1340 refill_all_diskstream_buffers ();
1345 struct RouteSorter {
1346 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1347 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1349 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1352 if (r1->fed_by.empty()) {
1353 if (r2->fed_by.empty()) {
1354 /* no ardour-based connections inbound to either route. just use signal order */
1355 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1357 /* r2 has connections, r1 does not; run r1 early */
1361 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1368 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1370 shared_ptr<Route> r2;
1372 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1373 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1377 /* make a copy of the existing list of routes that feed r1 */
1379 set<shared_ptr<Route> > existing = r1->fed_by;
1381 /* for each route that feeds r1, recurse, marking it as feeding
1385 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1388 /* r2 is a route that feeds r1 which somehow feeds base. mark
1389 base as being fed by r2
1392 rbase->fed_by.insert (r2);
1396 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1400 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1404 /* now recurse, so that we can mark base as being fed by
1405 all routes that feed r2
1408 trace_terminal (r2, rbase);
1415 Session::resort_routes ()
1417 /* don't do anything here with signals emitted
1418 by Routes while we are being destroyed.
1421 if (_state_of_the_state & Deletion) {
1428 RCUWriter<RouteList> writer (routes);
1429 shared_ptr<RouteList> r = writer.get_copy ();
1430 resort_routes_using (r);
1431 /* writer goes out of scope and forces update */
1436 Session::resort_routes_using (shared_ptr<RouteList> r)
1438 RouteList::iterator i, j;
1440 for (i = r->begin(); i != r->end(); ++i) {
1442 (*i)->fed_by.clear ();
1444 for (j = r->begin(); j != r->end(); ++j) {
1446 /* although routes can feed themselves, it will
1447 cause an endless recursive descent if we
1448 detect it. so don't bother checking for
1456 if ((*j)->feeds (*i)) {
1457 (*i)->fed_by.insert (*j);
1462 for (i = r->begin(); i != r->end(); ++i) {
1463 trace_terminal (*i, *i);
1470 cerr << "finished route resort\n";
1472 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1473 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1480 list<boost::shared_ptr<MidiTrack> >
1481 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1483 char track_name[32];
1484 uint32_t track_id = 0;
1487 RouteList new_routes;
1488 list<boost::shared_ptr<MidiTrack> > ret;
1489 //uint32_t control_id;
1491 // FIXME: need physical I/O and autoconnect stuff for MIDI
1493 /* count existing midi tracks */
1496 shared_ptr<RouteList> r = routes.reader ();
1498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1499 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1500 if (!(*i)->is_hidden()) {
1502 //channels_used += (*i)->n_inputs().n_midi();
1508 vector<string> physinputs;
1509 vector<string> physoutputs;
1511 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1512 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1514 // control_id = ntracks() + nbusses();
1518 /* check for duplicate route names, since we might have pre-existing
1519 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1520 save, close,restart,add new route - first named route is now
1528 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1530 if (route_by_name (track_name) == 0) {
1534 } while (track_id < (UINT_MAX-1));
1536 shared_ptr<MidiTrack> track;
1539 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1541 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1542 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1548 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1552 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1553 port = physinputs[(channels_used+x)%nphysical_in];
1556 if (port.length() && track->connect_input (track->input (x), port, this)) {
1562 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1566 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1567 port = physoutputs[(channels_used+x)%nphysical_out];
1568 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1570 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1574 if (port.length() && track->connect_output (track->output (x), port, this)) {
1579 channels_used += track->n_inputs ().n_midi();
1583 track->midi_diskstream()->non_realtime_input_change();
1585 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1586 //track->set_remote_control_id (control_id);
1588 new_routes.push_back (track);
1589 ret.push_back (track);
1592 catch (failed_constructor &err) {
1593 error << _("Session: could not create new midi track.") << endmsg;
1596 /* we need to get rid of this, since the track failed to be created */
1597 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1600 RCUWriter<DiskstreamList> writer (diskstreams);
1601 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1602 ds->remove (track->midi_diskstream());
1609 catch (AudioEngine::PortRegistrationFailure& pfe) {
1611 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;
1614 /* we need to get rid of this, since the track failed to be created */
1615 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1618 RCUWriter<DiskstreamList> writer (diskstreams);
1619 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1620 ds->remove (track->midi_diskstream());
1631 if (!new_routes.empty()) {
1632 add_routes (new_routes, false);
1633 save_state (_current_snapshot_name);
1639 list<boost::shared_ptr<AudioTrack> >
1640 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1642 char track_name[32];
1643 uint32_t track_id = 0;
1645 uint32_t channels_used = 0;
1647 RouteList new_routes;
1648 list<boost::shared_ptr<AudioTrack> > ret;
1649 uint32_t control_id;
1651 /* count existing audio tracks */
1654 shared_ptr<RouteList> r = routes.reader ();
1656 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1657 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1658 if (!(*i)->is_hidden()) {
1660 channels_used += (*i)->n_inputs().n_audio();
1666 vector<string> physinputs;
1667 vector<string> physoutputs;
1669 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1670 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1672 control_id = ntracks() + nbusses() + 1;
1676 /* check for duplicate route names, since we might have pre-existing
1677 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1678 save, close,restart,add new route - first named route is now
1686 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1688 if (route_by_name (track_name) == 0) {
1692 } while (track_id < (UINT_MAX-1));
1694 shared_ptr<AudioTrack> track;
1697 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1699 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1700 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1701 input_channels, output_channels)
1706 if (!physinputs.empty()) {
1707 uint32_t nphysical_in = physinputs.size();
1709 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1713 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1714 port = physinputs[(channels_used+x)%nphysical_in];
1717 if (port.length() && track->connect_input (track->input (x), port, this)) {
1723 if (!physoutputs.empty()) {
1724 uint32_t nphysical_out = physoutputs.size();
1726 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1730 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1731 port = physoutputs[(channels_used+x)%nphysical_out];
1732 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1734 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1738 if (port.length() && track->connect_output (track->output (x), port, this)) {
1744 channels_used += track->n_inputs ().n_audio();
1746 track->audio_diskstream()->non_realtime_input_change();
1748 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1749 track->set_remote_control_id (control_id);
1752 new_routes.push_back (track);
1753 ret.push_back (track);
1756 catch (failed_constructor &err) {
1757 error << _("Session: could not create new audio track.") << endmsg;
1760 /* we need to get rid of this, since the track failed to be created */
1761 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1764 RCUWriter<DiskstreamList> writer (diskstreams);
1765 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1766 ds->remove (track->audio_diskstream());
1773 catch (AudioEngine::PortRegistrationFailure& pfe) {
1775 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;
1778 /* we need to get rid of this, since the track failed to be created */
1779 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1782 RCUWriter<DiskstreamList> writer (diskstreams);
1783 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1784 ds->remove (track->audio_diskstream());
1795 if (!new_routes.empty()) {
1796 add_routes (new_routes, true);
1803 Session::set_remote_control_ids ()
1805 RemoteModel m = Config->get_remote_model();
1807 shared_ptr<RouteList> r = routes.reader ();
1809 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1810 if ( MixerOrdered == m) {
1811 long order = (*i)->order_key(N_("signal"));
1812 (*i)->set_remote_control_id( order+1 );
1813 } else if ( EditorOrdered == m) {
1814 long order = (*i)->order_key(N_("editor"));
1815 (*i)->set_remote_control_id( order+1 );
1816 } else if ( UserOrdered == m) {
1817 //do nothing ... only changes to remote id's are initiated by user
1824 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1827 uint32_t bus_id = 1;
1829 uint32_t channels_used = 0;
1832 uint32_t control_id;
1834 /* count existing audio busses */
1837 shared_ptr<RouteList> r = routes.reader ();
1839 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1840 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1842 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1845 channels_used += (*i)->n_inputs().n_audio();
1851 vector<string> physinputs;
1852 vector<string> physoutputs;
1854 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1855 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1857 n_physical_audio_outputs = physoutputs.size();
1858 n_physical_audio_inputs = physinputs.size();
1860 control_id = ntracks() + nbusses() + 1;
1865 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1869 if (route_by_name (bus_name) == 0) {
1873 } while (bus_id < (UINT_MAX-1));
1876 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1878 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1879 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1880 input_channels, output_channels)
1888 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1892 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1893 port = physinputs[((n+x)%n_physical_audio_inputs)];
1896 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1902 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1905 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1906 port = physoutputs[((n+x)%n_physical_outputs)];
1907 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1909 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1913 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1918 channels_used += bus->n_inputs ().n_audio();
1920 bus->set_remote_control_id (control_id);
1923 ret.push_back (bus);
1927 catch (failed_constructor &err) {
1928 error << _("Session: could not create new audio route.") << endmsg;
1932 catch (AudioEngine::PortRegistrationFailure& pfe) {
1933 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;
1943 add_routes (ret, true);
1951 Session::add_routes (RouteList& new_routes, bool save)
1954 RCUWriter<RouteList> writer (routes);
1955 shared_ptr<RouteList> r = writer.get_copy ();
1956 r->insert (r->end(), new_routes.begin(), new_routes.end());
1957 resort_routes_using (r);
1960 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1962 boost::weak_ptr<Route> wpr (*x);
1964 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1965 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1966 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1967 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
1969 if ((*x)->is_master()) {
1973 if ((*x)->is_control()) {
1974 _control_out = (*x);
1978 if (_control_out && IO::connecting_legal) {
1980 vector<string> cports;
1981 uint32_t ni = _control_out->n_inputs().n_audio();
1983 for (uint32_t n = 0; n < ni; ++n) {
1984 cports.push_back (_control_out->input(n)->name());
1987 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1988 (*x)->set_control_outs (cports);
1995 save_state (_current_snapshot_name);
1998 RouteAdded (new_routes); /* EMIT SIGNAL */
2002 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2004 /* need to do this in case we're rolling at the time, to prevent false underruns */
2005 dstream->do_refill_with_alloc ();
2007 dstream->set_block_size (current_block_size);
2010 RCUWriter<DiskstreamList> writer (diskstreams);
2011 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2012 ds->push_back (dstream);
2013 /* writer goes out of scope, copies ds back to main */
2016 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2017 /* this will connect to future changes, and check the current length */
2018 diskstream_playlist_changed (dstream);
2020 dstream->prepare ();
2025 Session::remove_route (shared_ptr<Route> route)
2028 RCUWriter<RouteList> writer (routes);
2029 shared_ptr<RouteList> rs = writer.get_copy ();
2033 /* deleting the master out seems like a dumb
2034 idea, but its more of a UI policy issue
2038 if (route == _master_out) {
2039 _master_out = shared_ptr<Route> ();
2042 if (route == _control_out) {
2043 _control_out = shared_ptr<Route> ();
2045 /* cancel control outs for all routes */
2047 vector<string> empty;
2049 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2050 (*r)->set_control_outs (empty);
2054 update_route_solo_state ();
2056 /* writer goes out of scope, forces route list update */
2060 boost::shared_ptr<Diskstream> ds;
2062 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2063 ds = t->diskstream();
2069 RCUWriter<DiskstreamList> dsl (diskstreams);
2070 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2075 find_current_end ();
2077 // We need to disconnect the routes inputs and outputs
2079 route->disconnect_inputs (0);
2080 route->disconnect_outputs (0);
2082 update_latency_compensation (false, false);
2085 /* get rid of it from the dead wood collection in the route list manager */
2087 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2091 /* try to cause everyone to drop their references */
2093 route->drop_references ();
2095 sync_order_keys (N_("session"));
2097 /* save the new state of the world */
2099 if (save_state (_current_snapshot_name)) {
2100 save_history (_current_snapshot_name);
2105 Session::route_mute_changed (void* src)
2111 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2113 if (solo_update_disabled) {
2119 boost::shared_ptr<Route> route = wpr.lock ();
2122 /* should not happen */
2123 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2127 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2129 shared_ptr<RouteList> r = routes.reader ();
2131 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2133 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2137 /* don't mess with busses */
2139 if (dynamic_cast<Track*>((*i).get()) == 0) {
2145 /* don't mess with tracks */
2147 if (dynamic_cast<Track*>((*i).get()) != 0) {
2152 if ((*i) != route &&
2153 ((*i)->mix_group () == 0 ||
2154 (*i)->mix_group () != route->mix_group () ||
2155 !route->mix_group ()->is_active())) {
2157 if ((*i)->soloed()) {
2159 /* if its already soloed, and solo latching is enabled,
2160 then leave it as it is.
2163 if (Config->get_solo_latched()) {
2170 solo_update_disabled = true;
2171 (*i)->set_solo (false, src);
2172 solo_update_disabled = false;
2176 bool something_soloed = false;
2177 bool same_thing_soloed = false;
2178 bool signal = false;
2180 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2181 if ((*i)->soloed()) {
2182 something_soloed = true;
2183 if (dynamic_cast<Track*>((*i).get())) {
2185 same_thing_soloed = true;
2190 same_thing_soloed = true;
2198 if (something_soloed != currently_soloing) {
2200 currently_soloing = something_soloed;
2203 modify_solo_mute (is_track, same_thing_soloed);
2206 SoloActive (currently_soloing); /* EMIT SIGNAL */
2209 SoloChanged (); /* EMIT SIGNAL */
2215 Session::update_route_solo_state ()
2218 bool is_track = false;
2219 bool signal = false;
2221 /* this is where we actually implement solo by changing
2222 the solo mute setting of each track.
2225 shared_ptr<RouteList> r = routes.reader ();
2227 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2228 if ((*i)->soloed()) {
2230 if (dynamic_cast<Track*>((*i).get())) {
2237 if (mute != currently_soloing) {
2239 currently_soloing = mute;
2242 if (!is_track && !mute) {
2244 /* nothing is soloed */
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 (*i)->set_solo_mute (false);
2257 modify_solo_mute (is_track, mute);
2260 SoloActive (currently_soloing);
2265 Session::modify_solo_mute (bool is_track, bool mute)
2267 shared_ptr<RouteList> r = routes.reader ();
2269 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2273 /* only alter track solo mute */
2275 if (dynamic_cast<Track*>((*i).get())) {
2276 if ((*i)->soloed()) {
2277 (*i)->set_solo_mute (!mute);
2279 (*i)->set_solo_mute (mute);
2285 /* only alter bus solo mute */
2287 if (!dynamic_cast<Track*>((*i).get())) {
2289 if ((*i)->soloed()) {
2291 (*i)->set_solo_mute (false);
2295 /* don't mute master or control outs
2296 in response to another bus solo
2299 if ((*i) != _master_out &&
2300 (*i) != _control_out) {
2301 (*i)->set_solo_mute (mute);
2312 Session::catch_up_on_solo ()
2314 /* this is called after set_state() to catch the full solo
2315 state, which can't be correctly determined on a per-route
2316 basis, but needs the global overview that only the session
2319 update_route_solo_state();
2323 Session::catch_up_on_solo_mute_override ()
2325 if (Config->get_solo_model() != InverseMute) {
2329 /* this is called whenever the param solo-mute-override is
2332 shared_ptr<RouteList> r = routes.reader ();
2334 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2335 (*i)->catch_up_on_solo_mute_override ();
2340 Session::route_by_name (string name)
2342 shared_ptr<RouteList> r = routes.reader ();
2344 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2345 if ((*i)->name() == name) {
2350 return shared_ptr<Route> ((Route*) 0);
2354 Session::route_by_id (PBD::ID id)
2356 shared_ptr<RouteList> r = routes.reader ();
2358 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2359 if ((*i)->id() == id) {
2364 return shared_ptr<Route> ((Route*) 0);
2368 Session::route_by_remote_id (uint32_t id)
2370 shared_ptr<RouteList> r = routes.reader ();
2372 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2373 if ((*i)->remote_control_id() == id) {
2378 return shared_ptr<Route> ((Route*) 0);
2382 Session::find_current_end ()
2384 if (_state_of_the_state & Loading) {
2388 nframes_t max = get_maximum_extent ();
2390 if (max > end_location->end()) {
2391 end_location->set_end (max);
2393 DurationChanged(); /* EMIT SIGNAL */
2398 Session::get_maximum_extent () const
2403 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2405 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2406 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2408 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2409 if ((me = pl->get_maximum_extent()) > max) {
2417 boost::shared_ptr<Diskstream>
2418 Session::diskstream_by_name (string name)
2420 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2422 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2423 if ((*i)->name() == name) {
2428 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2431 boost::shared_ptr<Diskstream>
2432 Session::diskstream_by_id (const PBD::ID& id)
2434 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2436 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2437 if ((*i)->id() == id) {
2442 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2445 /* Region management */
2448 Session::new_region_name (string old)
2450 string::size_type last_period;
2452 string::size_type len = old.length() + 64;
2455 if ((last_period = old.find_last_of ('.')) == string::npos) {
2457 /* no period present - add one explicitly */
2460 last_period = old.length() - 1;
2465 number = atoi (old.substr (last_period+1).c_str());
2469 while (number < (UINT_MAX-1)) {
2471 RegionList::const_iterator i;
2476 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2479 for (i = regions.begin(); i != regions.end(); ++i) {
2480 if (i->second->name() == sbuf) {
2485 if (i == regions.end()) {
2490 if (number != (UINT_MAX-1)) {
2494 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2499 Session::region_name (string& result, string base, bool newlevel)
2504 assert(base.find("/") == string::npos);
2508 Glib::Mutex::Lock lm (region_lock);
2510 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2519 string::size_type pos;
2521 pos = base.find_last_of ('.');
2523 /* pos may be npos, but then we just use entire base */
2525 subbase = base.substr (0, pos);
2530 Glib::Mutex::Lock lm (region_lock);
2532 map<string,uint32_t>::iterator x;
2536 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2538 region_name_map[subbase] = 1;
2541 snprintf (buf, sizeof (buf), ".%d", x->second);
2552 Session::add_region (boost::shared_ptr<Region> region)
2554 vector<boost::shared_ptr<Region> > v;
2555 v.push_back (region);
2560 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2565 Glib::Mutex::Lock lm (region_lock);
2567 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2569 boost::shared_ptr<Region> region = *ii;
2573 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2577 RegionList::iterator x;
2579 for (x = regions.begin(); x != regions.end(); ++x) {
2581 if (region->region_list_equivalent (x->second)) {
2586 if (x == regions.end()) {
2588 pair<RegionList::key_type,RegionList::mapped_type> entry;
2590 entry.first = region->id();
2591 entry.second = region;
2593 pair<RegionList::iterator,bool> x = regions.insert (entry);
2605 /* mark dirty because something has changed even if we didn't
2606 add the region to the region list.
2613 vector<boost::weak_ptr<Region> > v;
2614 boost::shared_ptr<Region> first_r;
2616 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2618 boost::shared_ptr<Region> region = *ii;
2622 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2625 v.push_back (region);
2632 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2633 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2635 update_region_name_map (region);
2639 RegionsAdded (v); /* EMIT SIGNAL */
2645 Session::update_region_name_map (boost::shared_ptr<Region> region)
2647 string::size_type last_period = region->name().find_last_of ('.');
2649 if (last_period != string::npos && last_period < region->name().length() - 1) {
2651 string base = region->name().substr (0, last_period);
2652 string number = region->name().substr (last_period+1);
2653 map<string,uint32_t>::iterator x;
2655 /* note that if there is no number, we get zero from atoi,
2659 region_name_map[base] = atoi (number);
2664 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2666 boost::shared_ptr<Region> region (weak_region.lock ());
2672 if (what_changed & Region::HiddenChanged) {
2673 /* relay hidden changes */
2674 RegionHiddenChange (region);
2677 if (what_changed & NameChanged) {
2678 update_region_name_map (region);
2683 Session::remove_region (boost::weak_ptr<Region> weak_region)
2685 RegionList::iterator i;
2686 boost::shared_ptr<Region> region (weak_region.lock ());
2692 bool removed = false;
2695 Glib::Mutex::Lock lm (region_lock);
2697 if ((i = regions.find (region->id())) != regions.end()) {
2703 /* mark dirty because something has changed even if we didn't
2704 remove the region from the region list.
2710 RegionRemoved(region); /* EMIT SIGNAL */
2714 boost::shared_ptr<Region>
2715 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2717 RegionList::iterator i;
2718 boost::shared_ptr<Region> region;
2720 Glib::Mutex::Lock lm (region_lock);
2722 for (i = regions.begin(); i != regions.end(); ++i) {
2726 if (region->whole_file()) {
2728 if (child->source_equivalent (region)) {
2734 return boost::shared_ptr<Region> ();
2738 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2740 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2741 (*i)->get_region_list_equivalent_regions (region, result);
2745 Session::destroy_region (boost::shared_ptr<Region> region)
2747 vector<boost::shared_ptr<Source> > srcs;
2750 if (region->playlist()) {
2751 region->playlist()->destroy_region (region);
2754 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2755 srcs.push_back (region->source (n));
2759 region->drop_references ();
2761 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2763 (*i)->mark_for_remove ();
2764 (*i)->drop_references ();
2766 cerr << "source was not used by any playlist\n";
2773 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2775 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2776 destroy_region (*i);
2782 Session::remove_last_capture ()
2784 list<boost::shared_ptr<Region> > r;
2786 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2788 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2789 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2792 r.insert (r.end(), l.begin(), l.end());
2797 destroy_regions (r);
2799 save_state (_current_snapshot_name);
2805 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2811 /* Source Management */
2813 Session::add_source (boost::shared_ptr<Source> source)
2815 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2816 pair<SourceMap::iterator,bool> result;
2818 entry.first = source->id();
2819 entry.second = source;
2822 Glib::Mutex::Lock lm (source_lock);
2823 result = sources.insert (entry);
2826 if (result.second) {
2827 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2831 boost::shared_ptr<AudioFileSource> afs;
2833 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2834 if (Config->get_auto_analyse_audio()) {
2835 Analyser::queue_source_for_analysis (source, false);
2841 Session::remove_source (boost::weak_ptr<Source> src)
2843 SourceMap::iterator i;
2844 boost::shared_ptr<Source> source = src.lock();
2851 Glib::Mutex::Lock lm (source_lock);
2853 if ((i = sources.find (source->id())) != sources.end()) {
2858 if (!_state_of_the_state & InCleanup) {
2860 /* save state so we don't end up with a session file
2861 referring to non-existent sources.
2864 save_state (_current_snapshot_name);
2868 boost::shared_ptr<Source>
2869 Session::source_by_id (const PBD::ID& id)
2871 Glib::Mutex::Lock lm (source_lock);
2872 SourceMap::iterator i;
2873 boost::shared_ptr<Source> source;
2875 if ((i = sources.find (id)) != sources.end()) {
2883 boost::shared_ptr<Source>
2884 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2886 Glib::Mutex::Lock lm (source_lock);
2888 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2889 cerr << "comparing " << path << " with " << i->second->name() << endl;
2890 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2892 if (afs && afs->path() == path && chn == afs->channel()) {
2897 return boost::shared_ptr<Source>();
2901 Session::peak_path (Glib::ustring base) const
2903 sys::path peakfile_path(_session_dir->peak_path());
2904 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2905 return peakfile_path.to_string();
2909 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2912 string old_basename = PBD::basename_nosuffix (oldname);
2913 string new_legalized = legalize_for_path (newname);
2915 /* note: we know (or assume) the old path is already valid */
2919 /* destructive file sources have a name of the form:
2921 /path/to/Tnnnn-NAME(%[LR])?.wav
2923 the task here is to replace NAME with the new name.
2926 /* find last slash */
2930 string::size_type slash;
2931 string::size_type dash;
2933 if ((slash = path.find_last_of ('/')) == string::npos) {
2937 dir = path.substr (0, slash+1);
2939 /* '-' is not a legal character for the NAME part of the path */
2941 if ((dash = path.find_last_of ('-')) == string::npos) {
2945 prefix = path.substr (slash+1, dash-(slash+1));
2950 path += new_legalized;
2951 path += ".wav"; /* XXX gag me with a spoon */
2955 /* non-destructive file sources have a name of the form:
2957 /path/to/NAME-nnnnn(%[LR])?.wav
2959 the task here is to replace NAME with the new name.
2964 string::size_type slash;
2965 string::size_type dash;
2966 string::size_type postfix;
2968 /* find last slash */
2970 if ((slash = path.find_last_of ('/')) == string::npos) {
2974 dir = path.substr (0, slash+1);
2976 /* '-' is not a legal character for the NAME part of the path */
2978 if ((dash = path.find_last_of ('-')) == string::npos) {
2982 suffix = path.substr (dash+1);
2984 // Suffix is now everything after the dash. Now we need to eliminate
2985 // the nnnnn part, which is done by either finding a '%' or a '.'
2987 postfix = suffix.find_last_of ("%");
2988 if (postfix == string::npos) {
2989 postfix = suffix.find_last_of ('.');
2992 if (postfix != string::npos) {
2993 suffix = suffix.substr (postfix);
2995 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2999 const uint32_t limit = 10000;
3000 char buf[PATH_MAX+1];
3002 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3004 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3006 if (access (buf, F_OK) != 0) {
3014 error << "FATAL ERROR! Could not find a " << endl;
3023 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3027 char buf[PATH_MAX+1];
3028 const uint32_t limit = 10000;
3032 legalized = legalize_for_path (name);
3034 /* find a "version" of the file name that doesn't exist in
3035 any of the possible directories.
3038 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3040 vector<space_and_path>::iterator i;
3041 uint32_t existing = 0;
3043 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3045 SessionDirectory sdir((*i).path);
3047 spath = sdir.sound_path().to_string();
3051 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3052 } else if (nchan == 2) {
3054 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3056 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3058 } else if (nchan < 26) {
3059 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3061 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3070 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3071 } else if (nchan == 2) {
3073 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3075 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3077 } else if (nchan < 26) {
3078 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3080 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3084 if (sys::exists(buf)) {
3090 if (existing == 0) {
3095 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3097 throw failed_constructor();
3101 /* we now have a unique name for the file, but figure out where to
3107 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3109 spath = sdir.sound_path().to_string();
3112 string::size_type pos = foo.find_last_of ('/');
3114 if (pos == string::npos) {
3117 spath += foo.substr (pos + 1);
3123 boost::shared_ptr<AudioFileSource>
3124 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3126 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
3127 return boost::dynamic_pointer_cast<AudioFileSource> (
3128 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3131 // FIXME: _terrible_ code duplication
3133 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3136 string old_basename = PBD::basename_nosuffix (oldname);
3137 string new_legalized = legalize_for_path (newname);
3139 /* note: we know (or assume) the old path is already valid */
3143 /* destructive file sources have a name of the form:
3145 /path/to/Tnnnn-NAME(%[LR])?.wav
3147 the task here is to replace NAME with the new name.
3150 /* find last slash */
3154 string::size_type slash;
3155 string::size_type dash;
3157 if ((slash = path.find_last_of ('/')) == string::npos) {
3161 dir = path.substr (0, slash+1);
3163 /* '-' is not a legal character for the NAME part of the path */
3165 if ((dash = path.find_last_of ('-')) == string::npos) {
3169 prefix = path.substr (slash+1, dash-(slash+1));
3174 path += new_legalized;
3175 path += ".mid"; /* XXX gag me with a spoon */
3179 /* non-destructive file sources have a name of the form:
3181 /path/to/NAME-nnnnn(%[LR])?.wav
3183 the task here is to replace NAME with the new name.
3188 string::size_type slash;
3189 string::size_type dash;
3190 string::size_type postfix;
3192 /* find last slash */
3194 if ((slash = path.find_last_of ('/')) == string::npos) {
3198 dir = path.substr (0, slash+1);
3200 /* '-' is not a legal character for the NAME part of the path */
3202 if ((dash = path.find_last_of ('-')) == string::npos) {
3206 suffix = path.substr (dash+1);
3208 // Suffix is now everything after the dash. Now we need to eliminate
3209 // the nnnnn part, which is done by either finding a '%' or a '.'
3211 postfix = suffix.find_last_of ("%");
3212 if (postfix == string::npos) {
3213 postfix = suffix.find_last_of ('.');
3216 if (postfix != string::npos) {
3217 suffix = suffix.substr (postfix);
3219 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3223 const uint32_t limit = 10000;
3224 char buf[PATH_MAX+1];
3226 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3228 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3230 if (access (buf, F_OK) != 0) {
3238 error << "FATAL ERROR! Could not find a " << endl;
3247 Session::midi_path_from_name (string name)
3251 char buf[PATH_MAX+1];
3252 const uint32_t limit = 10000;
3256 legalized = legalize_for_path (name);
3258 /* find a "version" of the file name that doesn't exist in
3259 any of the possible directories.
3262 for (cnt = 1; cnt <= limit; ++cnt) {
3264 vector<space_and_path>::iterator i;
3265 uint32_t existing = 0;
3267 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3269 SessionDirectory sdir((*i).path);
3271 sys::path p = sdir.midi_path();
3275 spath = p.to_string();
3277 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3279 if (sys::exists (buf)) {
3284 if (existing == 0) {
3289 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3290 throw failed_constructor();
3294 /* we now have a unique name for the file, but figure out where to
3300 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3302 spath = sdir.midi_path().to_string();
3305 string::size_type pos = foo.find_last_of ('/');
3307 if (pos == string::npos) {
3310 spath += foo.substr (pos + 1);
3316 boost::shared_ptr<MidiSource>
3317 Session::create_midi_source_for_session (MidiDiskstream& ds)
3319 string mpath = midi_path_from_name (ds.name());
3321 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
3325 /* Playlist management */
3327 boost::shared_ptr<Playlist>
3328 Session::playlist_by_name (string name)
3330 Glib::Mutex::Lock lm (playlist_lock);
3331 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3332 if ((*i)->name() == name) {
3336 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3337 if ((*i)->name() == name) {
3342 return boost::shared_ptr<Playlist>();
3346 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3348 Glib::Mutex::Lock lm (playlist_lock);
3349 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3350 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3351 list.push_back (*i);
3354 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3355 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3356 list.push_back (*i);
3362 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3364 if (playlist->hidden()) {
3369 Glib::Mutex::Lock lm (playlist_lock);
3370 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3371 playlists.insert (playlists.begin(), playlist);
3372 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3373 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3378 playlist->release();
3383 PlaylistAdded (playlist); /* EMIT SIGNAL */
3387 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3390 Glib::Mutex::Lock lm (playlist_lock);
3391 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3394 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3401 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3403 boost::shared_ptr<Playlist> pl(wpl.lock());
3409 PlaylistList::iterator x;
3412 /* its not supposed to be visible */
3417 Glib::Mutex::Lock lm (playlist_lock);
3421 unused_playlists.insert (pl);
3423 if ((x = playlists.find (pl)) != playlists.end()) {
3424 playlists.erase (x);
3430 playlists.insert (pl);
3432 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3433 unused_playlists.erase (x);
3440 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3442 if (_state_of_the_state & Deletion) {
3446 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3453 Glib::Mutex::Lock lm (playlist_lock);
3455 PlaylistList::iterator i;
3457 i = find (playlists.begin(), playlists.end(), playlist);
3458 if (i != playlists.end()) {
3459 playlists.erase (i);
3462 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3463 if (i != unused_playlists.end()) {
3464 unused_playlists.erase (i);
3471 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3475 Session::set_audition (boost::shared_ptr<Region> r)
3477 pending_audition_region = r;
3478 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3479 schedule_butler_transport_work ();
3483 Session::audition_playlist ()
3485 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3486 ev->region.reset ();
3491 Session::non_realtime_set_audition ()
3493 if (!pending_audition_region) {
3494 auditioner->audition_current_playlist ();
3496 auditioner->audition_region (pending_audition_region);
3497 pending_audition_region.reset ();
3499 AuditionActive (true); /* EMIT SIGNAL */
3503 Session::audition_region (boost::shared_ptr<Region> r)
3505 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3511 Session::cancel_audition ()
3513 if (auditioner->active()) {
3514 auditioner->cancel_audition ();
3515 AuditionActive (false); /* EMIT SIGNAL */
3520 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3522 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3526 Session::remove_empty_sounds ()
3528 vector<string> audio_filenames;
3530 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3532 Glib::Mutex::Lock lm (source_lock);
3534 TapeFileMatcher tape_file_matcher;
3536 remove_if (audio_filenames.begin(), audio_filenames.end(),
3537 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3539 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3541 sys::path audio_file_path (_session_dir->sound_path());
3543 audio_file_path /= *i;
3545 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3549 sys::remove (audio_file_path);
3550 const string peakfile = peak_path (audio_file_path.to_string());
3551 sys::remove (peakfile);
3553 catch (const sys::filesystem_error& err)
3555 error << err.what() << endmsg;
3562 Session::is_auditioning () const
3564 /* can be called before we have an auditioner object */
3566 return auditioner->active();
3573 Session::set_all_solo (bool yn)
3575 shared_ptr<RouteList> r = routes.reader ();
3577 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3578 if (!(*i)->is_hidden()) {
3579 (*i)->set_solo (yn, this);
3587 Session::set_all_mute (bool yn)
3589 shared_ptr<RouteList> r = routes.reader ();
3591 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3592 if (!(*i)->is_hidden()) {
3593 (*i)->set_mute (yn, this);
3601 Session::n_diskstreams () const
3605 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3607 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3608 if (!(*i)->hidden()) {
3616 Session::graph_reordered ()
3618 /* don't do this stuff if we are setting up connections
3619 from a set_state() call or creating new tracks.
3622 if (_state_of_the_state & InitialConnecting) {
3626 /* every track/bus asked for this to be handled but it was deferred because
3627 we were connecting. do it now.
3630 request_input_change_handling ();
3634 /* force all diskstreams to update their capture offset values to
3635 reflect any changes in latencies within the graph.
3638 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3640 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3641 (*i)->set_capture_offset ();
3646 Session::record_disenable_all ()
3648 record_enable_change_all (false);
3652 Session::record_enable_all ()
3654 record_enable_change_all (true);
3658 Session::record_enable_change_all (bool yn)
3660 shared_ptr<RouteList> r = routes.reader ();
3662 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3665 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3666 at->set_record_enable (yn, this);
3670 /* since we don't keep rec-enable state, don't mark session dirty */
3674 Session::add_processor (Processor* processor)
3677 PortInsert* port_insert;
3678 PluginInsert* plugin_insert;
3680 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3681 _port_inserts.insert (_port_inserts.begin(), port_insert);
3682 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3683 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3684 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3685 _sends.insert (_sends.begin(), send);
3687 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3691 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3697 Session::remove_processor (Processor* processor)
3700 PortInsert* port_insert;
3701 PluginInsert* plugin_insert;
3703 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3704 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3705 if (x != _port_inserts.end()) {
3706 insert_bitset[port_insert->bit_slot()] = false;
3707 _port_inserts.erase (x);
3709 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3710 _plugin_inserts.remove (plugin_insert);
3711 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3712 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3713 if (x != _sends.end()) {
3714 send_bitset[send->bit_slot()] = false;
3718 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3726 Session::available_capture_duration ()
3728 float sample_bytes_on_disk = 4.0; // keep gcc happy
3730 switch (Config->get_native_file_data_format()) {
3732 sample_bytes_on_disk = 4.0;
3736 sample_bytes_on_disk = 3.0;
3740 sample_bytes_on_disk = 2.0;
3744 /* impossible, but keep some gcc versions happy */
3745 fatal << string_compose (_("programming error: %1"),
3746 X_("illegal native file data format"))
3751 double scale = 4096.0 / sample_bytes_on_disk;
3753 if (_total_free_4k_blocks * scale > (double) max_frames) {
3757 return (nframes_t) floor (_total_free_4k_blocks * scale);
3761 Session::add_bundle (shared_ptr<Bundle> bundle)
3764 Glib::Mutex::Lock guard (bundle_lock);
3765 _bundles.push_back (bundle);
3768 BundleAdded (bundle); /* EMIT SIGNAL */
3774 Session::remove_bundle (shared_ptr<Bundle> bundle)
3776 bool removed = false;
3779 Glib::Mutex::Lock guard (bundle_lock);
3780 BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
3782 if (i != _bundles.end()) {
3789 BundleRemoved (bundle); /* EMIT SIGNAL */
3796 Session::bundle_by_name (string name) const
3798 Glib::Mutex::Lock lm (bundle_lock);
3800 for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
3801 if ((*i)->name() == name) {
3806 return boost::shared_ptr<Bundle> ();
3810 Session::tempo_map_changed (Change ignored)
3814 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3815 (*i)->update_after_tempo_map_change ();
3818 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3819 (*i)->update_after_tempo_map_change ();
3825 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3826 * the given count with the current block size.
3829 Session::ensure_buffers (ChanCount howmany)
3831 if (current_block_size == 0)
3832 return; // too early? (is this ok?)
3834 // We need at least 2 MIDI scratch buffers to mix/merge
3835 if (howmany.n_midi() < 2)
3836 howmany.set_midi(2);
3838 // FIXME: JACK needs to tell us maximum MIDI buffer size
3839 // Using nasty assumption (max # events == nframes) for now
3840 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3841 _mix_buffers->ensure_buffers(howmany, current_block_size);
3842 _silent_buffers->ensure_buffers(howmany, current_block_size);
3844 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3848 Session::next_insert_id ()
3850 /* this doesn't really loop forever. just think about it */
3853 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3854 if (!insert_bitset[n]) {
3855 insert_bitset[n] = true;
3861 /* none available, so resize and try again */
3863 insert_bitset.resize (insert_bitset.size() + 16, false);
3868 Session::next_send_id ()
3870 /* this doesn't really loop forever. just think about it */
3873 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3874 if (!send_bitset[n]) {
3875 send_bitset[n] = true;
3881 /* none available, so resize and try again */
3883 send_bitset.resize (send_bitset.size() + 16, false);
3888 Session::mark_send_id (uint32_t id)
3890 if (id >= send_bitset.size()) {
3891 send_bitset.resize (id+16, false);
3893 if (send_bitset[id]) {
3894 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3896 send_bitset[id] = true;
3900 Session::mark_insert_id (uint32_t id)
3902 if (id >= insert_bitset.size()) {
3903 insert_bitset.resize (id+16, false);
3905 if (insert_bitset[id]) {
3906 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3908 insert_bitset[id] = true;
3911 /* Named Selection management */
3914 Session::named_selection_by_name (string name)
3916 Glib::Mutex::Lock lm (named_selection_lock);
3917 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3918 if ((*i)->name == name) {
3926 Session::add_named_selection (NamedSelection* named_selection)
3929 Glib::Mutex::Lock lm (named_selection_lock);
3930 named_selections.insert (named_selections.begin(), named_selection);
3933 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3939 NamedSelectionAdded (); /* EMIT SIGNAL */
3943 Session::remove_named_selection (NamedSelection* named_selection)
3945 bool removed = false;
3948 Glib::Mutex::Lock lm (named_selection_lock);
3950 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3952 if (i != named_selections.end()) {
3954 named_selections.erase (i);
3961 NamedSelectionRemoved (); /* EMIT SIGNAL */
3966 Session::reset_native_file_format ()
3968 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3970 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3971 (*i)->reset_write_sources (false);
3976 Session::route_name_unique (string n) const
3978 shared_ptr<RouteList> r = routes.reader ();
3980 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3981 if ((*i)->name() == n) {
3990 Session::n_playlists () const
3992 Glib::Mutex::Lock lm (playlist_lock);
3993 return playlists.size();
3997 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3999 if (!force && howmany <= _npan_buffers) {
4003 if (_pan_automation_buffer) {
4005 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4006 delete [] _pan_automation_buffer[i];
4009 delete [] _pan_automation_buffer;
4012 _pan_automation_buffer = new pan_t*[howmany];
4014 for (uint32_t i = 0; i < howmany; ++i) {
4015 _pan_automation_buffer[i] = new pan_t[nframes];
4018 _npan_buffers = howmany;
4022 Session::freeze (InterThreadInfo& itt)
4024 shared_ptr<RouteList> r = routes.reader ();
4026 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4030 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
4031 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4041 boost::shared_ptr<Region>
4042 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4043 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
4045 boost::shared_ptr<Region> result;
4046 boost::shared_ptr<Playlist> playlist;
4047 boost::shared_ptr<AudioFileSource> fsource;
4049 char buf[PATH_MAX+1];
4050 ChanCount nchans(track.audio_diskstream()->n_channels());
4052 nframes_t this_chunk;
4055 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4056 const string sound_dir = sdir.sound_path().to_string();
4057 nframes_t len = end - start;
4060 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4061 end, start) << endmsg;
4065 // any bigger than this seems to cause stack overflows in called functions
4066 const nframes_t chunk_size = (128 * 1024)/4;
4068 g_atomic_int_set (&processing_prohibited, 1);
4070 /* call tree *MUST* hold route_lock */
4072 if ((playlist = track.diskstream()->playlist()) == 0) {
4076 /* external redirects will be a problem */
4078 if (track.has_external_redirects()) {
4082 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4084 for (x = 0; x < 99999; ++x) {
4085 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4086 if (access (buf, F_OK) != 0) {
4092 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4097 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4098 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4101 catch (failed_constructor& err) {
4102 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4106 srcs.push_back (fsource);
4109 /* XXX need to flush all redirects */
4114 /* create a set of reasonably-sized buffers */
4115 buffers.ensure_buffers(nchans, chunk_size);
4116 buffers.set_count(nchans);
4118 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4119 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4121 afs->prepare_for_peakfile_writes ();
4124 while (to_do && !itt.cancel) {
4126 this_chunk = min (to_do, chunk_size);
4128 if (track.export_stuff (buffers, start, this_chunk)) {
4133 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4134 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4137 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4143 start += this_chunk;
4144 to_do -= this_chunk;
4146 itt.progress = (float) (1.0 - ((double) to_do / len));
4155 xnow = localtime (&now);
4157 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4158 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4161 afs->update_header (position, *xnow, now);
4162 afs->flush_header ();
4166 /* construct a region to represent the bounced material */
4168 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4169 region_name_from_path (srcs.front()->name(), true));
4174 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4175 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4178 afs->mark_for_remove ();
4181 (*src)->drop_references ();
4185 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4186 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4189 afs->done_with_peakfile_writes ();
4193 g_atomic_int_set (&processing_prohibited, 0);
4199 Session::get_silent_buffers (ChanCount count)
4201 assert(_silent_buffers->available() >= count);
4202 _silent_buffers->set_count(count);
4204 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4205 for (size_t i= 0; i < count.get(*t); ++i) {
4206 _silent_buffers->get(*t, i).clear();
4210 return *_silent_buffers;
4214 Session::get_scratch_buffers (ChanCount count)
4216 if (count != ChanCount::ZERO) {
4217 assert(_scratch_buffers->available() >= count);
4218 _scratch_buffers->set_count(count);
4220 _scratch_buffers->set_count (_scratch_buffers->available());
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 (const char* base)
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 (base);
4290 Route::SyncOrderKeys (base); // 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) {