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.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.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>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/utils.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
68 #include <ardour/source_factory.h>
69 #include <ardour/region_factory.h>
72 #include <ardour/osc.h>
78 using namespace ARDOUR;
80 using boost::shared_ptr;
82 const char* Session::_template_suffix = X_(".template");
83 const char* Session::_statefile_suffix = X_(".ardour");
84 const char* Session::_pending_suffix = X_(".pending");
85 const char* Session::old_sound_dir_name = X_("sounds");
86 const char* Session::sound_dir_name = X_("audiofiles");
87 const char* Session::peak_dir_name = X_("peaks");
88 const char* Session::dead_sound_dir_name = X_("dead_sounds");
89 const char* Session::interchange_dir_name = X_("interchange");
90 const char* Session::export_dir_name = X_("export");
92 Session::compute_peak_t Session::compute_peak = 0;
93 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
94 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
95 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
97 sigc::signal<int> Session::AskAboutPendingState;
98 sigc::signal<void> Session::SendFeedback;
100 sigc::signal<void> Session::SMPTEOffsetChanged;
101 sigc::signal<void> Session::StartTimeChanged;
102 sigc::signal<void> Session::EndTimeChanged;
105 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
108 char buf[PATH_MAX+1];
112 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
113 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
119 /* check to see if it exists, and what it is */
121 if (stat (str.c_str(), &statbuf)) {
122 if (errno == ENOENT) {
125 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
133 /* it exists, so it must either be the name
134 of the directory, or the name of the statefile
138 if (S_ISDIR (statbuf.st_mode)) {
140 string::size_type slash = str.find_last_of ('/');
142 if (slash == string::npos) {
144 /* a subdirectory of cwd, so statefile should be ... */
150 tmp += _statefile_suffix;
154 if (stat (tmp.c_str(), &statbuf)) {
155 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
165 /* some directory someplace in the filesystem.
166 the snapshot name is the directory name
171 snapshot = str.substr (slash+1);
175 } else if (S_ISREG (statbuf.st_mode)) {
177 string::size_type slash = str.find_last_of ('/');
178 string::size_type suffix;
180 /* remove the suffix */
182 if (slash != string::npos) {
183 snapshot = str.substr (slash+1);
188 suffix = snapshot.find (_statefile_suffix);
190 if (suffix == string::npos) {
191 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
197 snapshot = snapshot.substr (0, suffix);
199 if (slash == string::npos) {
201 /* we must be in the directory where the
202 statefile lives. get it using cwd().
205 char cwd[PATH_MAX+1];
207 if (getcwd (cwd, sizeof (cwd)) == 0) {
208 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
217 /* full path to the statefile */
219 path = str.substr (0, slash);
224 /* what type of file is it? */
225 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
231 /* its the name of a new directory. get the name
235 string::size_type slash = str.find_last_of ('/');
237 if (slash == string::npos) {
239 /* no slash, just use the name, but clean it up */
241 path = legalize_for_path (str);
247 snapshot = str.substr (slash+1);
254 Session::Session (AudioEngine &eng,
256 string snapshot_name,
257 string* mix_template)
260 _mmc_port (default_mmc_port),
261 _mtc_port (default_mtc_port),
262 _midi_port (default_midi_port),
263 pending_events (2048),
264 midi_requests (128), // the size of this should match the midi request pool size
265 diskstreams (new DiskstreamList),
266 routes (new RouteList),
267 auditioner ((Auditioner*) 0),
273 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
275 n_physical_outputs = _engine.n_physical_outputs();
276 n_physical_inputs = _engine.n_physical_inputs();
278 first_stage_init (fullpath, snapshot_name);
280 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
282 if (create (new_session, mix_template, compute_initial_length())) {
283 cerr << "create failed\n";
285 throw failed_constructor ();
289 if (second_stage_init (new_session)) {
291 throw failed_constructor ();
294 store_recent_sessions(_name, _path);
296 bool was_dirty = dirty();
298 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
300 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
303 DirtyChanged (); /* EMIT SIGNAL */
307 Session::Session (AudioEngine &eng,
309 string snapshot_name,
310 AutoConnectOption input_ac,
311 AutoConnectOption output_ac,
312 uint32_t control_out_channels,
313 uint32_t master_out_channels,
314 uint32_t requested_physical_in,
315 uint32_t requested_physical_out,
316 nframes_t initial_length)
319 _mmc_port (default_mmc_port),
320 _mtc_port (default_mtc_port),
321 _midi_port (default_midi_port),
322 pending_events (2048),
324 diskstreams (new DiskstreamList),
325 routes (new RouteList),
331 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
333 n_physical_outputs = _engine.n_physical_outputs();
334 n_physical_inputs = _engine.n_physical_inputs();
336 if (n_physical_inputs) {
337 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
340 if (n_physical_outputs) {
341 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
344 first_stage_init (fullpath, snapshot_name);
346 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
349 if (create (new_session, 0, initial_length)) {
351 throw failed_constructor ();
356 /* set up Master Out and Control Out if necessary */
361 if (control_out_channels) {
362 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
363 r->set_remote_control_id (control_id++);
368 if (master_out_channels) {
369 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
370 r->set_remote_control_id (control_id);
374 /* prohibit auto-connect to master, because there isn't one */
375 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
384 Config->set_input_auto_connect (input_ac);
385 Config->set_output_auto_connect (output_ac);
387 if (second_stage_init (new_session)) {
389 throw failed_constructor ();
392 store_recent_sessions(_name, _path);
394 bool was_dirty = dirty ();
396 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
398 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
401 DirtyChanged (); /* EMIT SIGNAL */
413 /* if we got to here, leaving pending capture state around
417 remove_pending_capture_state ();
419 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
420 _engine.remove_session ();
422 GoingAway (); /* EMIT SIGNAL */
428 /* clear history so that no references to objects are held any more */
432 /* clear state tree so that no references to objects are held any more */
438 terminate_butler_thread ();
439 terminate_midi_thread ();
441 if (click_data && click_data != default_click) {
442 delete [] click_data;
445 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
446 delete [] click_emphasis_data;
451 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
455 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
459 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
463 AudioDiskstream::free_working_buffers();
465 /* this should cause deletion of the auditioner */
467 // auditioner.reset ();
469 #undef TRACK_DESTRUCTION
470 #ifdef TRACK_DESTRUCTION
471 cerr << "delete named selections\n";
472 #endif /* TRACK_DESTRUCTION */
473 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
474 NamedSelectionList::iterator tmp;
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete playlists\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
487 PlaylistList::iterator tmp;
492 (*i)->drop_references ();
497 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
498 PlaylistList::iterator tmp;
503 (*i)->drop_references ();
509 unused_playlists.clear ();
511 #ifdef TRACK_DESTRUCTION
512 cerr << "delete audio regions\n";
513 #endif /* TRACK_DESTRUCTION */
515 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
516 AudioRegionList::iterator tmp;
521 i->second->drop_references ();
526 audio_regions.clear ();
528 #ifdef TRACK_DESTRUCTION
529 cerr << "delete routes\n";
530 #endif /* TRACK_DESTRUCTION */
532 RCUWriter<RouteList> writer (routes);
533 boost::shared_ptr<RouteList> r = writer.get_copy ();
534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
535 (*i)->drop_references ();
538 /* writer goes out of scope and updates master */
543 #ifdef TRACK_DESTRUCTION
544 cerr << "delete diskstreams\n";
545 #endif /* TRACK_DESTRUCTION */
547 RCUWriter<DiskstreamList> dwriter (diskstreams);
548 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
549 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
550 (*i)->drop_references ();
554 diskstreams.flush ();
556 #ifdef TRACK_DESTRUCTION
557 cerr << "delete audio sources\n";
558 #endif /* TRACK_DESTRUCTION */
559 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
560 AudioSourceList::iterator tmp;
565 i->second->drop_references ();
570 audio_sources.clear ();
572 #ifdef TRACK_DESTRUCTION
573 cerr << "delete mix groups\n";
574 #endif /* TRACK_DESTRUCTION */
575 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
576 list<RouteGroup*>::iterator tmp;
586 #ifdef TRACK_DESTRUCTION
587 cerr << "delete edit groups\n";
588 #endif /* TRACK_DESTRUCTION */
589 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
590 list<RouteGroup*>::iterator tmp;
600 #ifdef TRACK_DESTRUCTION
601 cerr << "delete connections\n";
602 #endif /* TRACK_DESTRUCTION */
603 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
604 ConnectionList::iterator tmp;
614 if (butler_mixdown_buffer) {
615 delete [] butler_mixdown_buffer;
618 if (butler_gain_buffer) {
619 delete [] butler_gain_buffer;
622 Crossfade::set_buffer_size (0);
630 Session::set_worst_io_latencies ()
632 _worst_output_latency = 0;
633 _worst_input_latency = 0;
635 if (!_engine.connected()) {
639 boost::shared_ptr<RouteList> r = routes.reader ();
641 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
642 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
643 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
648 Session::when_engine_running ()
650 string first_physical_output;
652 /* we don't want to run execute this again */
654 set_block_size (_engine.frames_per_cycle());
655 set_frame_rate (_engine.frame_rate());
657 Config->map_parameters (mem_fun (*this, &Session::config_changed));
659 /* every time we reconnect, recompute worst case output latencies */
661 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
663 if (synced_to_jack()) {
664 _engine.transport_stop ();
667 if (Config->get_jack_time_master()) {
668 _engine.transport_locate (_transport_frame);
676 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
678 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
680 /* existing state for Click */
682 if (_click_io->set_state (*child->children().front()) == 0) {
684 _clicking = Config->get_clicking ();
688 error << _("could not setup Click I/O") << endmsg;
694 /* default state for Click */
696 first_physical_output = _engine.get_nth_physical_output (0);
698 if (first_physical_output.length()) {
699 if (_click_io->add_output_port (first_physical_output, this)) {
700 // relax, even though its an error
702 _clicking = Config->get_clicking ();
708 catch (failed_constructor& err) {
709 error << _("cannot setup Click I/O") << endmsg;
712 set_worst_io_latencies ();
715 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
718 /* Create a set of Connection objects that map
719 to the physical outputs currently available
724 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
726 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
728 Connection* c = new OutputConnection (buf, true);
731 c->add_connection (0, _engine.get_nth_physical_output (np));
736 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
738 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
740 Connection* c = new InputConnection (buf, true);
743 c->add_connection (0, _engine.get_nth_physical_input (np));
750 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
752 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
754 Connection* c = new OutputConnection (buf, true);
758 c->add_connection (0, _engine.get_nth_physical_output (np));
759 c->add_connection (1, _engine.get_nth_physical_output (np+1));
764 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
766 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
768 Connection* c = new InputConnection (buf, true);
772 c->add_connection (0, _engine.get_nth_physical_input (np));
773 c->add_connection (1, _engine.get_nth_physical_input (np+1));
782 /* create master/control ports */
787 /* force the master to ignore any later call to this */
789 if (_master_out->pending_state_node) {
790 _master_out->ports_became_legal();
793 /* no panner resets till we are through */
795 _master_out->defer_pan_reset ();
797 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
798 if (_master_out->add_input_port ("", this)) {
799 error << _("cannot setup master inputs")
805 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
806 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
807 error << _("cannot setup master outputs")
814 _master_out->allow_pan_reset ();
818 Connection* c = new OutputConnection (_("Master Out"), true);
820 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
822 c->add_connection ((int) n, _master_out->input(n)->name());
829 /* catch up on send+insert cnts */
833 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
836 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
837 if (id > insert_cnt) {
845 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
848 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
856 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
858 /* hook us up to the engine */
860 _engine.set_session (this);
865 osc->set_session (*this);
868 _state_of_the_state = Clean;
870 DirtyChanged (); /* EMIT SIGNAL */
874 Session::hookup_io ()
876 /* stop graph reordering notifications from
877 causing resorts, etc.
880 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
882 if (auditioner == 0) {
884 /* we delay creating the auditioner till now because
885 it makes its own connections to ports.
886 the engine has to be running for this to work.
890 auditioner.reset (new Auditioner (*this));
893 catch (failed_constructor& err) {
894 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
898 /* Tell all IO objects to create their ports */
905 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
906 if (_control_out->add_input_port ("", this)) {
907 error << _("cannot setup control inputs")
913 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
914 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
915 error << _("cannot set up master outputs")
923 /* Tell all IO objects to connect themselves together */
925 IO::enable_connecting ();
927 /* Now reset all panners */
929 IO::reset_panners ();
931 /* Anyone who cares about input state, wake up and do something */
933 IOConnectionsComplete (); /* EMIT SIGNAL */
935 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
937 /* now handle the whole enchilada as if it was one
943 /* update mixer solo state */
949 Session::playlist_length_changed ()
951 /* we can't just increase end_location->end() if pl->get_maximum_extent()
952 if larger. if the playlist used to be the longest playlist,
953 and its now shorter, we have to decrease end_location->end(). hence,
954 we have to iterate over all diskstreams and check the
955 playlists currently in use.
961 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
963 boost::shared_ptr<Playlist> playlist;
965 if ((playlist = dstream->playlist()) != 0) {
966 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
969 /* see comment in playlist_length_changed () */
974 Session::record_enabling_legal () const
976 /* this used to be in here, but survey says.... we don't need to restrict it */
977 // if (record_status() == Recording) {
981 if (Config->get_all_safe()) {
988 Session::reset_input_monitor_state ()
990 if (transport_rolling()) {
992 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
994 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
995 if ((*i)->record_enabled ()) {
996 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
997 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1001 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1003 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1004 if ((*i)->record_enabled ()) {
1005 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1006 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1013 Session::auto_punch_start_changed (Location* location)
1015 replace_event (Event::PunchIn, location->start());
1017 if (get_record_enabled() && Config->get_punch_in()) {
1018 /* capture start has been changed, so save new pending state */
1019 save_state ("", true);
1024 Session::auto_punch_end_changed (Location* location)
1026 nframes_t when_to_stop = location->end();
1027 // when_to_stop += _worst_output_latency + _worst_input_latency;
1028 replace_event (Event::PunchOut, when_to_stop);
1032 Session::auto_punch_changed (Location* location)
1034 nframes_t when_to_stop = location->end();
1036 replace_event (Event::PunchIn, location->start());
1037 //when_to_stop += _worst_output_latency + _worst_input_latency;
1038 replace_event (Event::PunchOut, when_to_stop);
1042 Session::auto_loop_changed (Location* location)
1044 replace_event (Event::AutoLoop, location->end(), location->start());
1046 if (transport_rolling() && play_loop) {
1048 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1050 if (_transport_frame > location->end()) {
1051 // relocate to beginning of loop
1052 clear_events (Event::LocateRoll);
1054 request_locate (location->start(), true);
1057 else if (Config->get_seamless_loop() && !loop_changing) {
1059 // schedule a locate-roll to refill the diskstreams at the
1060 // previous loop end
1061 loop_changing = true;
1063 if (location->end() > last_loopend) {
1064 clear_events (Event::LocateRoll);
1065 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1072 last_loopend = location->end();
1077 Session::set_auto_punch_location (Location* location)
1081 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1082 auto_punch_start_changed_connection.disconnect();
1083 auto_punch_end_changed_connection.disconnect();
1084 auto_punch_changed_connection.disconnect();
1085 existing->set_auto_punch (false, this);
1086 remove_event (existing->start(), Event::PunchIn);
1087 clear_events (Event::PunchOut);
1088 auto_punch_location_changed (0);
1093 if (location == 0) {
1097 if (location->end() <= location->start()) {
1098 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1102 auto_punch_start_changed_connection.disconnect();
1103 auto_punch_end_changed_connection.disconnect();
1104 auto_punch_changed_connection.disconnect();
1106 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1107 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1108 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1110 location->set_auto_punch (true, this);
1111 auto_punch_location_changed (location);
1115 Session::set_auto_loop_location (Location* location)
1119 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1120 auto_loop_start_changed_connection.disconnect();
1121 auto_loop_end_changed_connection.disconnect();
1122 auto_loop_changed_connection.disconnect();
1123 existing->set_auto_loop (false, this);
1124 remove_event (existing->end(), Event::AutoLoop);
1125 auto_loop_location_changed (0);
1130 if (location == 0) {
1134 if (location->end() <= location->start()) {
1135 error << _("Session: you can't use a mark for auto loop") << endmsg;
1139 last_loopend = location->end();
1141 auto_loop_start_changed_connection.disconnect();
1142 auto_loop_end_changed_connection.disconnect();
1143 auto_loop_changed_connection.disconnect();
1145 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1146 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1147 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1149 location->set_auto_loop (true, this);
1150 auto_loop_location_changed (location);
1154 Session::locations_added (Location* ignored)
1160 Session::locations_changed ()
1162 _locations.apply (*this, &Session::handle_locations_changed);
1166 Session::handle_locations_changed (Locations::LocationList& locations)
1168 Locations::LocationList::iterator i;
1170 bool set_loop = false;
1171 bool set_punch = false;
1173 for (i = locations.begin(); i != locations.end(); ++i) {
1177 if (location->is_auto_punch()) {
1178 set_auto_punch_location (location);
1181 if (location->is_auto_loop()) {
1182 set_auto_loop_location (location);
1189 set_auto_loop_location (0);
1192 set_auto_punch_location (0);
1199 Session::enable_record ()
1201 /* XXX really atomic compare+swap here */
1202 if (g_atomic_int_get (&_record_status) != Recording) {
1203 g_atomic_int_set (&_record_status, Recording);
1204 _last_record_location = _transport_frame;
1205 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1207 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1208 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1209 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1210 if ((*i)->record_enabled ()) {
1211 (*i)->monitor_input (true);
1216 RecordStateChanged ();
1221 Session::disable_record (bool rt_context, bool force)
1225 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1227 if (!Config->get_latched_record_enable () || force) {
1228 g_atomic_int_set (&_record_status, Disabled);
1230 if (rs == Recording) {
1231 g_atomic_int_set (&_record_status, Enabled);
1235 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1237 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1238 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1240 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1241 if ((*i)->record_enabled ()) {
1242 (*i)->monitor_input (false);
1247 RecordStateChanged (); /* emit signal */
1250 remove_pending_capture_state ();
1256 Session::step_back_from_record ()
1258 g_atomic_int_set (&_record_status, Enabled);
1260 if (Config->get_monitoring_model() == HardwareMonitoring) {
1261 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1263 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1264 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1265 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1266 (*i)->monitor_input (false);
1273 Session::maybe_enable_record ()
1275 g_atomic_int_set (&_record_status, Enabled);
1277 /* this function is currently called from somewhere other than an RT thread.
1278 this save_state() call therefore doesn't impact anything.
1281 save_state ("", true);
1283 if (_transport_speed) {
1284 if (!Config->get_punch_in()) {
1288 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1289 RecordStateChanged (); /* EMIT SIGNAL */
1296 Session::audible_frame () const
1302 /* the first of these two possible settings for "offset"
1303 mean that the audible frame is stationary until
1304 audio emerges from the latency compensation
1307 the second means that the audible frame is stationary
1308 until audio would emerge from a physical port
1309 in the absence of any plugin latency compensation
1312 offset = _worst_output_latency;
1314 if (offset > current_block_size) {
1315 offset -= current_block_size;
1317 /* XXX is this correct? if we have no external
1318 physical connections and everything is internal
1319 then surely this is zero? still, how
1320 likely is that anyway?
1322 offset = current_block_size;
1325 if (synced_to_jack()) {
1326 tf = _engine.transport_frame();
1328 tf = _transport_frame;
1331 if (_transport_speed == 0) {
1341 if (!non_realtime_work_pending()) {
1345 /* take latency into account */
1354 Session::set_frame_rate (nframes_t frames_per_second)
1356 /** \fn void Session::set_frame_size(nframes_t)
1357 the AudioEngine object that calls this guarantees
1358 that it will not be called while we are also in
1359 ::process(). Its fine to do things that block
1363 _base_frame_rate = frames_per_second;
1367 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1369 // XXX we need some equivalent to this, somehow
1370 // SndFileSource::setup_standard_crossfades (frames_per_second);
1374 /* XXX need to reset/reinstantiate all LADSPA plugins */
1378 Session::set_block_size (nframes_t nframes)
1380 /* the AudioEngine guarantees
1381 that it will not be called while we are also in
1382 ::process(). It is therefore fine to do things that block
1387 vector<Sample*>::iterator i;
1390 current_block_size = nframes;
1392 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1396 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1400 _passthru_buffers.clear ();
1401 _silent_buffers.clear ();
1403 ensure_passthru_buffers (np);
1405 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1409 #ifdef NO_POSIX_MEMALIGN
1410 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1412 posix_memalign((void **)&buf,16,current_block_size * 4);
1416 memset (*i, 0, sizeof (Sample) * current_block_size);
1420 if (_gain_automation_buffer) {
1421 delete [] _gain_automation_buffer;
1423 _gain_automation_buffer = new gain_t[nframes];
1425 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1427 boost::shared_ptr<RouteList> r = routes.reader ();
1429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1430 (*i)->set_block_size (nframes);
1433 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1434 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1435 (*i)->set_block_size (nframes);
1438 set_worst_io_latencies ();
1443 Session::set_default_fade (float steepness, float fade_msecs)
1446 nframes_t fade_frames;
1448 /* Don't allow fade of less 1 frame */
1450 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1457 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1461 default_fade_msecs = fade_msecs;
1462 default_fade_steepness = steepness;
1465 // jlc, WTF is this!
1466 Glib::RWLock::ReaderLock lm (route_lock);
1467 AudioRegion::set_default_fade (steepness, fade_frames);
1472 /* XXX have to do this at some point */
1473 /* foreach region using default fade, reset, then
1474 refill_all_diskstream_buffers ();
1479 struct RouteSorter {
1480 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1481 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1483 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1486 if (r1->fed_by.empty()) {
1487 if (r2->fed_by.empty()) {
1488 /* no ardour-based connections inbound to either route. just use signal order */
1489 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1491 /* r2 has connections, r1 does not; run r1 early */
1495 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1502 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1504 shared_ptr<Route> r2;
1506 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1507 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1511 /* make a copy of the existing list of routes that feed r1 */
1513 set<shared_ptr<Route> > existing = r1->fed_by;
1515 /* for each route that feeds r1, recurse, marking it as feeding
1519 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1522 /* r2 is a route that feeds r1 which somehow feeds base. mark
1523 base as being fed by r2
1526 rbase->fed_by.insert (r2);
1530 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1534 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1538 /* now recurse, so that we can mark base as being fed by
1539 all routes that feed r2
1542 trace_terminal (r2, rbase);
1549 Session::resort_routes ()
1551 /* don't do anything here with signals emitted
1552 by Routes while we are being destroyed.
1555 if (_state_of_the_state & Deletion) {
1562 RCUWriter<RouteList> writer (routes);
1563 shared_ptr<RouteList> r = writer.get_copy ();
1564 resort_routes_using (r);
1565 /* writer goes out of scope and forces update */
1570 Session::resort_routes_using (shared_ptr<RouteList> r)
1572 RouteList::iterator i, j;
1574 for (i = r->begin(); i != r->end(); ++i) {
1576 (*i)->fed_by.clear ();
1578 for (j = r->begin(); j != r->end(); ++j) {
1580 /* although routes can feed themselves, it will
1581 cause an endless recursive descent if we
1582 detect it. so don't bother checking for
1590 if ((*j)->feeds (*i)) {
1591 (*i)->fed_by.insert (*j);
1596 for (i = r->begin(); i != r->end(); ++i) {
1597 trace_terminal (*i, *i);
1603 /* don't leave dangling references to routes in Route::fed_by */
1605 for (i = r->begin(); i != r->end(); ++i) {
1606 (*i)->fed_by.clear ();
1610 cerr << "finished route resort\n";
1612 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1613 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1620 list<boost::shared_ptr<AudioTrack> >
1621 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1623 char track_name[32];
1624 uint32_t track_id = 0;
1626 uint32_t channels_used = 0;
1628 RouteList new_routes;
1629 list<boost::shared_ptr<AudioTrack> > ret;
1630 uint32_t control_id;
1632 /* count existing audio tracks */
1635 shared_ptr<RouteList> r = routes.reader ();
1637 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1638 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1639 if (!(*i)->hidden()) {
1641 channels_used += (*i)->n_inputs();
1647 vector<string> physinputs;
1648 vector<string> physoutputs;
1649 uint32_t nphysical_in;
1650 uint32_t nphysical_out;
1652 _engine.get_physical_outputs (physoutputs);
1653 _engine.get_physical_inputs (physinputs);
1654 control_id = ntracks() + nbusses() + 1;
1658 /* check for duplicate route names, since we might have pre-existing
1659 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1660 save, close,restart,add new route - first named route is now
1668 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1670 if (route_by_name (track_name) == 0) {
1674 } while (track_id < (UINT_MAX-1));
1676 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1677 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1682 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1683 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1689 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1691 if (track->ensure_io (input_channels, output_channels, false, this)) {
1692 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1693 input_channels, output_channels)
1698 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1702 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1703 port = physinputs[(channels_used+x)%nphysical_in];
1706 if (port.length() && track->connect_input (track->input (x), port, this)) {
1712 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1716 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1717 port = physoutputs[(channels_used+x)%nphysical_out];
1718 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1720 port = _master_out->input (x%_master_out->n_inputs())->name();
1724 if (port.length() && track->connect_output (track->output (x), port, this)) {
1729 channels_used += track->n_inputs ();
1732 vector<string> cports;
1733 uint32_t ni = _control_out->n_inputs();
1735 for (n = 0; n < ni; ++n) {
1736 cports.push_back (_control_out->input(n)->name());
1739 track->set_control_outs (cports);
1742 // assert (current_thread != RT_thread)
1744 track->audio_diskstream()->non_realtime_input_change();
1746 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1747 track->set_remote_control_id (control_id);
1750 new_routes.push_back (track);
1751 ret.push_back (track);
1754 catch (failed_constructor &err) {
1755 error << _("Session: could not create new audio track.") << endmsg;
1756 // XXX should we delete the tracks already created?
1764 if (!new_routes.empty()) {
1765 add_routes (new_routes, false);
1766 save_state (_current_snapshot_name);
1773 Session::set_remote_control_ids ()
1775 RemoteModel m = Config->get_remote_model();
1777 shared_ptr<RouteList> r = routes.reader ();
1779 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1780 if ( MixerOrdered == m) {
1781 long order = (*i)->order_key(N_("signal"));
1782 (*i)->set_remote_control_id( order+1 );
1783 } else if ( EditorOrdered == m) {
1784 long order = (*i)->order_key(N_("editor"));
1785 (*i)->set_remote_control_id( order+1 );
1786 } else if ( UserOrdered == m) {
1787 //do nothing ... only changes to remote id's are initiated by user
1794 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1797 uint32_t bus_id = 1;
1801 uint32_t control_id;
1803 /* count existing audio busses */
1806 shared_ptr<RouteList> r = routes.reader ();
1808 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1809 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1810 if (!(*i)->hidden()) {
1817 vector<string> physinputs;
1818 vector<string> physoutputs;
1820 _engine.get_physical_outputs (physoutputs);
1821 _engine.get_physical_inputs (physinputs);
1822 control_id = ntracks() + nbusses() + 1;
1829 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1831 if (route_by_name (bus_name) == 0) {
1835 } while (bus_id < (UINT_MAX-1));
1838 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1840 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1841 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1842 input_channels, output_channels)
1846 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1850 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1851 port = physinputs[((n+x)%n_physical_inputs)];
1854 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1859 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1863 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1864 port = physoutputs[((n+x)%n_physical_outputs)];
1865 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1867 port = _master_out->input (x%_master_out->n_inputs())->name();
1871 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1877 vector<string> cports;
1878 uint32_t ni = _control_out->n_inputs();
1880 for (uint32_t n = 0; n < ni; ++n) {
1881 cports.push_back (_control_out->input(n)->name());
1883 bus->set_control_outs (cports);
1886 bus->set_remote_control_id (control_id);
1889 ret.push_back (bus);
1893 catch (failed_constructor &err) {
1894 error << _("Session: could not create new audio route.") << endmsg;
1903 add_routes (ret, false);
1904 save_state (_current_snapshot_name);
1912 Session::add_routes (RouteList& new_routes, bool save)
1915 RCUWriter<RouteList> writer (routes);
1916 shared_ptr<RouteList> r = writer.get_copy ();
1917 r->insert (r->end(), new_routes.begin(), new_routes.end());
1918 resort_routes_using (r);
1921 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1923 boost::weak_ptr<Route> wpr (*x);
1925 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1926 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1927 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1928 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1930 if ((*x)->master()) {
1934 if ((*x)->control()) {
1935 _control_out = (*x);
1942 save_state (_current_snapshot_name);
1945 RouteAdded (new_routes); /* EMIT SIGNAL */
1949 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1951 /* need to do this in case we're rolling at the time, to prevent false underruns */
1952 dstream->do_refill_with_alloc();
1955 RCUWriter<DiskstreamList> writer (diskstreams);
1956 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1957 ds->push_back (dstream);
1960 dstream->set_block_size (current_block_size);
1962 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1963 /* this will connect to future changes, and check the current length */
1964 diskstream_playlist_changed (dstream);
1966 dstream->prepare ();
1970 Session::remove_route (shared_ptr<Route> route)
1973 RCUWriter<RouteList> writer (routes);
1974 shared_ptr<RouteList> rs = writer.get_copy ();
1978 /* deleting the master out seems like a dumb
1979 idea, but its more of a UI policy issue
1983 if (route == _master_out) {
1984 _master_out = shared_ptr<Route> ();
1987 if (route == _control_out) {
1988 _control_out = shared_ptr<Route> ();
1990 /* cancel control outs for all routes */
1992 vector<string> empty;
1994 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1995 (*r)->set_control_outs (empty);
1999 update_route_solo_state ();
2001 /* writer goes out of scope, forces route list update */
2004 // FIXME: audio specific
2006 boost::shared_ptr<AudioDiskstream> ds;
2008 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2009 ds = at->audio_diskstream();
2015 RCUWriter<DiskstreamList> dsl (diskstreams);
2016 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2021 find_current_end ();
2023 update_latency_compensation (false, false);
2026 // We need to disconnect the routes inputs and outputs
2027 route->disconnect_inputs(NULL);
2028 route->disconnect_outputs(NULL);
2030 /* get rid of it from the dead wood collection in the route list manager */
2032 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2036 /* try to cause everyone to drop their references */
2038 route->drop_references ();
2040 /* save the new state of the world */
2042 if (save_state (_current_snapshot_name)) {
2043 save_history (_current_snapshot_name);
2048 Session::route_mute_changed (void* src)
2054 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2056 if (solo_update_disabled) {
2062 boost::shared_ptr<Route> route = wpr.lock ();
2065 /* should not happen */
2066 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2070 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2072 shared_ptr<RouteList> r = routes.reader ();
2074 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2076 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2080 /* don't mess with busses */
2082 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2088 /* don't mess with tracks */
2090 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2095 if ((*i) != route &&
2096 ((*i)->mix_group () == 0 ||
2097 (*i)->mix_group () != route->mix_group () ||
2098 !route->mix_group ()->is_active())) {
2100 if ((*i)->soloed()) {
2102 /* if its already soloed, and solo latching is enabled,
2103 then leave it as it is.
2106 if (Config->get_solo_latched()) {
2113 solo_update_disabled = true;
2114 (*i)->set_solo (false, src);
2115 solo_update_disabled = false;
2119 bool something_soloed = false;
2120 bool same_thing_soloed = false;
2121 bool signal = false;
2123 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2124 if ((*i)->soloed()) {
2125 something_soloed = true;
2126 if (dynamic_cast<AudioTrack*>((*i).get())) {
2128 same_thing_soloed = true;
2133 same_thing_soloed = true;
2141 if (something_soloed != currently_soloing) {
2143 currently_soloing = something_soloed;
2146 modify_solo_mute (is_track, same_thing_soloed);
2149 SoloActive (currently_soloing); /* EMIT SIGNAL */
2152 SoloChanged (); /* EMIT SIGNAL */
2158 Session::update_route_solo_state ()
2161 bool is_track = false;
2162 bool signal = false;
2164 /* caller must hold RouteLock */
2166 /* this is where we actually implement solo by changing
2167 the solo mute setting of each track.
2170 shared_ptr<RouteList> r = routes.reader ();
2172 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2173 if ((*i)->soloed()) {
2175 if (dynamic_cast<AudioTrack*>((*i).get())) {
2182 if (mute != currently_soloing) {
2184 currently_soloing = mute;
2187 if (!is_track && !mute) {
2189 /* nothing is soloed */
2191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2192 (*i)->set_solo_mute (false);
2202 modify_solo_mute (is_track, mute);
2205 SoloActive (currently_soloing);
2210 Session::modify_solo_mute (bool is_track, bool mute)
2212 shared_ptr<RouteList> r = routes.reader ();
2214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2218 /* only alter track solo mute */
2220 if (dynamic_cast<AudioTrack*>((*i).get())) {
2221 if ((*i)->soloed()) {
2222 (*i)->set_solo_mute (!mute);
2224 (*i)->set_solo_mute (mute);
2230 /* only alter bus solo mute */
2232 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2234 if ((*i)->soloed()) {
2236 (*i)->set_solo_mute (false);
2240 /* don't mute master or control outs
2241 in response to another bus solo
2244 if ((*i) != _master_out &&
2245 (*i) != _control_out) {
2246 (*i)->set_solo_mute (mute);
2257 Session::catch_up_on_solo ()
2259 /* this is called after set_state() to catch the full solo
2260 state, which can't be correctly determined on a per-route
2261 basis, but needs the global overview that only the session
2264 update_route_solo_state();
2268 Session::route_by_name (string name)
2270 shared_ptr<RouteList> r = routes.reader ();
2272 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2273 if ((*i)->name() == name) {
2278 return shared_ptr<Route> ((Route*) 0);
2282 Session::route_by_id (PBD::ID id)
2284 shared_ptr<RouteList> r = routes.reader ();
2286 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2287 if ((*i)->id() == id) {
2292 return shared_ptr<Route> ((Route*) 0);
2296 Session::route_by_remote_id (uint32_t id)
2298 shared_ptr<RouteList> r = routes.reader ();
2300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2301 if ((*i)->remote_control_id() == id) {
2306 return shared_ptr<Route> ((Route*) 0);
2310 Session::find_current_end ()
2312 if (_state_of_the_state & Loading) {
2316 nframes_t max = get_maximum_extent ();
2318 if (max > end_location->end()) {
2319 end_location->set_end (max);
2321 DurationChanged(); /* EMIT SIGNAL */
2326 Session::get_maximum_extent () const
2331 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2333 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2334 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2335 if ((me = pl->get_maximum_extent()) > max) {
2343 boost::shared_ptr<Diskstream>
2344 Session::diskstream_by_name (string name)
2346 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2348 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2349 if ((*i)->name() == name) {
2354 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2357 boost::shared_ptr<Diskstream>
2358 Session::diskstream_by_id (const PBD::ID& id)
2360 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2362 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2363 if ((*i)->id() == id) {
2368 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2371 /* AudioRegion management */
2374 Session::new_region_name (string old)
2376 string::size_type last_period;
2378 string::size_type len = old.length() + 64;
2381 if ((last_period = old.find_last_of ('.')) == string::npos) {
2383 /* no period present - add one explicitly */
2386 last_period = old.length() - 1;
2391 number = atoi (old.substr (last_period+1).c_str());
2395 while (number < (UINT_MAX-1)) {
2397 AudioRegionList::const_iterator i;
2402 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2405 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2406 if (i->second->name() == sbuf) {
2411 if (i == audio_regions.end()) {
2416 if (number != (UINT_MAX-1)) {
2420 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2425 Session::region_name (string& result, string base, bool newlevel) const
2432 Glib::Mutex::Lock lm (region_lock);
2434 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2442 /* XXX this is going to be slow. optimize me later */
2447 string::size_type pos;
2449 pos = base.find_last_of ('.');
2451 /* pos may be npos, but then we just use entire base */
2453 subbase = base.substr (0, pos);
2457 bool name_taken = true;
2460 Glib::Mutex::Lock lm (region_lock);
2462 for (int n = 1; n < 5000; ++n) {
2465 snprintf (buf, sizeof (buf), ".%d", n);
2470 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2471 if (i->second->name() == result) {
2484 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2492 Session::add_region (boost::shared_ptr<Region> region)
2494 boost::shared_ptr<AudioRegion> ar;
2495 boost::shared_ptr<AudioRegion> oar;
2499 Glib::Mutex::Lock lm (region_lock);
2501 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2503 AudioRegionList::iterator x;
2505 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2507 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2509 if (ar->region_list_equivalent (oar)) {
2514 if (x == audio_regions.end()) {
2516 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2518 entry.first = region->id();
2521 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2533 fatal << _("programming error: ")
2534 << X_("unknown region type passed to Session::add_region()")
2541 /* mark dirty because something has changed even if we didn't
2542 add the region to the region list.
2548 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2549 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2550 AudioRegionAdded (ar); /* EMIT SIGNAL */
2555 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2557 boost::shared_ptr<Region> region (weak_region.lock ());
2563 if (what_changed & Region::HiddenChanged) {
2564 /* relay hidden changes */
2565 RegionHiddenChange (region);
2570 Session::remove_region (boost::weak_ptr<Region> weak_region)
2572 AudioRegionList::iterator i;
2573 boost::shared_ptr<Region> region (weak_region.lock ());
2579 boost::shared_ptr<AudioRegion> ar;
2580 bool removed = false;
2583 Glib::Mutex::Lock lm (region_lock);
2585 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2586 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2587 audio_regions.erase (i);
2593 fatal << _("programming error: ")
2594 << X_("unknown region type passed to Session::remove_region()")
2600 /* mark dirty because something has changed even if we didn't
2601 remove the region from the region list.
2607 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2611 boost::shared_ptr<AudioRegion>
2612 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2614 AudioRegionList::iterator i;
2615 boost::shared_ptr<AudioRegion> region;
2616 Glib::Mutex::Lock lm (region_lock);
2618 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2622 if (region->whole_file()) {
2624 if (child->source_equivalent (region)) {
2630 return boost::shared_ptr<AudioRegion> ();
2634 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2636 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2637 (*i)->get_region_list_equivalent_regions (region, result);
2641 Session::destroy_region (boost::shared_ptr<Region> region)
2643 vector<boost::shared_ptr<Source> > srcs;
2646 boost::shared_ptr<AudioRegion> aregion;
2648 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2652 if (aregion->playlist()) {
2653 aregion->playlist()->destroy_region (region);
2656 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2657 srcs.push_back (aregion->source (n));
2661 region->drop_references ();
2663 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2665 if (!(*i)->used()) {
2666 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2669 (afs)->mark_for_remove ();
2672 (*i)->drop_references ();
2674 cerr << "source was not used by any playlist\n";
2682 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2684 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2685 destroy_region (*i);
2691 Session::remove_last_capture ()
2693 list<boost::shared_ptr<Region> > r;
2695 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2697 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2698 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2701 r.insert (r.end(), l.begin(), l.end());
2706 destroy_regions (r);
2711 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2717 /* Source Management */
2720 Session::add_source (boost::shared_ptr<Source> source)
2722 boost::shared_ptr<AudioFileSource> afs;
2724 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2726 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2727 pair<AudioSourceList::iterator,bool> result;
2729 entry.first = source->id();
2733 Glib::Mutex::Lock lm (audio_source_lock);
2734 result = audio_sources.insert (entry);
2737 if (result.second) {
2738 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2746 Session::remove_source (boost::weak_ptr<Source> src)
2748 AudioSourceList::iterator i;
2749 boost::shared_ptr<Source> source = src.lock();
2756 Glib::Mutex::Lock lm (audio_source_lock);
2758 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2759 audio_sources.erase (i);
2763 if (!_state_of_the_state & InCleanup) {
2765 /* save state so we don't end up with a session file
2766 referring to non-existent sources.
2769 save_state (_current_snapshot_name);
2773 boost::shared_ptr<Source>
2774 Session::source_by_id (const PBD::ID& id)
2776 Glib::Mutex::Lock lm (audio_source_lock);
2777 AudioSourceList::iterator i;
2778 boost::shared_ptr<Source> source;
2780 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2784 /* XXX search MIDI or other searches here */
2790 Session::peak_path_from_audio_path (string audio_path) const
2795 res += PBD::basename_nosuffix (audio_path);
2802 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2805 string old_basename = PBD::basename_nosuffix (oldname);
2806 string new_legalized = legalize_for_path (newname);
2808 /* note: we know (or assume) the old path is already valid */
2812 /* destructive file sources have a name of the form:
2814 /path/to/Tnnnn-NAME(%[LR])?.wav
2816 the task here is to replace NAME with the new name.
2819 /* find last slash */
2823 string::size_type slash;
2824 string::size_type dash;
2826 if ((slash = path.find_last_of ('/')) == string::npos) {
2830 dir = path.substr (0, slash+1);
2832 /* '-' is not a legal character for the NAME part of the path */
2834 if ((dash = path.find_last_of ('-')) == string::npos) {
2838 prefix = path.substr (slash+1, dash-(slash+1));
2843 path += new_legalized;
2844 path += ".wav"; /* XXX gag me with a spoon */
2848 /* non-destructive file sources have a name of the form:
2850 /path/to/NAME-nnnnn(%[LR])?.wav
2852 the task here is to replace NAME with the new name.
2857 string::size_type slash;
2858 string::size_type dash;
2859 string::size_type postfix;
2861 /* find last slash */
2863 if ((slash = path.find_last_of ('/')) == string::npos) {
2867 dir = path.substr (0, slash+1);
2869 /* '-' is not a legal character for the NAME part of the path */
2871 if ((dash = path.find_last_of ('-')) == string::npos) {
2875 suffix = path.substr (dash+1);
2877 // Suffix is now everything after the dash. Now we need to eliminate
2878 // the nnnnn part, which is done by either finding a '%' or a '.'
2880 postfix = suffix.find_last_of ("%");
2881 if (postfix == string::npos) {
2882 postfix = suffix.find_last_of ('.');
2885 if (postfix != string::npos) {
2886 suffix = suffix.substr (postfix);
2888 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2892 const uint32_t limit = 10000;
2893 char buf[PATH_MAX+1];
2895 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2897 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2899 if (access (buf, F_OK) != 0) {
2907 error << "FATAL ERROR! Could not find a " << endl;
2916 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2920 char buf[PATH_MAX+1];
2921 const uint32_t limit = 10000;
2925 legalized = legalize_for_path (name);
2927 /* find a "version" of the file name that doesn't exist in
2928 any of the possible directories.
2931 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2933 vector<space_and_path>::iterator i;
2934 uint32_t existing = 0;
2936 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2940 spath += sound_dir (false);
2944 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2945 } else if (nchan == 2) {
2947 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2949 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2951 } else if (nchan < 26) {
2952 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2954 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2963 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2964 } else if (nchan == 2) {
2966 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2968 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2970 } else if (nchan < 26) {
2971 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2973 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2977 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2983 if (existing == 0) {
2988 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2990 throw failed_constructor();
2994 /* we now have a unique name for the file, but figure out where to
3000 spath = discover_best_sound_dir ();
3003 string::size_type pos = foo.find_last_of ('/');
3005 if (pos == string::npos) {
3008 spath += foo.substr (pos + 1);
3014 boost::shared_ptr<AudioFileSource>
3015 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3017 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3018 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3021 /* Playlist management */
3023 boost::shared_ptr<Playlist>
3024 Session::playlist_by_name (string name)
3026 Glib::Mutex::Lock lm (playlist_lock);
3027 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3028 if ((*i)->name() == name) {
3032 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3033 if ((*i)->name() == name) {
3038 return boost::shared_ptr<Playlist>();
3042 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3044 if (playlist->hidden()) {
3049 Glib::Mutex::Lock lm (playlist_lock);
3050 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3051 playlists.insert (playlists.begin(), playlist);
3052 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3053 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3059 PlaylistAdded (playlist); /* EMIT SIGNAL */
3063 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3066 Glib::Mutex::Lock lm (playlist_lock);
3067 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3070 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3077 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3079 boost::shared_ptr<Playlist> pl(wpl.lock());
3085 PlaylistList::iterator x;
3088 /* its not supposed to be visible */
3093 Glib::Mutex::Lock lm (playlist_lock);
3097 unused_playlists.insert (pl);
3099 if ((x = playlists.find (pl)) != playlists.end()) {
3100 playlists.erase (x);
3106 playlists.insert (pl);
3108 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3109 unused_playlists.erase (x);
3116 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3118 if (_state_of_the_state & Deletion) {
3122 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3129 Glib::Mutex::Lock lm (playlist_lock);
3131 PlaylistList::iterator i;
3133 i = find (playlists.begin(), playlists.end(), playlist);
3134 if (i != playlists.end()) {
3135 playlists.erase (i);
3138 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3139 if (i != unused_playlists.end()) {
3140 unused_playlists.erase (i);
3147 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3151 Session::set_audition (boost::shared_ptr<Region> r)
3153 pending_audition_region = r;
3154 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3155 schedule_butler_transport_work ();
3159 Session::audition_playlist ()
3161 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3162 ev->region.reset ();
3167 Session::non_realtime_set_audition ()
3169 if (!pending_audition_region) {
3170 auditioner->audition_current_playlist ();
3172 auditioner->audition_region (pending_audition_region);
3173 pending_audition_region.reset ();
3175 AuditionActive (true); /* EMIT SIGNAL */
3179 Session::audition_region (boost::shared_ptr<Region> r)
3181 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3187 Session::cancel_audition ()
3189 if (auditioner->active()) {
3190 auditioner->cancel_audition ();
3191 AuditionActive (false); /* EMIT SIGNAL */
3196 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3198 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3202 Session::remove_empty_sounds ()
3204 PathScanner scanner;
3206 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3208 Glib::Mutex::Lock lm (audio_source_lock);
3210 regex_t compiled_tape_track_pattern;
3213 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3217 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3219 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3223 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3225 /* never remove files that appear to be a tape track */
3227 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3232 if (AudioFileSource::is_empty (*this, *(*i))) {
3234 unlink ((*i)->c_str());
3236 string peak_path = peak_path_from_audio_path (**i);
3237 unlink (peak_path.c_str());
3243 delete possible_audiofiles;
3247 Session::is_auditioning () const
3249 /* can be called before we have an auditioner object */
3251 return auditioner->active();
3258 Session::set_all_solo (bool yn)
3260 shared_ptr<RouteList> r = routes.reader ();
3262 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3263 if (!(*i)->hidden()) {
3264 (*i)->set_solo (yn, this);
3272 Session::set_all_mute (bool yn)
3274 shared_ptr<RouteList> r = routes.reader ();
3276 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3277 if (!(*i)->hidden()) {
3278 (*i)->set_mute (yn, this);
3286 Session::n_diskstreams () const
3290 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3292 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3293 if (!(*i)->hidden()) {
3301 Session::graph_reordered ()
3303 /* don't do this stuff if we are setting up connections
3304 from a set_state() call.
3307 if (_state_of_the_state & InitialConnecting) {
3311 /* every track/bus asked for this to be handled but it was deferred because
3312 we were connecting. do it now.
3315 request_input_change_handling ();
3319 /* force all diskstreams to update their capture offset values to
3320 reflect any changes in latencies within the graph.
3323 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3325 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3326 (*i)->set_capture_offset ();
3331 Session::record_disenable_all ()
3333 record_enable_change_all (false);
3337 Session::record_enable_all ()
3339 record_enable_change_all (true);
3343 Session::record_enable_change_all (bool yn)
3345 shared_ptr<RouteList> r = routes.reader ();
3347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3350 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3351 at->set_record_enable (yn, this);
3355 /* since we don't keep rec-enable state, don't mark session dirty */
3359 Session::add_redirect (Redirect* redirect)
3363 PortInsert* port_insert;
3364 PluginInsert* plugin_insert;
3366 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3367 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3368 _port_inserts.insert (_port_inserts.begin(), port_insert);
3369 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3370 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3372 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3375 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3376 _sends.insert (_sends.begin(), send);
3378 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3382 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3388 Session::remove_redirect (Redirect* redirect)
3392 PortInsert* port_insert;
3393 PluginInsert* plugin_insert;
3395 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3396 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3397 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3398 if (x != _port_inserts.end()) {
3399 insert_bitset[port_insert->bit_slot()] = false;
3400 _port_inserts.erase (x);
3402 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3403 _plugin_inserts.remove (plugin_insert);
3405 fatal << string_compose (_("programming error: %1"),
3406 X_("unknown type of Insert deleted!"))
3410 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3411 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3412 if (x != _sends.end()) {
3413 send_bitset[send->bit_slot()] = false;
3417 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3425 Session::available_capture_duration ()
3427 float sample_bytes_on_disk = 4.0; // keep gcc happy
3429 switch (Config->get_native_file_data_format()) {
3431 sample_bytes_on_disk = 4.0;
3435 sample_bytes_on_disk = 3.0;
3439 /* impossible, but keep some gcc versions happy */
3440 fatal << string_compose (_("programming error: %1"),
3441 X_("illegal native file data format"))
3446 double scale = 4096.0 / sample_bytes_on_disk;
3448 if (_total_free_4k_blocks * scale > (double) max_frames) {
3452 return (nframes_t) floor (_total_free_4k_blocks * scale);
3456 Session::add_connection (ARDOUR::Connection* connection)
3459 Glib::Mutex::Lock guard (connection_lock);
3460 _connections.push_back (connection);
3463 ConnectionAdded (connection); /* EMIT SIGNAL */
3469 Session::remove_connection (ARDOUR::Connection* connection)
3471 bool removed = false;
3474 Glib::Mutex::Lock guard (connection_lock);
3475 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3477 if (i != _connections.end()) {
3478 _connections.erase (i);
3484 ConnectionRemoved (connection); /* EMIT SIGNAL */
3490 ARDOUR::Connection *
3491 Session::connection_by_name (string name) const
3493 Glib::Mutex::Lock lm (connection_lock);
3495 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3496 if ((*i)->name() == name) {
3505 Session::tempo_map_changed (Change ignored)
3512 Session::ensure_passthru_buffers (uint32_t howmany)
3514 while (howmany > _passthru_buffers.size()) {
3516 #ifdef NO_POSIX_MEMALIGN
3517 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3519 posix_memalign((void **)&p,16,current_block_size * 4);
3521 _passthru_buffers.push_back (p);
3525 #ifdef NO_POSIX_MEMALIGN
3526 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3528 posix_memalign((void **)&p,16,current_block_size * 4);
3530 memset (p, 0, sizeof (Sample) * current_block_size);
3531 _silent_buffers.push_back (p);
3535 #ifdef NO_POSIX_MEMALIGN
3536 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3538 posix_memalign((void **)&p,16,current_block_size * 4);
3540 memset (p, 0, sizeof (Sample) * current_block_size);
3541 _send_buffers.push_back (p);
3544 allocate_pan_automation_buffers (current_block_size, howmany, false);
3548 Session::next_insert_id ()
3550 /* this doesn't really loop forever. just think about it */
3553 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3554 if (!insert_bitset[n]) {
3555 insert_bitset[n] = true;
3556 cerr << "Returning " << n << " as insert ID\n";
3562 /* none available, so resize and try again */
3564 insert_bitset.resize (insert_bitset.size() + 16, false);
3569 Session::next_send_id ()
3571 /* this doesn't really loop forever. just think about it */
3574 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3575 if (!send_bitset[n]) {
3576 send_bitset[n] = true;
3577 cerr << "Returning " << n << " as send ID\n";
3583 /* none available, so resize and try again */
3585 send_bitset.resize (send_bitset.size() + 16, false);
3590 Session::mark_send_id (uint32_t id)
3592 if (id >= send_bitset.size()) {
3593 send_bitset.resize (id+16, false);
3595 if (send_bitset[id]) {
3596 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3598 send_bitset[id] = true;
3602 Session::mark_insert_id (uint32_t id)
3604 if (id >= insert_bitset.size()) {
3605 insert_bitset.resize (id+16, false);
3607 if (insert_bitset[id]) {
3608 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3610 insert_bitset[id] = true;
3613 /* Named Selection management */
3616 Session::named_selection_by_name (string name)
3618 Glib::Mutex::Lock lm (named_selection_lock);
3619 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3620 if ((*i)->name == name) {
3628 Session::add_named_selection (NamedSelection* named_selection)
3631 Glib::Mutex::Lock lm (named_selection_lock);
3632 named_selections.insert (named_selections.begin(), named_selection);
3635 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3641 NamedSelectionAdded (); /* EMIT SIGNAL */
3645 Session::remove_named_selection (NamedSelection* named_selection)
3647 bool removed = false;
3650 Glib::Mutex::Lock lm (named_selection_lock);
3652 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3654 if (i != named_selections.end()) {
3656 named_selections.erase (i);
3663 NamedSelectionRemoved (); /* EMIT SIGNAL */
3668 Session::reset_native_file_format ()
3670 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3672 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3673 (*i)->reset_write_sources (false);
3678 Session::route_name_unique (string n) const
3680 shared_ptr<RouteList> r = routes.reader ();
3682 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3683 if ((*i)->name() == n) {
3692 Session::n_playlists () const
3694 Glib::Mutex::Lock lm (playlist_lock);
3695 return playlists.size();
3699 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3701 if (!force && howmany <= _npan_buffers) {
3705 if (_pan_automation_buffer) {
3707 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3708 delete [] _pan_automation_buffer[i];
3711 delete [] _pan_automation_buffer;
3714 _pan_automation_buffer = new pan_t*[howmany];
3716 for (uint32_t i = 0; i < howmany; ++i) {
3717 _pan_automation_buffer[i] = new pan_t[nframes];
3720 _npan_buffers = howmany;
3724 Session::freeze (InterThreadInfo& itt)
3726 shared_ptr<RouteList> r = routes.reader ();
3728 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3732 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3733 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3744 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3745 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3748 boost::shared_ptr<Playlist> playlist;
3749 boost::shared_ptr<AudioFileSource> fsource;
3751 char buf[PATH_MAX+1];
3755 nframes_t this_chunk;
3757 vector<Sample*> buffers;
3759 // any bigger than this seems to cause stack overflows in called functions
3760 const nframes_t chunk_size = (128 * 1024)/4;
3762 g_atomic_int_set (&processing_prohibited, 1);
3764 /* call tree *MUST* hold route_lock */
3766 if ((playlist = track.diskstream()->playlist()) == 0) {
3770 /* external redirects will be a problem */
3772 if (track.has_external_redirects()) {
3776 nchans = track.audio_diskstream()->n_channels();
3778 dir = discover_best_sound_dir ();
3780 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3782 for (x = 0; x < 99999; ++x) {
3783 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3784 if (access (buf, F_OK) != 0) {
3790 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3795 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3798 catch (failed_constructor& err) {
3799 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3803 srcs.push_back (fsource);
3806 /* XXX need to flush all redirects */
3811 /* create a set of reasonably-sized buffers */
3813 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3815 #ifdef NO_POSIX_MEMALIGN
3816 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3818 posix_memalign((void **)&b,16,chunk_size * 4);
3820 buffers.push_back (b);
3823 while (to_do && !itt.cancel) {
3825 this_chunk = min (to_do, chunk_size);
3827 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3832 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3833 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3836 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3842 start += this_chunk;
3843 to_do -= this_chunk;
3845 itt.progress = (float) (1.0 - ((double) to_do / len));
3854 xnow = localtime (&now);
3856 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3857 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3860 afs->update_header (position, *xnow, now);
3864 /* build peakfile for new source */
3866 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3867 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3869 afs->build_peaks ();
3873 /* construct a region to represent the bounced material */
3875 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3876 region_name_from_path (srcs.front()->name(), true));
3883 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3884 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3887 afs->mark_for_remove ();
3890 (*src)->drop_references ();
3894 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3898 g_atomic_int_set (&processing_prohibited, 0);
3906 Session::get_silent_buffers (uint32_t howmany)
3908 for (uint32_t i = 0; i < howmany; ++i) {
3909 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3911 return _silent_buffers;
3915 Session::ntracks () const
3918 shared_ptr<RouteList> r = routes.reader ();
3920 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3921 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3930 Session::nbusses () const
3933 shared_ptr<RouteList> r = routes.reader ();
3935 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3936 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3945 Session::add_automation_list(AutomationList *al)
3947 automation_lists[al->id()] = al;
3951 Session::compute_initial_length ()
3953 return _engine.frame_rate() * 60 * 5;