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>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/auditioner.h>
53 #include <ardour/recent_sessions.h>
54 #include <ardour/redirect.h>
55 #include <ardour/send.h>
56 #include <ardour/insert.h>
57 #include <ardour/connection.h>
58 #include <ardour/slave.h>
59 #include <ardour/tempo.h>
60 #include <ardour/audio_track.h>
61 #include <ardour/cycle_timer.h>
62 #include <ardour/named_selection.h>
63 #include <ardour/crossfade.h>
64 #include <ardour/playlist.h>
65 #include <ardour/click.h>
66 #include <ardour/data_type.h>
67 #include <ardour/source_factory.h>
68 #include <ardour/region_factory.h>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
81 const char* Session::_template_suffix = X_(".template");
82 const char* Session::_statefile_suffix = X_(".ardour");
83 const char* Session::_pending_suffix = X_(".pending");
84 const char* Session::old_sound_dir_name = X_("sounds");
85 const char* Session::sound_dir_name = X_("audiofiles");
86 const char* Session::peak_dir_name = X_("peaks");
87 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 const char* Session::interchange_dir_name = X_("interchange");
89 const char* Session::export_dir_name = X_("export");
91 Session::compute_peak_t Session::compute_peak = 0;
92 Session::find_peaks_t Session::find_peaks = 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 if (!eng.connected()) {
274 throw failed_constructor();
277 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
279 n_physical_outputs = _engine.n_physical_outputs();
280 n_physical_inputs = _engine.n_physical_inputs();
282 first_stage_init (fullpath, snapshot_name);
284 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
286 if (create (new_session, mix_template, compute_initial_length())) {
287 cerr << "create failed\n";
289 throw failed_constructor ();
293 if (second_stage_init (new_session)) {
295 throw failed_constructor ();
298 store_recent_sessions(_name, _path);
300 bool was_dirty = dirty();
302 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
304 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
307 DirtyChanged (); /* EMIT SIGNAL */
311 Session::Session (AudioEngine &eng,
313 string snapshot_name,
314 AutoConnectOption input_ac,
315 AutoConnectOption output_ac,
316 uint32_t control_out_channels,
317 uint32_t master_out_channels,
318 uint32_t requested_physical_in,
319 uint32_t requested_physical_out,
320 nframes_t initial_length)
323 _mmc_port (default_mmc_port),
324 _mtc_port (default_mtc_port),
325 _midi_port (default_midi_port),
326 pending_events (2048),
328 diskstreams (new DiskstreamList),
329 routes (new RouteList),
335 if (!eng.connected()) {
336 throw failed_constructor();
339 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
341 n_physical_outputs = _engine.n_physical_outputs();
342 n_physical_inputs = _engine.n_physical_inputs();
344 if (n_physical_inputs) {
345 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
348 if (n_physical_outputs) {
349 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
352 first_stage_init (fullpath, snapshot_name);
354 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
357 if (create (new_session, 0, initial_length)) {
359 throw failed_constructor ();
364 /* set up Master Out and Control Out if necessary */
369 if (control_out_channels) {
370 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
371 r->set_remote_control_id (control_id++);
376 if (master_out_channels) {
377 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
378 r->set_remote_control_id (control_id);
382 /* prohibit auto-connect to master, because there isn't one */
383 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
392 Config->set_input_auto_connect (input_ac);
393 Config->set_output_auto_connect (output_ac);
395 if (second_stage_init (new_session)) {
397 throw failed_constructor ();
400 store_recent_sessions(_name, _path);
402 bool was_dirty = dirty ();
404 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
406 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
409 DirtyChanged (); /* EMIT SIGNAL */
421 /* if we got to here, leaving pending capture state around
425 remove_pending_capture_state ();
427 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
428 _engine.remove_session ();
430 GoingAway (); /* EMIT SIGNAL */
436 /* clear history so that no references to objects are held any more */
440 /* clear state tree so that no references to objects are held any more */
446 terminate_butler_thread ();
447 terminate_midi_thread ();
449 if (click_data && click_data != default_click) {
450 delete [] click_data;
453 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
454 delete [] click_emphasis_data;
459 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
463 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
467 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
471 AudioDiskstream::free_working_buffers();
473 /* this should cause deletion of the auditioner */
475 // auditioner.reset ();
477 #undef TRACK_DESTRUCTION
478 #ifdef TRACK_DESTRUCTION
479 cerr << "delete named selections\n";
480 #endif /* TRACK_DESTRUCTION */
481 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
482 NamedSelectionList::iterator tmp;
491 #ifdef TRACK_DESTRUCTION
492 cerr << "delete playlists\n";
493 #endif /* TRACK_DESTRUCTION */
494 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
495 PlaylistList::iterator tmp;
500 (*i)->drop_references ();
505 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
506 PlaylistList::iterator tmp;
511 (*i)->drop_references ();
517 unused_playlists.clear ();
519 #ifdef TRACK_DESTRUCTION
520 cerr << "delete audio regions\n";
521 #endif /* TRACK_DESTRUCTION */
523 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
524 AudioRegionList::iterator tmp;
529 i->second->drop_references ();
534 audio_regions.clear ();
536 #ifdef TRACK_DESTRUCTION
537 cerr << "delete routes\n";
538 #endif /* TRACK_DESTRUCTION */
540 RCUWriter<RouteList> writer (routes);
541 boost::shared_ptr<RouteList> r = writer.get_copy ();
542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
543 (*i)->drop_references ();
546 /* writer goes out of scope and updates master */
551 #ifdef TRACK_DESTRUCTION
552 cerr << "delete diskstreams\n";
553 #endif /* TRACK_DESTRUCTION */
555 RCUWriter<DiskstreamList> dwriter (diskstreams);
556 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
557 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
558 (*i)->drop_references ();
562 diskstreams.flush ();
564 #ifdef TRACK_DESTRUCTION
565 cerr << "delete audio sources\n";
566 #endif /* TRACK_DESTRUCTION */
567 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
568 AudioSourceList::iterator tmp;
573 i->second->drop_references ();
578 audio_sources.clear ();
580 #ifdef TRACK_DESTRUCTION
581 cerr << "delete mix groups\n";
582 #endif /* TRACK_DESTRUCTION */
583 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
584 list<RouteGroup*>::iterator tmp;
594 #ifdef TRACK_DESTRUCTION
595 cerr << "delete edit groups\n";
596 #endif /* TRACK_DESTRUCTION */
597 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
598 list<RouteGroup*>::iterator tmp;
608 #ifdef TRACK_DESTRUCTION
609 cerr << "delete connections\n";
610 #endif /* TRACK_DESTRUCTION */
611 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
612 ConnectionList::iterator tmp;
622 if (butler_mixdown_buffer) {
623 delete [] butler_mixdown_buffer;
626 if (butler_gain_buffer) {
627 delete [] butler_gain_buffer;
630 Crossfade::set_buffer_size (0);
638 Session::set_worst_io_latencies ()
640 _worst_output_latency = 0;
641 _worst_input_latency = 0;
643 if (!_engine.connected()) {
647 boost::shared_ptr<RouteList> r = routes.reader ();
649 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
650 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
651 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
656 Session::when_engine_running ()
658 string first_physical_output;
660 /* we don't want to run execute this again */
662 set_block_size (_engine.frames_per_cycle());
663 set_frame_rate (_engine.frame_rate());
665 Config->map_parameters (mem_fun (*this, &Session::config_changed));
667 /* every time we reconnect, recompute worst case output latencies */
669 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
671 if (synced_to_jack()) {
672 _engine.transport_stop ();
675 if (Config->get_jack_time_master()) {
676 _engine.transport_locate (_transport_frame);
684 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
686 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
688 /* existing state for Click */
690 if (_click_io->set_state (*child->children().front()) == 0) {
692 _clicking = Config->get_clicking ();
696 error << _("could not setup Click I/O") << endmsg;
702 /* default state for Click */
704 first_physical_output = _engine.get_nth_physical_output (0);
706 if (first_physical_output.length()) {
707 if (_click_io->add_output_port (first_physical_output, this)) {
708 // relax, even though its an error
710 _clicking = Config->get_clicking ();
716 catch (failed_constructor& err) {
717 error << _("cannot setup Click I/O") << endmsg;
720 set_worst_io_latencies ();
723 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
726 /* Create a set of Connection objects that map
727 to the physical outputs currently available
732 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
734 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
736 Connection* c = new OutputConnection (buf, true);
739 c->add_connection (0, _engine.get_nth_physical_output (np));
744 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
746 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
748 Connection* c = new InputConnection (buf, true);
751 c->add_connection (0, _engine.get_nth_physical_input (np));
758 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
760 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
762 Connection* c = new OutputConnection (buf, true);
766 c->add_connection (0, _engine.get_nth_physical_output (np));
767 c->add_connection (1, _engine.get_nth_physical_output (np+1));
772 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
774 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
776 Connection* c = new InputConnection (buf, true);
780 c->add_connection (0, _engine.get_nth_physical_input (np));
781 c->add_connection (1, _engine.get_nth_physical_input (np+1));
790 /* create master/control ports */
795 /* force the master to ignore any later call to this */
797 if (_master_out->pending_state_node) {
798 _master_out->ports_became_legal();
801 /* no panner resets till we are through */
803 _master_out->defer_pan_reset ();
805 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
806 if (_master_out->add_input_port ("", this)) {
807 error << _("cannot setup master inputs")
813 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
814 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
815 error << _("cannot setup master outputs")
822 _master_out->allow_pan_reset ();
826 Connection* c = new OutputConnection (_("Master Out"), true);
828 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
830 c->add_connection ((int) n, _master_out->input(n)->name());
837 /* catch up on send+insert cnts */
841 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
844 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
845 if (id > insert_cnt) {
853 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
856 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
864 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
866 /* hook us up to the engine */
868 _engine.set_session (this);
873 osc->set_session (*this);
876 _state_of_the_state = Clean;
878 DirtyChanged (); /* EMIT SIGNAL */
882 Session::hookup_io ()
884 /* stop graph reordering notifications from
885 causing resorts, etc.
888 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
890 if (auditioner == 0) {
892 /* we delay creating the auditioner till now because
893 it makes its own connections to ports.
894 the engine has to be running for this to work.
898 auditioner.reset (new Auditioner (*this));
901 catch (failed_constructor& err) {
902 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
906 /* Tell all IO objects to create their ports */
913 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
914 if (_control_out->add_input_port ("", this)) {
915 error << _("cannot setup control inputs")
921 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
922 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
923 error << _("cannot set up master outputs")
931 /* Tell all IO objects to connect themselves together */
933 IO::enable_connecting ();
935 /* Now reset all panners */
937 IO::reset_panners ();
939 /* Anyone who cares about input state, wake up and do something */
941 IOConnectionsComplete (); /* EMIT SIGNAL */
943 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
945 /* now handle the whole enchilada as if it was one
951 /* update mixer solo state */
957 Session::playlist_length_changed ()
959 /* we can't just increase end_location->end() if pl->get_maximum_extent()
960 if larger. if the playlist used to be the longest playlist,
961 and its now shorter, we have to decrease end_location->end(). hence,
962 we have to iterate over all diskstreams and check the
963 playlists currently in use.
969 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
971 boost::shared_ptr<Playlist> playlist;
973 if ((playlist = dstream->playlist()) != 0) {
974 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
977 /* see comment in playlist_length_changed () */
982 Session::record_enabling_legal () const
984 /* this used to be in here, but survey says.... we don't need to restrict it */
985 // if (record_status() == Recording) {
989 if (Config->get_all_safe()) {
996 Session::reset_input_monitor_state ()
998 if (transport_rolling()) {
1000 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1002 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1003 if ((*i)->record_enabled ()) {
1004 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1005 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1009 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1011 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1012 if ((*i)->record_enabled ()) {
1013 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1014 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1021 Session::auto_punch_start_changed (Location* location)
1023 replace_event (Event::PunchIn, location->start());
1025 if (get_record_enabled() && Config->get_punch_in()) {
1026 /* capture start has been changed, so save new pending state */
1027 save_state ("", true);
1032 Session::auto_punch_end_changed (Location* location)
1034 nframes_t when_to_stop = location->end();
1035 // when_to_stop += _worst_output_latency + _worst_input_latency;
1036 replace_event (Event::PunchOut, when_to_stop);
1040 Session::auto_punch_changed (Location* location)
1042 nframes_t when_to_stop = location->end();
1044 replace_event (Event::PunchIn, location->start());
1045 //when_to_stop += _worst_output_latency + _worst_input_latency;
1046 replace_event (Event::PunchOut, when_to_stop);
1050 Session::auto_loop_changed (Location* location)
1052 replace_event (Event::AutoLoop, location->end(), location->start());
1054 if (transport_rolling() && play_loop) {
1056 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1058 if (_transport_frame > location->end()) {
1059 // relocate to beginning of loop
1060 clear_events (Event::LocateRoll);
1062 request_locate (location->start(), true);
1065 else if (Config->get_seamless_loop() && !loop_changing) {
1067 // schedule a locate-roll to refill the diskstreams at the
1068 // previous loop end
1069 loop_changing = true;
1071 if (location->end() > last_loopend) {
1072 clear_events (Event::LocateRoll);
1073 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1080 last_loopend = location->end();
1085 Session::set_auto_punch_location (Location* location)
1089 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1090 auto_punch_start_changed_connection.disconnect();
1091 auto_punch_end_changed_connection.disconnect();
1092 auto_punch_changed_connection.disconnect();
1093 existing->set_auto_punch (false, this);
1094 remove_event (existing->start(), Event::PunchIn);
1095 clear_events (Event::PunchOut);
1096 auto_punch_location_changed (0);
1101 if (location == 0) {
1105 if (location->end() <= location->start()) {
1106 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1110 auto_punch_start_changed_connection.disconnect();
1111 auto_punch_end_changed_connection.disconnect();
1112 auto_punch_changed_connection.disconnect();
1114 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1115 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1116 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1118 location->set_auto_punch (true, this);
1119 auto_punch_location_changed (location);
1123 Session::set_auto_loop_location (Location* location)
1127 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1128 auto_loop_start_changed_connection.disconnect();
1129 auto_loop_end_changed_connection.disconnect();
1130 auto_loop_changed_connection.disconnect();
1131 existing->set_auto_loop (false, this);
1132 remove_event (existing->end(), Event::AutoLoop);
1133 auto_loop_location_changed (0);
1138 if (location == 0) {
1142 if (location->end() <= location->start()) {
1143 error << _("Session: you can't use a mark for auto loop") << endmsg;
1147 last_loopend = location->end();
1149 auto_loop_start_changed_connection.disconnect();
1150 auto_loop_end_changed_connection.disconnect();
1151 auto_loop_changed_connection.disconnect();
1153 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1154 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1155 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1157 location->set_auto_loop (true, this);
1158 auto_loop_location_changed (location);
1162 Session::locations_added (Location* ignored)
1168 Session::locations_changed ()
1170 _locations.apply (*this, &Session::handle_locations_changed);
1174 Session::handle_locations_changed (Locations::LocationList& locations)
1176 Locations::LocationList::iterator i;
1178 bool set_loop = false;
1179 bool set_punch = false;
1181 for (i = locations.begin(); i != locations.end(); ++i) {
1185 if (location->is_auto_punch()) {
1186 set_auto_punch_location (location);
1189 if (location->is_auto_loop()) {
1190 set_auto_loop_location (location);
1197 set_auto_loop_location (0);
1200 set_auto_punch_location (0);
1207 Session::enable_record ()
1209 /* XXX really atomic compare+swap here */
1210 if (g_atomic_int_get (&_record_status) != Recording) {
1211 g_atomic_int_set (&_record_status, Recording);
1212 _last_record_location = _transport_frame;
1213 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1215 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1216 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1217 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1218 if ((*i)->record_enabled ()) {
1219 (*i)->monitor_input (true);
1224 RecordStateChanged ();
1229 Session::disable_record (bool rt_context, bool force)
1233 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1235 if (!Config->get_latched_record_enable () || force) {
1236 g_atomic_int_set (&_record_status, Disabled);
1238 if (rs == Recording) {
1239 g_atomic_int_set (&_record_status, Enabled);
1243 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1245 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1246 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1248 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1249 if ((*i)->record_enabled ()) {
1250 (*i)->monitor_input (false);
1255 RecordStateChanged (); /* emit signal */
1258 remove_pending_capture_state ();
1264 Session::step_back_from_record ()
1266 g_atomic_int_set (&_record_status, Enabled);
1268 if (Config->get_monitoring_model() == HardwareMonitoring) {
1269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1272 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1273 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1274 (*i)->monitor_input (false);
1281 Session::maybe_enable_record ()
1283 g_atomic_int_set (&_record_status, Enabled);
1285 /* this function is currently called from somewhere other than an RT thread.
1286 this save_state() call therefore doesn't impact anything.
1289 save_state ("", true);
1291 if (_transport_speed) {
1292 if (!Config->get_punch_in()) {
1296 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1297 RecordStateChanged (); /* EMIT SIGNAL */
1304 Session::audible_frame () const
1310 /* the first of these two possible settings for "offset"
1311 mean that the audible frame is stationary until
1312 audio emerges from the latency compensation
1315 the second means that the audible frame is stationary
1316 until audio would emerge from a physical port
1317 in the absence of any plugin latency compensation
1320 offset = _worst_output_latency;
1322 if (offset > current_block_size) {
1323 offset -= current_block_size;
1325 /* XXX is this correct? if we have no external
1326 physical connections and everything is internal
1327 then surely this is zero? still, how
1328 likely is that anyway?
1330 offset = current_block_size;
1333 if (synced_to_jack()) {
1334 tf = _engine.transport_frame();
1336 tf = _transport_frame;
1339 if (_transport_speed == 0) {
1349 if (!non_realtime_work_pending()) {
1353 /* take latency into account */
1362 Session::set_frame_rate (nframes_t frames_per_second)
1364 /** \fn void Session::set_frame_size(nframes_t)
1365 the AudioEngine object that calls this guarantees
1366 that it will not be called while we are also in
1367 ::process(). Its fine to do things that block
1371 _base_frame_rate = frames_per_second;
1375 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1377 // XXX we need some equivalent to this, somehow
1378 // SndFileSource::setup_standard_crossfades (frames_per_second);
1382 /* XXX need to reset/reinstantiate all LADSPA plugins */
1386 Session::set_block_size (nframes_t nframes)
1388 /* the AudioEngine guarantees
1389 that it will not be called while we are also in
1390 ::process(). It is therefore fine to do things that block
1395 vector<Sample*>::iterator i;
1398 current_block_size = nframes;
1400 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1404 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1408 _passthru_buffers.clear ();
1409 _silent_buffers.clear ();
1411 ensure_passthru_buffers (np);
1413 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1417 #ifdef NO_POSIX_MEMALIGN
1418 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1420 posix_memalign((void **)&buf,16,current_block_size * 4);
1424 memset (*i, 0, sizeof (Sample) * current_block_size);
1428 if (_gain_automation_buffer) {
1429 delete [] _gain_automation_buffer;
1431 _gain_automation_buffer = new gain_t[nframes];
1433 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1435 boost::shared_ptr<RouteList> r = routes.reader ();
1437 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1438 (*i)->set_block_size (nframes);
1441 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1442 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1443 (*i)->set_block_size (nframes);
1446 set_worst_io_latencies ();
1451 Session::set_default_fade (float steepness, float fade_msecs)
1454 nframes_t fade_frames;
1456 /* Don't allow fade of less 1 frame */
1458 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1465 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1469 default_fade_msecs = fade_msecs;
1470 default_fade_steepness = steepness;
1473 // jlc, WTF is this!
1474 Glib::RWLock::ReaderLock lm (route_lock);
1475 AudioRegion::set_default_fade (steepness, fade_frames);
1480 /* XXX have to do this at some point */
1481 /* foreach region using default fade, reset, then
1482 refill_all_diskstream_buffers ();
1487 struct RouteSorter {
1488 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1489 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1491 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1494 if (r1->fed_by.empty()) {
1495 if (r2->fed_by.empty()) {
1496 /* no ardour-based connections inbound to either route. just use signal order */
1497 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1499 /* r2 has connections, r1 does not; run r1 early */
1503 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1510 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1512 shared_ptr<Route> r2;
1514 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1515 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1519 /* make a copy of the existing list of routes that feed r1 */
1521 set<shared_ptr<Route> > existing = r1->fed_by;
1523 /* for each route that feeds r1, recurse, marking it as feeding
1527 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1530 /* r2 is a route that feeds r1 which somehow feeds base. mark
1531 base as being fed by r2
1534 rbase->fed_by.insert (r2);
1538 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1542 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1546 /* now recurse, so that we can mark base as being fed by
1547 all routes that feed r2
1550 trace_terminal (r2, rbase);
1557 Session::resort_routes ()
1559 /* don't do anything here with signals emitted
1560 by Routes while we are being destroyed.
1563 if (_state_of_the_state & Deletion) {
1570 RCUWriter<RouteList> writer (routes);
1571 shared_ptr<RouteList> r = writer.get_copy ();
1572 resort_routes_using (r);
1573 /* writer goes out of scope and forces update */
1578 Session::resort_routes_using (shared_ptr<RouteList> r)
1580 RouteList::iterator i, j;
1582 for (i = r->begin(); i != r->end(); ++i) {
1584 (*i)->fed_by.clear ();
1586 for (j = r->begin(); j != r->end(); ++j) {
1588 /* although routes can feed themselves, it will
1589 cause an endless recursive descent if we
1590 detect it. so don't bother checking for
1598 if ((*j)->feeds (*i)) {
1599 (*i)->fed_by.insert (*j);
1604 for (i = r->begin(); i != r->end(); ++i) {
1605 trace_terminal (*i, *i);
1611 /* don't leave dangling references to routes in Route::fed_by */
1613 for (i = r->begin(); i != r->end(); ++i) {
1614 (*i)->fed_by.clear ();
1618 cerr << "finished route resort\n";
1620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1621 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1628 list<boost::shared_ptr<AudioTrack> >
1629 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1631 char track_name[32];
1632 uint32_t track_id = 0;
1634 uint32_t channels_used = 0;
1636 RouteList new_routes;
1637 list<boost::shared_ptr<AudioTrack> > ret;
1638 uint32_t control_id;
1640 /* count existing audio tracks */
1643 shared_ptr<RouteList> r = routes.reader ();
1645 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1646 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1647 if (!(*i)->hidden()) {
1649 channels_used += (*i)->n_inputs();
1655 vector<string> physinputs;
1656 vector<string> physoutputs;
1657 uint32_t nphysical_in;
1658 uint32_t nphysical_out;
1660 _engine.get_physical_outputs (physoutputs);
1661 _engine.get_physical_inputs (physinputs);
1662 control_id = ntracks() + nbusses() + 1;
1666 /* check for duplicate route names, since we might have pre-existing
1667 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1668 save, close,restart,add new route - first named route is now
1676 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1678 if (route_by_name (track_name) == 0) {
1682 } while (track_id < (UINT_MAX-1));
1684 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1685 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1690 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1691 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1696 shared_ptr<AudioTrack> track;
1699 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1701 if (track->ensure_io (input_channels, output_channels, false, this)) {
1702 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1703 input_channels, output_channels)
1709 for (uint32_t x = 0; x < track->n_inputs() && 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 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1727 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1728 port = physoutputs[(channels_used+x)%nphysical_out];
1729 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1731 port = _master_out->input (x%_master_out->n_inputs())->name();
1735 if (port.length() && track->connect_output (track->output (x), port, this)) {
1740 channels_used += track->n_inputs ();
1743 vector<string> cports;
1744 uint32_t ni = _control_out->n_inputs();
1746 for (n = 0; n < ni; ++n) {
1747 cports.push_back (_control_out->input(n)->name());
1750 track->set_control_outs (cports);
1753 // assert (current_thread != RT_thread)
1755 track->audio_diskstream()->non_realtime_input_change();
1757 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1758 track->set_remote_control_id (control_id);
1761 new_routes.push_back (track);
1762 ret.push_back (track);
1765 catch (failed_constructor &err) {
1766 error << _("Session: could not create new audio track.") << endmsg;
1769 /* we need to get rid of this, since the track failed to be created */
1770 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1773 RCUWriter<DiskstreamList> writer (diskstreams);
1774 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1775 ds->remove (track->audio_diskstream());
1782 catch (AudioEngine::PortRegistrationFailure& pfe) {
1784 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;
1787 /* we need to get rid of this, since the track failed to be created */
1788 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1791 RCUWriter<DiskstreamList> writer (diskstreams);
1792 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1793 ds->remove (track->audio_diskstream());
1804 if (!new_routes.empty()) {
1805 add_routes (new_routes, false);
1806 save_state (_current_snapshot_name);
1813 Session::set_remote_control_ids ()
1815 RemoteModel m = Config->get_remote_model();
1817 shared_ptr<RouteList> r = routes.reader ();
1819 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1820 if ( MixerOrdered == m) {
1821 long order = (*i)->order_key(N_("signal"));
1822 (*i)->set_remote_control_id( order+1 );
1823 } else if ( EditorOrdered == m) {
1824 long order = (*i)->order_key(N_("editor"));
1825 (*i)->set_remote_control_id( order+1 );
1826 } else if ( UserOrdered == m) {
1827 //do nothing ... only changes to remote id's are initiated by user
1834 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1837 uint32_t bus_id = 1;
1841 uint32_t control_id;
1843 /* count existing audio busses */
1846 shared_ptr<RouteList> r = routes.reader ();
1848 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1849 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1850 if (!(*i)->hidden()) {
1857 vector<string> physinputs;
1858 vector<string> physoutputs;
1860 _engine.get_physical_outputs (physoutputs);
1861 _engine.get_physical_inputs (physinputs);
1862 control_id = ntracks() + nbusses() + 1;
1869 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1871 if (route_by_name (bus_name) == 0) {
1875 } while (bus_id < (UINT_MAX-1));
1878 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1880 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1881 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1882 input_channels, output_channels)
1887 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1891 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1892 port = physinputs[((n+x)%n_physical_inputs)];
1895 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1900 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1904 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1905 port = physoutputs[((n+x)%n_physical_outputs)];
1906 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1908 port = _master_out->input (x%_master_out->n_inputs())->name();
1912 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1918 vector<string> cports;
1919 uint32_t ni = _control_out->n_inputs();
1921 for (uint32_t n = 0; n < ni; ++n) {
1922 cports.push_back (_control_out->input(n)->name());
1924 bus->set_control_outs (cports);
1927 bus->set_remote_control_id (control_id);
1930 ret.push_back (bus);
1934 catch (failed_constructor &err) {
1935 error << _("Session: could not create new audio route.") << endmsg;
1939 catch (AudioEngine::PortRegistrationFailure& pfe) {
1940 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;
1950 add_routes (ret, false);
1951 save_state (_current_snapshot_name);
1959 Session::add_routes (RouteList& new_routes, bool save)
1962 RCUWriter<RouteList> writer (routes);
1963 shared_ptr<RouteList> r = writer.get_copy ();
1964 r->insert (r->end(), new_routes.begin(), new_routes.end());
1965 resort_routes_using (r);
1968 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1970 boost::weak_ptr<Route> wpr (*x);
1972 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1973 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1974 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1975 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1977 if ((*x)->master()) {
1981 if ((*x)->control()) {
1982 _control_out = (*x);
1989 save_state (_current_snapshot_name);
1992 RouteAdded (new_routes); /* EMIT SIGNAL */
1996 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1998 /* need to do this in case we're rolling at the time, to prevent false underruns */
1999 dstream->do_refill_with_alloc();
2002 RCUWriter<DiskstreamList> writer (diskstreams);
2003 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2004 ds->push_back (dstream);
2007 dstream->set_block_size (current_block_size);
2009 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2010 /* this will connect to future changes, and check the current length */
2011 diskstream_playlist_changed (dstream);
2013 dstream->prepare ();
2017 Session::remove_route (shared_ptr<Route> route)
2020 RCUWriter<RouteList> writer (routes);
2021 shared_ptr<RouteList> rs = writer.get_copy ();
2025 /* deleting the master out seems like a dumb
2026 idea, but its more of a UI policy issue
2030 if (route == _master_out) {
2031 _master_out = shared_ptr<Route> ();
2034 if (route == _control_out) {
2035 _control_out = shared_ptr<Route> ();
2037 /* cancel control outs for all routes */
2039 vector<string> empty;
2041 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2042 (*r)->set_control_outs (empty);
2046 update_route_solo_state ();
2048 /* writer goes out of scope, forces route list update */
2051 // FIXME: audio specific
2053 boost::shared_ptr<AudioDiskstream> ds;
2055 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2056 ds = at->audio_diskstream();
2062 RCUWriter<DiskstreamList> dsl (diskstreams);
2063 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2068 find_current_end ();
2070 update_latency_compensation (false, false);
2073 // We need to disconnect the routes inputs and outputs
2074 route->disconnect_inputs(NULL);
2075 route->disconnect_outputs(NULL);
2077 /* get rid of it from the dead wood collection in the route list manager */
2079 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2083 /* try to cause everyone to drop their references */
2085 route->drop_references ();
2087 /* save the new state of the world */
2089 if (save_state (_current_snapshot_name)) {
2090 save_history (_current_snapshot_name);
2095 Session::route_mute_changed (void* src)
2101 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2103 if (solo_update_disabled) {
2109 boost::shared_ptr<Route> route = wpr.lock ();
2112 /* should not happen */
2113 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2117 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2119 shared_ptr<RouteList> r = routes.reader ();
2121 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2127 /* don't mess with busses */
2129 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2135 /* don't mess with tracks */
2137 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2142 if ((*i) != route &&
2143 ((*i)->mix_group () == 0 ||
2144 (*i)->mix_group () != route->mix_group () ||
2145 !route->mix_group ()->is_active())) {
2147 if ((*i)->soloed()) {
2149 /* if its already soloed, and solo latching is enabled,
2150 then leave it as it is.
2153 if (Config->get_solo_latched()) {
2160 solo_update_disabled = true;
2161 (*i)->set_solo (false, src);
2162 solo_update_disabled = false;
2166 bool something_soloed = false;
2167 bool same_thing_soloed = false;
2168 bool signal = false;
2170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2171 if ((*i)->soloed()) {
2172 something_soloed = true;
2173 if (dynamic_cast<AudioTrack*>((*i).get())) {
2175 same_thing_soloed = true;
2180 same_thing_soloed = true;
2188 if (something_soloed != currently_soloing) {
2190 currently_soloing = something_soloed;
2193 modify_solo_mute (is_track, same_thing_soloed);
2196 SoloActive (currently_soloing); /* EMIT SIGNAL */
2199 SoloChanged (); /* EMIT SIGNAL */
2205 Session::update_route_solo_state ()
2208 bool is_track = false;
2209 bool signal = false;
2211 /* caller must hold RouteLock */
2213 /* this is where we actually implement solo by changing
2214 the solo mute setting of each track.
2217 shared_ptr<RouteList> r = routes.reader ();
2219 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2220 if ((*i)->soloed()) {
2222 if (dynamic_cast<AudioTrack*>((*i).get())) {
2229 if (mute != currently_soloing) {
2231 currently_soloing = mute;
2234 if (!is_track && !mute) {
2236 /* nothing is soloed */
2238 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2239 (*i)->set_solo_mute (false);
2249 modify_solo_mute (is_track, mute);
2252 SoloActive (currently_soloing);
2257 Session::modify_solo_mute (bool is_track, bool mute)
2259 shared_ptr<RouteList> r = routes.reader ();
2261 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2265 /* only alter track solo mute */
2267 if (dynamic_cast<AudioTrack*>((*i).get())) {
2268 if ((*i)->soloed()) {
2269 (*i)->set_solo_mute (!mute);
2271 (*i)->set_solo_mute (mute);
2277 /* only alter bus solo mute */
2279 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2281 if ((*i)->soloed()) {
2283 (*i)->set_solo_mute (false);
2287 /* don't mute master or control outs
2288 in response to another bus solo
2291 if ((*i) != _master_out &&
2292 (*i) != _control_out) {
2293 (*i)->set_solo_mute (mute);
2304 Session::catch_up_on_solo ()
2306 /* this is called after set_state() to catch the full solo
2307 state, which can't be correctly determined on a per-route
2308 basis, but needs the global overview that only the session
2311 update_route_solo_state();
2315 Session::route_by_name (string name)
2317 shared_ptr<RouteList> r = routes.reader ();
2319 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2320 if ((*i)->name() == name) {
2325 return shared_ptr<Route> ((Route*) 0);
2329 Session::route_by_id (PBD::ID id)
2331 shared_ptr<RouteList> r = routes.reader ();
2333 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2334 if ((*i)->id() == id) {
2339 return shared_ptr<Route> ((Route*) 0);
2343 Session::route_by_remote_id (uint32_t id)
2345 shared_ptr<RouteList> r = routes.reader ();
2347 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2348 if ((*i)->remote_control_id() == id) {
2353 return shared_ptr<Route> ((Route*) 0);
2357 Session::find_current_end ()
2359 if (_state_of_the_state & Loading) {
2363 nframes_t max = get_maximum_extent ();
2365 if (max > end_location->end()) {
2366 end_location->set_end (max);
2368 DurationChanged(); /* EMIT SIGNAL */
2373 Session::get_maximum_extent () const
2378 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2380 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2381 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2382 if ((me = pl->get_maximum_extent()) > max) {
2390 boost::shared_ptr<Diskstream>
2391 Session::diskstream_by_name (string name)
2393 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2395 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2396 if ((*i)->name() == name) {
2401 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2404 boost::shared_ptr<Diskstream>
2405 Session::diskstream_by_id (const PBD::ID& id)
2407 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2409 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2410 if ((*i)->id() == id) {
2415 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2418 /* AudioRegion management */
2421 Session::new_region_name (string old)
2423 string::size_type last_period;
2425 string::size_type len = old.length() + 64;
2428 if ((last_period = old.find_last_of ('.')) == string::npos) {
2430 /* no period present - add one explicitly */
2433 last_period = old.length() - 1;
2438 number = atoi (old.substr (last_period+1).c_str());
2442 while (number < (UINT_MAX-1)) {
2444 AudioRegionList::const_iterator i;
2449 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2452 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2453 if (i->second->name() == sbuf) {
2458 if (i == audio_regions.end()) {
2463 if (number != (UINT_MAX-1)) {
2467 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2472 Session::region_name (string& result, string base, bool newlevel) const
2479 Glib::Mutex::Lock lm (region_lock);
2481 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2489 /* XXX this is going to be slow. optimize me later */
2494 string::size_type pos;
2496 pos = base.find_last_of ('.');
2498 /* pos may be npos, but then we just use entire base */
2500 subbase = base.substr (0, pos);
2504 bool name_taken = true;
2507 Glib::Mutex::Lock lm (region_lock);
2509 for (int n = 1; n < 5000; ++n) {
2512 snprintf (buf, sizeof (buf), ".%d", n);
2517 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2518 if (i->second->name() == result) {
2531 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2539 Session::add_region (boost::shared_ptr<Region> region)
2541 boost::shared_ptr<AudioRegion> ar;
2542 boost::shared_ptr<AudioRegion> oar;
2546 Glib::Mutex::Lock lm (region_lock);
2548 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2550 AudioRegionList::iterator x;
2552 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2554 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2556 if (ar->region_list_equivalent (oar)) {
2561 if (x == audio_regions.end()) {
2563 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2565 entry.first = region->id();
2568 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2580 fatal << _("programming error: ")
2581 << X_("unknown region type passed to Session::add_region()")
2588 /* mark dirty because something has changed even if we didn't
2589 add the region to the region list.
2595 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2596 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2597 AudioRegionAdded (ar); /* EMIT SIGNAL */
2602 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2604 boost::shared_ptr<Region> region (weak_region.lock ());
2610 if (what_changed & Region::HiddenChanged) {
2611 /* relay hidden changes */
2612 RegionHiddenChange (region);
2617 Session::remove_region (boost::weak_ptr<Region> weak_region)
2619 AudioRegionList::iterator i;
2620 boost::shared_ptr<Region> region (weak_region.lock ());
2626 boost::shared_ptr<AudioRegion> ar;
2627 bool removed = false;
2630 Glib::Mutex::Lock lm (region_lock);
2632 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2633 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2634 audio_regions.erase (i);
2640 fatal << _("programming error: ")
2641 << X_("unknown region type passed to Session::remove_region()")
2647 /* mark dirty because something has changed even if we didn't
2648 remove the region from the region list.
2654 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2658 boost::shared_ptr<AudioRegion>
2659 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2661 AudioRegionList::iterator i;
2662 boost::shared_ptr<AudioRegion> region;
2663 Glib::Mutex::Lock lm (region_lock);
2665 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2669 if (region->whole_file()) {
2671 if (child->source_equivalent (region)) {
2677 return boost::shared_ptr<AudioRegion> ();
2681 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2683 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2684 (*i)->get_region_list_equivalent_regions (region, result);
2688 Session::destroy_region (boost::shared_ptr<Region> region)
2690 vector<boost::shared_ptr<Source> > srcs;
2693 boost::shared_ptr<AudioRegion> aregion;
2695 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2699 if (aregion->playlist()) {
2700 aregion->playlist()->destroy_region (region);
2703 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2704 srcs.push_back (aregion->source (n));
2708 region->drop_references ();
2710 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2712 if (!(*i)->used()) {
2713 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2716 (afs)->mark_for_remove ();
2719 (*i)->drop_references ();
2721 cerr << "source was not used by any playlist\n";
2729 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2731 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2732 destroy_region (*i);
2738 Session::remove_last_capture ()
2740 list<boost::shared_ptr<Region> > r;
2742 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2744 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2745 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2748 r.insert (r.end(), l.begin(), l.end());
2753 destroy_regions (r);
2758 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2764 /* Source Management */
2767 Session::add_source (boost::shared_ptr<Source> source)
2769 boost::shared_ptr<AudioFileSource> afs;
2771 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2773 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2774 pair<AudioSourceList::iterator,bool> result;
2776 entry.first = source->id();
2780 Glib::Mutex::Lock lm (audio_source_lock);
2781 result = audio_sources.insert (entry);
2784 if (result.second) {
2785 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2793 Session::remove_source (boost::weak_ptr<Source> src)
2795 AudioSourceList::iterator i;
2796 boost::shared_ptr<Source> source = src.lock();
2803 Glib::Mutex::Lock lm (audio_source_lock);
2805 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2806 audio_sources.erase (i);
2810 if (!_state_of_the_state & InCleanup) {
2812 /* save state so we don't end up with a session file
2813 referring to non-existent sources.
2816 save_state (_current_snapshot_name);
2820 boost::shared_ptr<Source>
2821 Session::source_by_id (const PBD::ID& id)
2823 Glib::Mutex::Lock lm (audio_source_lock);
2824 AudioSourceList::iterator i;
2825 boost::shared_ptr<Source> source;
2827 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2831 /* XXX search MIDI or other searches here */
2837 Session::peak_path_from_audio_path (string audio_path) const
2842 res += PBD::basename_nosuffix (audio_path);
2849 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2852 string old_basename = PBD::basename_nosuffix (oldname);
2853 string new_legalized = legalize_for_path (newname);
2855 /* note: we know (or assume) the old path is already valid */
2859 /* destructive file sources have a name of the form:
2861 /path/to/Tnnnn-NAME(%[LR])?.wav
2863 the task here is to replace NAME with the new name.
2866 /* find last slash */
2870 string::size_type slash;
2871 string::size_type dash;
2873 if ((slash = path.find_last_of ('/')) == string::npos) {
2877 dir = path.substr (0, slash+1);
2879 /* '-' is not a legal character for the NAME part of the path */
2881 if ((dash = path.find_last_of ('-')) == string::npos) {
2885 prefix = path.substr (slash+1, dash-(slash+1));
2890 path += new_legalized;
2891 path += ".wav"; /* XXX gag me with a spoon */
2895 /* non-destructive file sources have a name of the form:
2897 /path/to/NAME-nnnnn(%[LR])?.wav
2899 the task here is to replace NAME with the new name.
2904 string::size_type slash;
2905 string::size_type dash;
2906 string::size_type postfix;
2908 /* find last slash */
2910 if ((slash = path.find_last_of ('/')) == string::npos) {
2914 dir = path.substr (0, slash+1);
2916 /* '-' is not a legal character for the NAME part of the path */
2918 if ((dash = path.find_last_of ('-')) == string::npos) {
2922 suffix = path.substr (dash+1);
2924 // Suffix is now everything after the dash. Now we need to eliminate
2925 // the nnnnn part, which is done by either finding a '%' or a '.'
2927 postfix = suffix.find_last_of ("%");
2928 if (postfix == string::npos) {
2929 postfix = suffix.find_last_of ('.');
2932 if (postfix != string::npos) {
2933 suffix = suffix.substr (postfix);
2935 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2939 const uint32_t limit = 10000;
2940 char buf[PATH_MAX+1];
2942 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2944 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2946 if (access (buf, F_OK) != 0) {
2954 error << "FATAL ERROR! Could not find a " << endl;
2963 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2967 char buf[PATH_MAX+1];
2968 const uint32_t limit = 10000;
2972 legalized = legalize_for_path (name);
2974 /* find a "version" of the file name that doesn't exist in
2975 any of the possible directories.
2978 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2980 vector<space_and_path>::iterator i;
2981 uint32_t existing = 0;
2983 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2987 spath += sound_dir (false);
2991 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2992 } else if (nchan == 2) {
2994 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2996 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2998 } else if (nchan < 26) {
2999 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3001 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3010 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3011 } else if (nchan == 2) {
3013 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3015 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3017 } else if (nchan < 26) {
3018 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3020 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3024 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3030 if (existing == 0) {
3035 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3037 throw failed_constructor();
3041 /* we now have a unique name for the file, but figure out where to
3047 spath = discover_best_sound_dir ();
3050 string::size_type pos = foo.find_last_of ('/');
3052 if (pos == string::npos) {
3055 spath += foo.substr (pos + 1);
3061 boost::shared_ptr<AudioFileSource>
3062 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3064 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3065 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3068 /* Playlist management */
3070 boost::shared_ptr<Playlist>
3071 Session::playlist_by_name (string name)
3073 Glib::Mutex::Lock lm (playlist_lock);
3074 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3075 if ((*i)->name() == name) {
3079 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3080 if ((*i)->name() == name) {
3085 return boost::shared_ptr<Playlist>();
3089 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3091 if (playlist->hidden()) {
3096 Glib::Mutex::Lock lm (playlist_lock);
3097 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3098 playlists.insert (playlists.begin(), playlist);
3099 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3100 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3106 PlaylistAdded (playlist); /* EMIT SIGNAL */
3110 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3113 Glib::Mutex::Lock lm (playlist_lock);
3114 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3117 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3124 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3126 boost::shared_ptr<Playlist> pl(wpl.lock());
3132 PlaylistList::iterator x;
3135 /* its not supposed to be visible */
3140 Glib::Mutex::Lock lm (playlist_lock);
3144 unused_playlists.insert (pl);
3146 if ((x = playlists.find (pl)) != playlists.end()) {
3147 playlists.erase (x);
3153 playlists.insert (pl);
3155 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3156 unused_playlists.erase (x);
3163 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3165 if (_state_of_the_state & Deletion) {
3169 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3176 Glib::Mutex::Lock lm (playlist_lock);
3178 PlaylistList::iterator i;
3180 i = find (playlists.begin(), playlists.end(), playlist);
3181 if (i != playlists.end()) {
3182 playlists.erase (i);
3185 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3186 if (i != unused_playlists.end()) {
3187 unused_playlists.erase (i);
3194 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3198 Session::set_audition (boost::shared_ptr<Region> r)
3200 pending_audition_region = r;
3201 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3202 schedule_butler_transport_work ();
3206 Session::audition_playlist ()
3208 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3209 ev->region.reset ();
3214 Session::non_realtime_set_audition ()
3216 if (!pending_audition_region) {
3217 auditioner->audition_current_playlist ();
3219 auditioner->audition_region (pending_audition_region);
3220 pending_audition_region.reset ();
3222 AuditionActive (true); /* EMIT SIGNAL */
3226 Session::audition_region (boost::shared_ptr<Region> r)
3228 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3234 Session::cancel_audition ()
3236 if (auditioner->active()) {
3237 auditioner->cancel_audition ();
3238 AuditionActive (false); /* EMIT SIGNAL */
3243 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3245 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3249 Session::remove_empty_sounds ()
3251 PathScanner scanner;
3253 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3255 Glib::Mutex::Lock lm (audio_source_lock);
3257 regex_t compiled_tape_track_pattern;
3260 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3264 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3266 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3270 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3272 /* never remove files that appear to be a tape track */
3274 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3279 if (AudioFileSource::is_empty (*this, *(*i))) {
3281 unlink ((*i)->c_str());
3283 string peak_path = peak_path_from_audio_path (**i);
3284 unlink (peak_path.c_str());
3290 delete possible_audiofiles;
3294 Session::is_auditioning () const
3296 /* can be called before we have an auditioner object */
3298 return auditioner->active();
3305 Session::set_all_solo (bool yn)
3307 shared_ptr<RouteList> r = routes.reader ();
3309 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3310 if (!(*i)->hidden()) {
3311 (*i)->set_solo (yn, this);
3319 Session::set_all_mute (bool yn)
3321 shared_ptr<RouteList> r = routes.reader ();
3323 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3324 if (!(*i)->hidden()) {
3325 (*i)->set_mute (yn, this);
3333 Session::n_diskstreams () const
3337 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3339 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3340 if (!(*i)->hidden()) {
3348 Session::graph_reordered ()
3350 /* don't do this stuff if we are setting up connections
3351 from a set_state() call or creating new tracks.
3354 if (_state_of_the_state & InitialConnecting) {
3358 /* every track/bus asked for this to be handled but it was deferred because
3359 we were connecting. do it now.
3362 request_input_change_handling ();
3366 /* force all diskstreams to update their capture offset values to
3367 reflect any changes in latencies within the graph.
3370 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3372 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3373 (*i)->set_capture_offset ();
3378 Session::record_disenable_all ()
3380 record_enable_change_all (false);
3384 Session::record_enable_all ()
3386 record_enable_change_all (true);
3390 Session::record_enable_change_all (bool yn)
3392 shared_ptr<RouteList> r = routes.reader ();
3394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3397 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3398 at->set_record_enable (yn, this);
3402 /* since we don't keep rec-enable state, don't mark session dirty */
3406 Session::add_redirect (Redirect* redirect)
3410 PortInsert* port_insert;
3411 PluginInsert* plugin_insert;
3413 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3414 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3415 _port_inserts.insert (_port_inserts.begin(), port_insert);
3416 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3417 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3419 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3422 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3423 _sends.insert (_sends.begin(), send);
3425 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3429 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3435 Session::remove_redirect (Redirect* redirect)
3439 PortInsert* port_insert;
3440 PluginInsert* plugin_insert;
3442 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3443 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3444 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3445 if (x != _port_inserts.end()) {
3446 insert_bitset[port_insert->bit_slot()] = false;
3447 _port_inserts.erase (x);
3449 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3450 _plugin_inserts.remove (plugin_insert);
3452 fatal << string_compose (_("programming error: %1"),
3453 X_("unknown type of Insert deleted!"))
3457 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3458 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3459 if (x != _sends.end()) {
3460 send_bitset[send->bit_slot()] = false;
3464 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3472 Session::available_capture_duration ()
3474 float sample_bytes_on_disk = 4.0; // keep gcc happy
3476 switch (Config->get_native_file_data_format()) {
3478 sample_bytes_on_disk = 4.0;
3482 sample_bytes_on_disk = 3.0;
3486 /* impossible, but keep some gcc versions happy */
3487 fatal << string_compose (_("programming error: %1"),
3488 X_("illegal native file data format"))
3493 double scale = 4096.0 / sample_bytes_on_disk;
3495 if (_total_free_4k_blocks * scale > (double) max_frames) {
3499 return (nframes_t) floor (_total_free_4k_blocks * scale);
3503 Session::add_connection (ARDOUR::Connection* connection)
3506 Glib::Mutex::Lock guard (connection_lock);
3507 _connections.push_back (connection);
3510 ConnectionAdded (connection); /* EMIT SIGNAL */
3516 Session::remove_connection (ARDOUR::Connection* connection)
3518 bool removed = false;
3521 Glib::Mutex::Lock guard (connection_lock);
3522 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3524 if (i != _connections.end()) {
3525 _connections.erase (i);
3531 ConnectionRemoved (connection); /* EMIT SIGNAL */
3537 ARDOUR::Connection *
3538 Session::connection_by_name (string name) const
3540 Glib::Mutex::Lock lm (connection_lock);
3542 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3543 if ((*i)->name() == name) {
3552 Session::tempo_map_changed (Change ignored)
3559 Session::ensure_passthru_buffers (uint32_t howmany)
3561 while (howmany > _passthru_buffers.size()) {
3563 #ifdef NO_POSIX_MEMALIGN
3564 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3566 posix_memalign((void **)&p,16,current_block_size * 4);
3568 _passthru_buffers.push_back (p);
3572 #ifdef NO_POSIX_MEMALIGN
3573 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3575 posix_memalign((void **)&p,16,current_block_size * 4);
3577 memset (p, 0, sizeof (Sample) * current_block_size);
3578 _silent_buffers.push_back (p);
3582 #ifdef NO_POSIX_MEMALIGN
3583 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3585 posix_memalign((void **)&p,16,current_block_size * 4);
3587 memset (p, 0, sizeof (Sample) * current_block_size);
3588 _send_buffers.push_back (p);
3591 allocate_pan_automation_buffers (current_block_size, howmany, false);
3595 Session::next_insert_id ()
3597 /* this doesn't really loop forever. just think about it */
3600 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3601 if (!insert_bitset[n]) {
3602 insert_bitset[n] = true;
3603 cerr << "Returning " << n << " as insert ID\n";
3609 /* none available, so resize and try again */
3611 insert_bitset.resize (insert_bitset.size() + 16, false);
3616 Session::next_send_id ()
3618 /* this doesn't really loop forever. just think about it */
3621 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3622 if (!send_bitset[n]) {
3623 send_bitset[n] = true;
3624 cerr << "Returning " << n << " as send ID\n";
3630 /* none available, so resize and try again */
3632 send_bitset.resize (send_bitset.size() + 16, false);
3637 Session::mark_send_id (uint32_t id)
3639 if (id >= send_bitset.size()) {
3640 send_bitset.resize (id+16, false);
3642 if (send_bitset[id]) {
3643 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3645 send_bitset[id] = true;
3649 Session::mark_insert_id (uint32_t id)
3651 if (id >= insert_bitset.size()) {
3652 insert_bitset.resize (id+16, false);
3654 if (insert_bitset[id]) {
3655 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3657 insert_bitset[id] = true;
3660 /* Named Selection management */
3663 Session::named_selection_by_name (string name)
3665 Glib::Mutex::Lock lm (named_selection_lock);
3666 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3667 if ((*i)->name == name) {
3675 Session::add_named_selection (NamedSelection* named_selection)
3678 Glib::Mutex::Lock lm (named_selection_lock);
3679 named_selections.insert (named_selections.begin(), named_selection);
3682 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3688 NamedSelectionAdded (); /* EMIT SIGNAL */
3692 Session::remove_named_selection (NamedSelection* named_selection)
3694 bool removed = false;
3697 Glib::Mutex::Lock lm (named_selection_lock);
3699 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3701 if (i != named_selections.end()) {
3703 named_selections.erase (i);
3710 NamedSelectionRemoved (); /* EMIT SIGNAL */
3715 Session::reset_native_file_format ()
3717 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3719 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3720 (*i)->reset_write_sources (false);
3725 Session::route_name_unique (string n) const
3727 shared_ptr<RouteList> r = routes.reader ();
3729 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3730 if ((*i)->name() == n) {
3739 Session::n_playlists () const
3741 Glib::Mutex::Lock lm (playlist_lock);
3742 return playlists.size();
3746 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3748 if (!force && howmany <= _npan_buffers) {
3752 if (_pan_automation_buffer) {
3754 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3755 delete [] _pan_automation_buffer[i];
3758 delete [] _pan_automation_buffer;
3761 _pan_automation_buffer = new pan_t*[howmany];
3763 for (uint32_t i = 0; i < howmany; ++i) {
3764 _pan_automation_buffer[i] = new pan_t[nframes];
3767 _npan_buffers = howmany;
3771 Session::freeze (InterThreadInfo& itt)
3773 shared_ptr<RouteList> r = routes.reader ();
3775 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3779 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3780 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3791 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3792 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3795 boost::shared_ptr<Playlist> playlist;
3796 boost::shared_ptr<AudioFileSource> fsource;
3798 char buf[PATH_MAX+1];
3802 nframes_t this_chunk;
3804 vector<Sample*> buffers;
3806 // any bigger than this seems to cause stack overflows in called functions
3807 const nframes_t chunk_size = (128 * 1024)/4;
3809 g_atomic_int_set (&processing_prohibited, 1);
3811 /* call tree *MUST* hold route_lock */
3813 if ((playlist = track.diskstream()->playlist()) == 0) {
3817 /* external redirects will be a problem */
3819 if (track.has_external_redirects()) {
3823 nchans = track.audio_diskstream()->n_channels();
3825 dir = discover_best_sound_dir ();
3827 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3829 for (x = 0; x < 99999; ++x) {
3830 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3831 if (access (buf, F_OK) != 0) {
3837 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3842 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3845 catch (failed_constructor& err) {
3846 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3850 srcs.push_back (fsource);
3853 /* XXX need to flush all redirects */
3858 /* create a set of reasonably-sized buffers */
3860 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3862 #ifdef NO_POSIX_MEMALIGN
3863 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3865 posix_memalign((void **)&b,16,chunk_size * 4);
3867 buffers.push_back (b);
3870 while (to_do && !itt.cancel) {
3872 this_chunk = min (to_do, chunk_size);
3874 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3879 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3880 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3883 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3889 start += this_chunk;
3890 to_do -= this_chunk;
3892 itt.progress = (float) (1.0 - ((double) to_do / len));
3901 xnow = localtime (&now);
3903 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3904 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3907 afs->update_header (position, *xnow, now);
3908 afs->flush_header ();
3912 /* build peakfile for new source */
3914 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3915 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3917 afs->build_peaks ();
3921 /* construct a region to represent the bounced material */
3923 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3924 region_name_from_path (srcs.front()->name(), true));
3931 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3932 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3935 afs->mark_for_remove ();
3938 (*src)->drop_references ();
3942 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3946 g_atomic_int_set (&processing_prohibited, 0);
3954 Session::get_silent_buffers (uint32_t howmany)
3956 for (uint32_t i = 0; i < howmany; ++i) {
3957 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3959 return _silent_buffers;
3963 Session::ntracks () const
3966 shared_ptr<RouteList> r = routes.reader ();
3968 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3969 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3978 Session::nbusses () const
3981 shared_ptr<RouteList> r = routes.reader ();
3983 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3984 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3993 Session::add_automation_list(AutomationList *al)
3995 automation_lists[al->id()] = al;
3999 Session::compute_initial_length ()
4001 return _engine.frame_rate() * 60 * 5;