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::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
93 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
94 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
96 sigc::signal<int> Session::AskAboutPendingState;
97 sigc::signal<void> Session::SendFeedback;
99 sigc::signal<void> Session::SMPTEOffsetChanged;
100 sigc::signal<void> Session::StartTimeChanged;
101 sigc::signal<void> Session::EndTimeChanged;
104 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
107 char buf[PATH_MAX+1];
111 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
112 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
118 /* check to see if it exists, and what it is */
120 if (stat (str.c_str(), &statbuf)) {
121 if (errno == ENOENT) {
124 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
132 /* it exists, so it must either be the name
133 of the directory, or the name of the statefile
137 if (S_ISDIR (statbuf.st_mode)) {
139 string::size_type slash = str.find_last_of ('/');
141 if (slash == string::npos) {
143 /* a subdirectory of cwd, so statefile should be ... */
149 tmp += _statefile_suffix;
153 if (stat (tmp.c_str(), &statbuf)) {
154 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
164 /* some directory someplace in the filesystem.
165 the snapshot name is the directory name
170 snapshot = str.substr (slash+1);
174 } else if (S_ISREG (statbuf.st_mode)) {
176 string::size_type slash = str.find_last_of ('/');
177 string::size_type suffix;
179 /* remove the suffix */
181 if (slash != string::npos) {
182 snapshot = str.substr (slash+1);
187 suffix = snapshot.find (_statefile_suffix);
189 if (suffix == string::npos) {
190 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
196 snapshot = snapshot.substr (0, suffix);
198 if (slash == string::npos) {
200 /* we must be in the directory where the
201 statefile lives. get it using cwd().
204 char cwd[PATH_MAX+1];
206 if (getcwd (cwd, sizeof (cwd)) == 0) {
207 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
216 /* full path to the statefile */
218 path = str.substr (0, slash);
223 /* what type of file is it? */
224 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
230 /* its the name of a new directory. get the name
234 string::size_type slash = str.find_last_of ('/');
236 if (slash == string::npos) {
238 /* no slash, just use the name, but clean it up */
240 path = legalize_for_path (str);
246 snapshot = str.substr (slash+1);
253 Session::Session (AudioEngine &eng,
255 string snapshot_name,
256 string* mix_template)
259 _mmc_port (default_mmc_port),
260 _mtc_port (default_mtc_port),
261 _midi_port (default_midi_port),
262 pending_events (2048),
263 midi_requests (128), // the size of this should match the midi request pool size
264 diskstreams (new DiskstreamList),
265 routes (new RouteList),
266 auditioner ((Auditioner*) 0),
272 if (!eng.connected()) {
273 throw failed_constructor();
276 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
278 n_physical_outputs = _engine.n_physical_outputs();
279 n_physical_inputs = _engine.n_physical_inputs();
281 first_stage_init (fullpath, snapshot_name);
283 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
285 if (create (new_session, mix_template, compute_initial_length())) {
286 cerr << "create failed\n";
288 throw failed_constructor ();
292 if (second_stage_init (new_session)) {
294 throw failed_constructor ();
297 store_recent_sessions(_name, _path);
299 bool was_dirty = dirty();
301 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
303 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
306 DirtyChanged (); /* EMIT SIGNAL */
310 Session::Session (AudioEngine &eng,
312 string snapshot_name,
313 AutoConnectOption input_ac,
314 AutoConnectOption output_ac,
315 uint32_t control_out_channels,
316 uint32_t master_out_channels,
317 uint32_t requested_physical_in,
318 uint32_t requested_physical_out,
319 nframes_t initial_length)
322 _mmc_port (default_mmc_port),
323 _mtc_port (default_mtc_port),
324 _midi_port (default_midi_port),
325 pending_events (2048),
327 diskstreams (new DiskstreamList),
328 routes (new RouteList),
334 if (!eng.connected()) {
335 throw failed_constructor();
338 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
340 n_physical_outputs = _engine.n_physical_outputs();
341 n_physical_inputs = _engine.n_physical_inputs();
343 if (n_physical_inputs) {
344 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
347 if (n_physical_outputs) {
348 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
351 first_stage_init (fullpath, snapshot_name);
353 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
356 if (create (new_session, 0, initial_length)) {
358 throw failed_constructor ();
363 /* set up Master Out and Control Out if necessary */
368 if (control_out_channels) {
369 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
370 r->set_remote_control_id (control_id++);
375 if (master_out_channels) {
376 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
377 r->set_remote_control_id (control_id);
381 /* prohibit auto-connect to master, because there isn't one */
382 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
391 Config->set_input_auto_connect (input_ac);
392 Config->set_output_auto_connect (output_ac);
394 if (second_stage_init (new_session)) {
396 throw failed_constructor ();
399 store_recent_sessions(_name, _path);
401 bool was_dirty = dirty ();
403 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
405 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
408 DirtyChanged (); /* EMIT SIGNAL */
420 /* if we got to here, leaving pending capture state around
424 remove_pending_capture_state ();
426 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
427 _engine.remove_session ();
429 GoingAway (); /* EMIT SIGNAL */
435 /* clear history so that no references to objects are held any more */
439 /* clear state tree so that no references to objects are held any more */
445 terminate_butler_thread ();
446 terminate_midi_thread ();
448 if (click_data && click_data != default_click) {
449 delete [] click_data;
452 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
453 delete [] click_emphasis_data;
458 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
462 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
466 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
470 AudioDiskstream::free_working_buffers();
472 /* this should cause deletion of the auditioner */
474 // auditioner.reset ();
476 #undef TRACK_DESTRUCTION
477 #ifdef TRACK_DESTRUCTION
478 cerr << "delete named selections\n";
479 #endif /* TRACK_DESTRUCTION */
480 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
481 NamedSelectionList::iterator tmp;
490 #ifdef TRACK_DESTRUCTION
491 cerr << "delete playlists\n";
492 #endif /* TRACK_DESTRUCTION */
493 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
494 PlaylistList::iterator tmp;
499 (*i)->drop_references ();
504 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
505 PlaylistList::iterator tmp;
510 (*i)->drop_references ();
516 unused_playlists.clear ();
518 #ifdef TRACK_DESTRUCTION
519 cerr << "delete audio regions\n";
520 #endif /* TRACK_DESTRUCTION */
522 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
523 AudioRegionList::iterator tmp;
528 i->second->drop_references ();
533 audio_regions.clear ();
535 #ifdef TRACK_DESTRUCTION
536 cerr << "delete routes\n";
537 #endif /* TRACK_DESTRUCTION */
539 RCUWriter<RouteList> writer (routes);
540 boost::shared_ptr<RouteList> r = writer.get_copy ();
541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
542 (*i)->drop_references ();
545 /* writer goes out of scope and updates master */
550 #ifdef TRACK_DESTRUCTION
551 cerr << "delete diskstreams\n";
552 #endif /* TRACK_DESTRUCTION */
554 RCUWriter<DiskstreamList> dwriter (diskstreams);
555 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
556 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
557 (*i)->drop_references ();
561 diskstreams.flush ();
563 #ifdef TRACK_DESTRUCTION
564 cerr << "delete audio sources\n";
565 #endif /* TRACK_DESTRUCTION */
566 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
567 AudioSourceList::iterator tmp;
572 i->second->drop_references ();
577 audio_sources.clear ();
579 #ifdef TRACK_DESTRUCTION
580 cerr << "delete mix groups\n";
581 #endif /* TRACK_DESTRUCTION */
582 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
583 list<RouteGroup*>::iterator tmp;
593 #ifdef TRACK_DESTRUCTION
594 cerr << "delete edit groups\n";
595 #endif /* TRACK_DESTRUCTION */
596 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
597 list<RouteGroup*>::iterator tmp;
607 #ifdef TRACK_DESTRUCTION
608 cerr << "delete connections\n";
609 #endif /* TRACK_DESTRUCTION */
610 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
611 ConnectionList::iterator tmp;
621 if (butler_mixdown_buffer) {
622 delete [] butler_mixdown_buffer;
625 if (butler_gain_buffer) {
626 delete [] butler_gain_buffer;
629 Crossfade::set_buffer_size (0);
637 Session::set_worst_io_latencies ()
639 _worst_output_latency = 0;
640 _worst_input_latency = 0;
642 if (!_engine.connected()) {
646 boost::shared_ptr<RouteList> r = routes.reader ();
648 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
649 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
650 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
655 Session::when_engine_running ()
657 string first_physical_output;
659 /* we don't want to run execute this again */
661 set_block_size (_engine.frames_per_cycle());
662 set_frame_rate (_engine.frame_rate());
664 Config->map_parameters (mem_fun (*this, &Session::config_changed));
666 /* every time we reconnect, recompute worst case output latencies */
668 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
670 if (synced_to_jack()) {
671 _engine.transport_stop ();
674 if (Config->get_jack_time_master()) {
675 _engine.transport_locate (_transport_frame);
683 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
685 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
687 /* existing state for Click */
689 if (_click_io->set_state (*child->children().front()) == 0) {
691 _clicking = Config->get_clicking ();
695 error << _("could not setup Click I/O") << endmsg;
701 /* default state for Click */
703 first_physical_output = _engine.get_nth_physical_output (0);
705 if (first_physical_output.length()) {
706 if (_click_io->add_output_port (first_physical_output, this)) {
707 // relax, even though its an error
709 _clicking = Config->get_clicking ();
715 catch (failed_constructor& err) {
716 error << _("cannot setup Click I/O") << endmsg;
719 set_worst_io_latencies ();
722 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
725 /* Create a set of Connection objects that map
726 to the physical outputs currently available
731 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
733 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
735 Connection* c = new OutputConnection (buf, true);
738 c->add_connection (0, _engine.get_nth_physical_output (np));
743 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
745 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
747 Connection* c = new InputConnection (buf, true);
750 c->add_connection (0, _engine.get_nth_physical_input (np));
757 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
759 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
761 Connection* c = new OutputConnection (buf, true);
765 c->add_connection (0, _engine.get_nth_physical_output (np));
766 c->add_connection (1, _engine.get_nth_physical_output (np+1));
771 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
773 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
775 Connection* c = new InputConnection (buf, true);
779 c->add_connection (0, _engine.get_nth_physical_input (np));
780 c->add_connection (1, _engine.get_nth_physical_input (np+1));
789 /* create master/control ports */
794 /* force the master to ignore any later call to this */
796 if (_master_out->pending_state_node) {
797 _master_out->ports_became_legal();
800 /* no panner resets till we are through */
802 _master_out->defer_pan_reset ();
804 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
805 if (_master_out->add_input_port ("", this)) {
806 error << _("cannot setup master inputs")
812 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
813 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
814 error << _("cannot setup master outputs")
821 _master_out->allow_pan_reset ();
825 Connection* c = new OutputConnection (_("Master Out"), true);
827 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
829 c->add_connection ((int) n, _master_out->input(n)->name());
836 /* catch up on send+insert cnts */
840 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
843 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
844 if (id > insert_cnt) {
852 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
855 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
863 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
865 /* hook us up to the engine */
867 _engine.set_session (this);
872 osc->set_session (*this);
875 _state_of_the_state = Clean;
877 DirtyChanged (); /* EMIT SIGNAL */
881 Session::hookup_io ()
883 /* stop graph reordering notifications from
884 causing resorts, etc.
887 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
889 if (auditioner == 0) {
891 /* we delay creating the auditioner till now because
892 it makes its own connections to ports.
893 the engine has to be running for this to work.
897 auditioner.reset (new Auditioner (*this));
900 catch (failed_constructor& err) {
901 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
905 /* Tell all IO objects to create their ports */
912 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
913 if (_control_out->add_input_port ("", this)) {
914 error << _("cannot setup control inputs")
920 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
921 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
922 error << _("cannot set up master outputs")
930 /* Tell all IO objects to connect themselves together */
932 IO::enable_connecting ();
934 /* Now reset all panners */
936 IO::reset_panners ();
938 /* Anyone who cares about input state, wake up and do something */
940 IOConnectionsComplete (); /* EMIT SIGNAL */
942 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
944 /* now handle the whole enchilada as if it was one
950 /* update mixer solo state */
956 Session::playlist_length_changed ()
958 /* we can't just increase end_location->end() if pl->get_maximum_extent()
959 if larger. if the playlist used to be the longest playlist,
960 and its now shorter, we have to decrease end_location->end(). hence,
961 we have to iterate over all diskstreams and check the
962 playlists currently in use.
968 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
970 boost::shared_ptr<Playlist> playlist;
972 if ((playlist = dstream->playlist()) != 0) {
973 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
976 /* see comment in playlist_length_changed () */
981 Session::record_enabling_legal () const
983 /* this used to be in here, but survey says.... we don't need to restrict it */
984 // if (record_status() == Recording) {
988 if (Config->get_all_safe()) {
995 Session::reset_input_monitor_state ()
997 if (transport_rolling()) {
999 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1001 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1002 if ((*i)->record_enabled ()) {
1003 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1004 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1008 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1010 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1011 if ((*i)->record_enabled ()) {
1012 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1013 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1020 Session::auto_punch_start_changed (Location* location)
1022 replace_event (Event::PunchIn, location->start());
1024 if (get_record_enabled() && Config->get_punch_in()) {
1025 /* capture start has been changed, so save new pending state */
1026 save_state ("", true);
1031 Session::auto_punch_end_changed (Location* location)
1033 nframes_t when_to_stop = location->end();
1034 // when_to_stop += _worst_output_latency + _worst_input_latency;
1035 replace_event (Event::PunchOut, when_to_stop);
1039 Session::auto_punch_changed (Location* location)
1041 nframes_t when_to_stop = location->end();
1043 replace_event (Event::PunchIn, location->start());
1044 //when_to_stop += _worst_output_latency + _worst_input_latency;
1045 replace_event (Event::PunchOut, when_to_stop);
1049 Session::auto_loop_changed (Location* location)
1051 replace_event (Event::AutoLoop, location->end(), location->start());
1053 if (transport_rolling() && play_loop) {
1055 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1057 if (_transport_frame > location->end()) {
1058 // relocate to beginning of loop
1059 clear_events (Event::LocateRoll);
1061 request_locate (location->start(), true);
1064 else if (Config->get_seamless_loop() && !loop_changing) {
1066 // schedule a locate-roll to refill the diskstreams at the
1067 // previous loop end
1068 loop_changing = true;
1070 if (location->end() > last_loopend) {
1071 clear_events (Event::LocateRoll);
1072 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1079 last_loopend = location->end();
1084 Session::set_auto_punch_location (Location* location)
1088 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1089 auto_punch_start_changed_connection.disconnect();
1090 auto_punch_end_changed_connection.disconnect();
1091 auto_punch_changed_connection.disconnect();
1092 existing->set_auto_punch (false, this);
1093 remove_event (existing->start(), Event::PunchIn);
1094 clear_events (Event::PunchOut);
1095 auto_punch_location_changed (0);
1100 if (location == 0) {
1104 if (location->end() <= location->start()) {
1105 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1109 auto_punch_start_changed_connection.disconnect();
1110 auto_punch_end_changed_connection.disconnect();
1111 auto_punch_changed_connection.disconnect();
1113 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1114 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1115 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1117 location->set_auto_punch (true, this);
1118 auto_punch_location_changed (location);
1122 Session::set_auto_loop_location (Location* location)
1126 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1127 auto_loop_start_changed_connection.disconnect();
1128 auto_loop_end_changed_connection.disconnect();
1129 auto_loop_changed_connection.disconnect();
1130 existing->set_auto_loop (false, this);
1131 remove_event (existing->end(), Event::AutoLoop);
1132 auto_loop_location_changed (0);
1137 if (location == 0) {
1141 if (location->end() <= location->start()) {
1142 error << _("Session: you can't use a mark for auto loop") << endmsg;
1146 last_loopend = location->end();
1148 auto_loop_start_changed_connection.disconnect();
1149 auto_loop_end_changed_connection.disconnect();
1150 auto_loop_changed_connection.disconnect();
1152 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1153 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1154 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1156 location->set_auto_loop (true, this);
1157 auto_loop_location_changed (location);
1161 Session::locations_added (Location* ignored)
1167 Session::locations_changed ()
1169 _locations.apply (*this, &Session::handle_locations_changed);
1173 Session::handle_locations_changed (Locations::LocationList& locations)
1175 Locations::LocationList::iterator i;
1177 bool set_loop = false;
1178 bool set_punch = false;
1180 for (i = locations.begin(); i != locations.end(); ++i) {
1184 if (location->is_auto_punch()) {
1185 set_auto_punch_location (location);
1188 if (location->is_auto_loop()) {
1189 set_auto_loop_location (location);
1196 set_auto_loop_location (0);
1199 set_auto_punch_location (0);
1206 Session::enable_record ()
1208 /* XXX really atomic compare+swap here */
1209 if (g_atomic_int_get (&_record_status) != Recording) {
1210 g_atomic_int_set (&_record_status, Recording);
1211 _last_record_location = _transport_frame;
1212 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1214 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1215 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1216 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1217 if ((*i)->record_enabled ()) {
1218 (*i)->monitor_input (true);
1223 RecordStateChanged ();
1228 Session::disable_record (bool rt_context, bool force)
1232 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1234 if (!Config->get_latched_record_enable () || force) {
1235 g_atomic_int_set (&_record_status, Disabled);
1237 if (rs == Recording) {
1238 g_atomic_int_set (&_record_status, Enabled);
1242 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1244 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1245 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1247 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1248 if ((*i)->record_enabled ()) {
1249 (*i)->monitor_input (false);
1254 RecordStateChanged (); /* emit signal */
1257 remove_pending_capture_state ();
1263 Session::step_back_from_record ()
1265 g_atomic_int_set (&_record_status, Enabled);
1267 if (Config->get_monitoring_model() == HardwareMonitoring) {
1268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1271 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1272 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1273 (*i)->monitor_input (false);
1280 Session::maybe_enable_record ()
1282 g_atomic_int_set (&_record_status, Enabled);
1284 /* this function is currently called from somewhere other than an RT thread.
1285 this save_state() call therefore doesn't impact anything.
1288 save_state ("", true);
1290 if (_transport_speed) {
1291 if (!Config->get_punch_in()) {
1295 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1296 RecordStateChanged (); /* EMIT SIGNAL */
1303 Session::audible_frame () const
1309 /* the first of these two possible settings for "offset"
1310 mean that the audible frame is stationary until
1311 audio emerges from the latency compensation
1314 the second means that the audible frame is stationary
1315 until audio would emerge from a physical port
1316 in the absence of any plugin latency compensation
1319 offset = _worst_output_latency;
1321 if (offset > current_block_size) {
1322 offset -= current_block_size;
1324 /* XXX is this correct? if we have no external
1325 physical connections and everything is internal
1326 then surely this is zero? still, how
1327 likely is that anyway?
1329 offset = current_block_size;
1332 if (synced_to_jack()) {
1333 tf = _engine.transport_frame();
1335 tf = _transport_frame;
1338 if (_transport_speed == 0) {
1348 if (!non_realtime_work_pending()) {
1352 /* take latency into account */
1361 Session::set_frame_rate (nframes_t frames_per_second)
1363 /** \fn void Session::set_frame_size(nframes_t)
1364 the AudioEngine object that calls this guarantees
1365 that it will not be called while we are also in
1366 ::process(). Its fine to do things that block
1370 _base_frame_rate = frames_per_second;
1374 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1376 // XXX we need some equivalent to this, somehow
1377 // SndFileSource::setup_standard_crossfades (frames_per_second);
1381 /* XXX need to reset/reinstantiate all LADSPA plugins */
1385 Session::set_block_size (nframes_t nframes)
1387 /* the AudioEngine guarantees
1388 that it will not be called while we are also in
1389 ::process(). It is therefore fine to do things that block
1394 vector<Sample*>::iterator i;
1397 current_block_size = nframes;
1399 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1403 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1407 _passthru_buffers.clear ();
1408 _silent_buffers.clear ();
1410 ensure_passthru_buffers (np);
1412 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1416 #ifdef NO_POSIX_MEMALIGN
1417 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1419 posix_memalign((void **)&buf,16,current_block_size * 4);
1423 memset (*i, 0, sizeof (Sample) * current_block_size);
1427 if (_gain_automation_buffer) {
1428 delete [] _gain_automation_buffer;
1430 _gain_automation_buffer = new gain_t[nframes];
1432 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1434 boost::shared_ptr<RouteList> r = routes.reader ();
1436 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1437 (*i)->set_block_size (nframes);
1440 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1441 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1442 (*i)->set_block_size (nframes);
1445 set_worst_io_latencies ();
1450 Session::set_default_fade (float steepness, float fade_msecs)
1453 nframes_t fade_frames;
1455 /* Don't allow fade of less 1 frame */
1457 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1464 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1468 default_fade_msecs = fade_msecs;
1469 default_fade_steepness = steepness;
1472 // jlc, WTF is this!
1473 Glib::RWLock::ReaderLock lm (route_lock);
1474 AudioRegion::set_default_fade (steepness, fade_frames);
1479 /* XXX have to do this at some point */
1480 /* foreach region using default fade, reset, then
1481 refill_all_diskstream_buffers ();
1486 struct RouteSorter {
1487 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1488 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1490 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1493 if (r1->fed_by.empty()) {
1494 if (r2->fed_by.empty()) {
1495 /* no ardour-based connections inbound to either route. just use signal order */
1496 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1498 /* r2 has connections, r1 does not; run r1 early */
1502 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1509 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1511 shared_ptr<Route> r2;
1513 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1514 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1518 /* make a copy of the existing list of routes that feed r1 */
1520 set<shared_ptr<Route> > existing = r1->fed_by;
1522 /* for each route that feeds r1, recurse, marking it as feeding
1526 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1529 /* r2 is a route that feeds r1 which somehow feeds base. mark
1530 base as being fed by r2
1533 rbase->fed_by.insert (r2);
1537 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1541 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1545 /* now recurse, so that we can mark base as being fed by
1546 all routes that feed r2
1549 trace_terminal (r2, rbase);
1556 Session::resort_routes ()
1558 /* don't do anything here with signals emitted
1559 by Routes while we are being destroyed.
1562 if (_state_of_the_state & Deletion) {
1569 RCUWriter<RouteList> writer (routes);
1570 shared_ptr<RouteList> r = writer.get_copy ();
1571 resort_routes_using (r);
1572 /* writer goes out of scope and forces update */
1577 Session::resort_routes_using (shared_ptr<RouteList> r)
1579 RouteList::iterator i, j;
1581 for (i = r->begin(); i != r->end(); ++i) {
1583 (*i)->fed_by.clear ();
1585 for (j = r->begin(); j != r->end(); ++j) {
1587 /* although routes can feed themselves, it will
1588 cause an endless recursive descent if we
1589 detect it. so don't bother checking for
1597 if ((*j)->feeds (*i)) {
1598 (*i)->fed_by.insert (*j);
1603 for (i = r->begin(); i != r->end(); ++i) {
1604 trace_terminal (*i, *i);
1610 /* don't leave dangling references to routes in Route::fed_by */
1612 for (i = r->begin(); i != r->end(); ++i) {
1613 (*i)->fed_by.clear ();
1617 cerr << "finished route resort\n";
1619 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1620 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1627 list<boost::shared_ptr<AudioTrack> >
1628 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1630 char track_name[32];
1631 uint32_t track_id = 0;
1633 uint32_t channels_used = 0;
1635 RouteList new_routes;
1636 list<boost::shared_ptr<AudioTrack> > ret;
1637 uint32_t control_id;
1639 /* count existing audio tracks */
1642 shared_ptr<RouteList> r = routes.reader ();
1644 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1645 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1646 if (!(*i)->hidden()) {
1648 channels_used += (*i)->n_inputs();
1654 vector<string> physinputs;
1655 vector<string> physoutputs;
1656 uint32_t nphysical_in;
1657 uint32_t nphysical_out;
1659 _engine.get_physical_outputs (physoutputs);
1660 _engine.get_physical_inputs (physinputs);
1661 control_id = ntracks() + nbusses() + 1;
1665 /* check for duplicate route names, since we might have pre-existing
1666 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1667 save, close,restart,add new route - first named route is now
1675 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1677 if (route_by_name (track_name) == 0) {
1681 } while (track_id < (UINT_MAX-1));
1683 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1684 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1689 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1690 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1695 shared_ptr<AudioTrack> track;
1698 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1700 if (track->ensure_io (input_channels, output_channels, false, this)) {
1701 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1702 input_channels, output_channels)
1708 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1712 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1713 port = physinputs[(channels_used+x)%nphysical_in];
1716 if (port.length() && track->connect_input (track->input (x), port, this)) {
1722 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1726 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1727 port = physoutputs[(channels_used+x)%nphysical_out];
1728 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1730 port = _master_out->input (x%_master_out->n_inputs())->name();
1734 if (port.length() && track->connect_output (track->output (x), port, this)) {
1739 channels_used += track->n_inputs ();
1742 vector<string> cports;
1743 uint32_t ni = _control_out->n_inputs();
1745 for (n = 0; n < ni; ++n) {
1746 cports.push_back (_control_out->input(n)->name());
1749 track->set_control_outs (cports);
1752 // assert (current_thread != RT_thread)
1754 track->audio_diskstream()->non_realtime_input_change();
1756 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1757 track->set_remote_control_id (control_id);
1760 new_routes.push_back (track);
1761 ret.push_back (track);
1764 catch (failed_constructor &err) {
1765 error << _("Session: could not create new audio track.") << endmsg;
1768 /* we need to get rid of this, since the track failed to be created */
1769 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1772 RCUWriter<DiskstreamList> writer (diskstreams);
1773 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1774 ds->remove (track->audio_diskstream());
1781 catch (AudioEngine::PortRegistrationFailure& pfe) {
1783 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;
1786 /* we need to get rid of this, since the track failed to be created */
1787 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1790 RCUWriter<DiskstreamList> writer (diskstreams);
1791 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1792 ds->remove (track->audio_diskstream());
1803 if (!new_routes.empty()) {
1804 add_routes (new_routes, false);
1805 save_state (_current_snapshot_name);
1812 Session::set_remote_control_ids ()
1814 RemoteModel m = Config->get_remote_model();
1816 shared_ptr<RouteList> r = routes.reader ();
1818 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1819 if ( MixerOrdered == m) {
1820 long order = (*i)->order_key(N_("signal"));
1821 (*i)->set_remote_control_id( order+1 );
1822 } else if ( EditorOrdered == m) {
1823 long order = (*i)->order_key(N_("editor"));
1824 (*i)->set_remote_control_id( order+1 );
1825 } else if ( UserOrdered == m) {
1826 //do nothing ... only changes to remote id's are initiated by user
1833 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1836 uint32_t bus_id = 1;
1840 uint32_t control_id;
1842 /* count existing audio busses */
1845 shared_ptr<RouteList> r = routes.reader ();
1847 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1848 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1849 if (!(*i)->hidden()) {
1856 vector<string> physinputs;
1857 vector<string> physoutputs;
1859 _engine.get_physical_outputs (physoutputs);
1860 _engine.get_physical_inputs (physinputs);
1861 control_id = ntracks() + nbusses() + 1;
1868 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1870 if (route_by_name (bus_name) == 0) {
1874 } while (bus_id < (UINT_MAX-1));
1877 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1879 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1880 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1881 input_channels, output_channels)
1886 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1890 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1891 port = physinputs[((n+x)%n_physical_inputs)];
1894 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1899 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1903 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1904 port = physoutputs[((n+x)%n_physical_outputs)];
1905 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1907 port = _master_out->input (x%_master_out->n_inputs())->name();
1911 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1917 vector<string> cports;
1918 uint32_t ni = _control_out->n_inputs();
1920 for (uint32_t n = 0; n < ni; ++n) {
1921 cports.push_back (_control_out->input(n)->name());
1923 bus->set_control_outs (cports);
1926 bus->set_remote_control_id (control_id);
1929 ret.push_back (bus);
1933 catch (failed_constructor &err) {
1934 error << _("Session: could not create new audio route.") << endmsg;
1938 catch (AudioEngine::PortRegistrationFailure& pfe) {
1939 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;
1949 add_routes (ret, false);
1950 save_state (_current_snapshot_name);
1958 Session::add_routes (RouteList& new_routes, bool save)
1961 RCUWriter<RouteList> writer (routes);
1962 shared_ptr<RouteList> r = writer.get_copy ();
1963 r->insert (r->end(), new_routes.begin(), new_routes.end());
1964 resort_routes_using (r);
1967 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1969 boost::weak_ptr<Route> wpr (*x);
1971 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1972 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1973 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1974 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1976 if ((*x)->master()) {
1980 if ((*x)->control()) {
1981 _control_out = (*x);
1988 save_state (_current_snapshot_name);
1991 RouteAdded (new_routes); /* EMIT SIGNAL */
1995 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1997 /* need to do this in case we're rolling at the time, to prevent false underruns */
1998 dstream->do_refill_with_alloc();
2001 RCUWriter<DiskstreamList> writer (diskstreams);
2002 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2003 ds->push_back (dstream);
2006 dstream->set_block_size (current_block_size);
2008 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2009 /* this will connect to future changes, and check the current length */
2010 diskstream_playlist_changed (dstream);
2012 dstream->prepare ();
2016 Session::remove_route (shared_ptr<Route> route)
2019 RCUWriter<RouteList> writer (routes);
2020 shared_ptr<RouteList> rs = writer.get_copy ();
2024 /* deleting the master out seems like a dumb
2025 idea, but its more of a UI policy issue
2029 if (route == _master_out) {
2030 _master_out = shared_ptr<Route> ();
2033 if (route == _control_out) {
2034 _control_out = shared_ptr<Route> ();
2036 /* cancel control outs for all routes */
2038 vector<string> empty;
2040 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2041 (*r)->set_control_outs (empty);
2045 update_route_solo_state ();
2047 /* writer goes out of scope, forces route list update */
2050 // FIXME: audio specific
2052 boost::shared_ptr<AudioDiskstream> ds;
2054 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2055 ds = at->audio_diskstream();
2061 RCUWriter<DiskstreamList> dsl (diskstreams);
2062 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2067 find_current_end ();
2069 update_latency_compensation (false, false);
2072 // We need to disconnect the routes inputs and outputs
2073 route->disconnect_inputs(NULL);
2074 route->disconnect_outputs(NULL);
2076 /* get rid of it from the dead wood collection in the route list manager */
2078 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2082 /* try to cause everyone to drop their references */
2084 route->drop_references ();
2086 /* save the new state of the world */
2088 if (save_state (_current_snapshot_name)) {
2089 save_history (_current_snapshot_name);
2094 Session::route_mute_changed (void* src)
2100 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2102 if (solo_update_disabled) {
2108 boost::shared_ptr<Route> route = wpr.lock ();
2111 /* should not happen */
2112 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2116 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2118 shared_ptr<RouteList> r = routes.reader ();
2120 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2122 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2126 /* don't mess with busses */
2128 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2134 /* don't mess with tracks */
2136 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2141 if ((*i) != route &&
2142 ((*i)->mix_group () == 0 ||
2143 (*i)->mix_group () != route->mix_group () ||
2144 !route->mix_group ()->is_active())) {
2146 if ((*i)->soloed()) {
2148 /* if its already soloed, and solo latching is enabled,
2149 then leave it as it is.
2152 if (Config->get_solo_latched()) {
2159 solo_update_disabled = true;
2160 (*i)->set_solo (false, src);
2161 solo_update_disabled = false;
2165 bool something_soloed = false;
2166 bool same_thing_soloed = false;
2167 bool signal = false;
2169 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2170 if ((*i)->soloed()) {
2171 something_soloed = true;
2172 if (dynamic_cast<AudioTrack*>((*i).get())) {
2174 same_thing_soloed = true;
2179 same_thing_soloed = true;
2187 if (something_soloed != currently_soloing) {
2189 currently_soloing = something_soloed;
2192 modify_solo_mute (is_track, same_thing_soloed);
2195 SoloActive (currently_soloing); /* EMIT SIGNAL */
2198 SoloChanged (); /* EMIT SIGNAL */
2204 Session::update_route_solo_state ()
2207 bool is_track = false;
2208 bool signal = false;
2210 /* caller must hold RouteLock */
2212 /* this is where we actually implement solo by changing
2213 the solo mute setting of each track.
2216 shared_ptr<RouteList> r = routes.reader ();
2218 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2219 if ((*i)->soloed()) {
2221 if (dynamic_cast<AudioTrack*>((*i).get())) {
2228 if (mute != currently_soloing) {
2230 currently_soloing = mute;
2233 if (!is_track && !mute) {
2235 /* nothing is soloed */
2237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238 (*i)->set_solo_mute (false);
2248 modify_solo_mute (is_track, mute);
2251 SoloActive (currently_soloing);
2256 Session::modify_solo_mute (bool is_track, bool mute)
2258 shared_ptr<RouteList> r = routes.reader ();
2260 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2264 /* only alter track solo mute */
2266 if (dynamic_cast<AudioTrack*>((*i).get())) {
2267 if ((*i)->soloed()) {
2268 (*i)->set_solo_mute (!mute);
2270 (*i)->set_solo_mute (mute);
2276 /* only alter bus solo mute */
2278 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2280 if ((*i)->soloed()) {
2282 (*i)->set_solo_mute (false);
2286 /* don't mute master or control outs
2287 in response to another bus solo
2290 if ((*i) != _master_out &&
2291 (*i) != _control_out) {
2292 (*i)->set_solo_mute (mute);
2303 Session::catch_up_on_solo ()
2305 /* this is called after set_state() to catch the full solo
2306 state, which can't be correctly determined on a per-route
2307 basis, but needs the global overview that only the session
2310 update_route_solo_state();
2314 Session::route_by_name (string name)
2316 shared_ptr<RouteList> r = routes.reader ();
2318 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2319 if ((*i)->name() == name) {
2324 return shared_ptr<Route> ((Route*) 0);
2328 Session::route_by_id (PBD::ID id)
2330 shared_ptr<RouteList> r = routes.reader ();
2332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2333 if ((*i)->id() == id) {
2338 return shared_ptr<Route> ((Route*) 0);
2342 Session::route_by_remote_id (uint32_t id)
2344 shared_ptr<RouteList> r = routes.reader ();
2346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2347 if ((*i)->remote_control_id() == id) {
2352 return shared_ptr<Route> ((Route*) 0);
2356 Session::find_current_end ()
2358 if (_state_of_the_state & Loading) {
2362 nframes_t max = get_maximum_extent ();
2364 if (max > end_location->end()) {
2365 end_location->set_end (max);
2367 DurationChanged(); /* EMIT SIGNAL */
2372 Session::get_maximum_extent () const
2377 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2379 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2380 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2381 if ((me = pl->get_maximum_extent()) > max) {
2389 boost::shared_ptr<Diskstream>
2390 Session::diskstream_by_name (string name)
2392 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2394 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2395 if ((*i)->name() == name) {
2400 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2403 boost::shared_ptr<Diskstream>
2404 Session::diskstream_by_id (const PBD::ID& id)
2406 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2408 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2409 if ((*i)->id() == id) {
2414 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2417 /* AudioRegion management */
2420 Session::new_region_name (string old)
2422 string::size_type last_period;
2424 string::size_type len = old.length() + 64;
2427 if ((last_period = old.find_last_of ('.')) == string::npos) {
2429 /* no period present - add one explicitly */
2432 last_period = old.length() - 1;
2437 number = atoi (old.substr (last_period+1).c_str());
2441 while (number < (UINT_MAX-1)) {
2443 AudioRegionList::const_iterator i;
2448 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2451 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2452 if (i->second->name() == sbuf) {
2457 if (i == audio_regions.end()) {
2462 if (number != (UINT_MAX-1)) {
2466 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2471 Session::region_name (string& result, string base, bool newlevel) const
2478 Glib::Mutex::Lock lm (region_lock);
2480 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2488 /* XXX this is going to be slow. optimize me later */
2493 string::size_type pos;
2495 pos = base.find_last_of ('.');
2497 /* pos may be npos, but then we just use entire base */
2499 subbase = base.substr (0, pos);
2503 bool name_taken = true;
2506 Glib::Mutex::Lock lm (region_lock);
2508 for (int n = 1; n < 5000; ++n) {
2511 snprintf (buf, sizeof (buf), ".%d", n);
2516 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2517 if (i->second->name() == result) {
2530 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2538 Session::add_region (boost::shared_ptr<Region> region)
2540 boost::shared_ptr<AudioRegion> ar;
2541 boost::shared_ptr<AudioRegion> oar;
2545 Glib::Mutex::Lock lm (region_lock);
2547 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2549 AudioRegionList::iterator x;
2551 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2553 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2555 if (ar->region_list_equivalent (oar)) {
2560 if (x == audio_regions.end()) {
2562 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2564 entry.first = region->id();
2567 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2579 fatal << _("programming error: ")
2580 << X_("unknown region type passed to Session::add_region()")
2587 /* mark dirty because something has changed even if we didn't
2588 add the region to the region list.
2594 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2595 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2596 AudioRegionAdded (ar); /* EMIT SIGNAL */
2601 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2603 boost::shared_ptr<Region> region (weak_region.lock ());
2609 if (what_changed & Region::HiddenChanged) {
2610 /* relay hidden changes */
2611 RegionHiddenChange (region);
2616 Session::remove_region (boost::weak_ptr<Region> weak_region)
2618 AudioRegionList::iterator i;
2619 boost::shared_ptr<Region> region (weak_region.lock ());
2625 boost::shared_ptr<AudioRegion> ar;
2626 bool removed = false;
2629 Glib::Mutex::Lock lm (region_lock);
2631 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2632 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2633 audio_regions.erase (i);
2639 fatal << _("programming error: ")
2640 << X_("unknown region type passed to Session::remove_region()")
2646 /* mark dirty because something has changed even if we didn't
2647 remove the region from the region list.
2653 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2657 boost::shared_ptr<AudioRegion>
2658 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2660 AudioRegionList::iterator i;
2661 boost::shared_ptr<AudioRegion> region;
2662 Glib::Mutex::Lock lm (region_lock);
2664 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2668 if (region->whole_file()) {
2670 if (child->source_equivalent (region)) {
2676 return boost::shared_ptr<AudioRegion> ();
2680 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2682 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2683 (*i)->get_region_list_equivalent_regions (region, result);
2687 Session::destroy_region (boost::shared_ptr<Region> region)
2689 vector<boost::shared_ptr<Source> > srcs;
2692 boost::shared_ptr<AudioRegion> aregion;
2694 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2698 if (aregion->playlist()) {
2699 aregion->playlist()->destroy_region (region);
2702 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2703 srcs.push_back (aregion->source (n));
2707 region->drop_references ();
2709 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2711 if (!(*i)->used()) {
2712 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2715 (afs)->mark_for_remove ();
2718 (*i)->drop_references ();
2720 cerr << "source was not used by any playlist\n";
2728 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2730 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2731 destroy_region (*i);
2737 Session::remove_last_capture ()
2739 list<boost::shared_ptr<Region> > r;
2741 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2743 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2744 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2747 r.insert (r.end(), l.begin(), l.end());
2752 destroy_regions (r);
2757 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2763 /* Source Management */
2766 Session::add_source (boost::shared_ptr<Source> source)
2768 boost::shared_ptr<AudioFileSource> afs;
2770 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2772 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2773 pair<AudioSourceList::iterator,bool> result;
2775 entry.first = source->id();
2779 Glib::Mutex::Lock lm (audio_source_lock);
2780 result = audio_sources.insert (entry);
2783 if (result.second) {
2784 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2792 Session::remove_source (boost::weak_ptr<Source> src)
2794 AudioSourceList::iterator i;
2795 boost::shared_ptr<Source> source = src.lock();
2802 Glib::Mutex::Lock lm (audio_source_lock);
2804 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2805 audio_sources.erase (i);
2809 if (!_state_of_the_state & InCleanup) {
2811 /* save state so we don't end up with a session file
2812 referring to non-existent sources.
2815 save_state (_current_snapshot_name);
2819 boost::shared_ptr<Source>
2820 Session::source_by_id (const PBD::ID& id)
2822 Glib::Mutex::Lock lm (audio_source_lock);
2823 AudioSourceList::iterator i;
2824 boost::shared_ptr<Source> source;
2826 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2830 /* XXX search MIDI or other searches here */
2836 Session::peak_path_from_audio_path (string audio_path) const
2841 res += PBD::basename_nosuffix (audio_path);
2848 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2851 string old_basename = PBD::basename_nosuffix (oldname);
2852 string new_legalized = legalize_for_path (newname);
2854 /* note: we know (or assume) the old path is already valid */
2858 /* destructive file sources have a name of the form:
2860 /path/to/Tnnnn-NAME(%[LR])?.wav
2862 the task here is to replace NAME with the new name.
2865 /* find last slash */
2869 string::size_type slash;
2870 string::size_type dash;
2872 if ((slash = path.find_last_of ('/')) == string::npos) {
2876 dir = path.substr (0, slash+1);
2878 /* '-' is not a legal character for the NAME part of the path */
2880 if ((dash = path.find_last_of ('-')) == string::npos) {
2884 prefix = path.substr (slash+1, dash-(slash+1));
2889 path += new_legalized;
2890 path += ".wav"; /* XXX gag me with a spoon */
2894 /* non-destructive file sources have a name of the form:
2896 /path/to/NAME-nnnnn(%[LR])?.wav
2898 the task here is to replace NAME with the new name.
2903 string::size_type slash;
2904 string::size_type dash;
2905 string::size_type postfix;
2907 /* find last slash */
2909 if ((slash = path.find_last_of ('/')) == string::npos) {
2913 dir = path.substr (0, slash+1);
2915 /* '-' is not a legal character for the NAME part of the path */
2917 if ((dash = path.find_last_of ('-')) == string::npos) {
2921 suffix = path.substr (dash+1);
2923 // Suffix is now everything after the dash. Now we need to eliminate
2924 // the nnnnn part, which is done by either finding a '%' or a '.'
2926 postfix = suffix.find_last_of ("%");
2927 if (postfix == string::npos) {
2928 postfix = suffix.find_last_of ('.');
2931 if (postfix != string::npos) {
2932 suffix = suffix.substr (postfix);
2934 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2938 const uint32_t limit = 10000;
2939 char buf[PATH_MAX+1];
2941 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2943 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2945 if (access (buf, F_OK) != 0) {
2953 error << "FATAL ERROR! Could not find a " << endl;
2962 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2966 char buf[PATH_MAX+1];
2967 const uint32_t limit = 10000;
2971 legalized = legalize_for_path (name);
2973 /* find a "version" of the file name that doesn't exist in
2974 any of the possible directories.
2977 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2979 vector<space_and_path>::iterator i;
2980 uint32_t existing = 0;
2982 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2986 spath += sound_dir (false);
2990 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2991 } else if (nchan == 2) {
2993 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2995 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2997 } else if (nchan < 26) {
2998 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3000 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3009 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3010 } else if (nchan == 2) {
3012 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3014 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3016 } else if (nchan < 26) {
3017 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3019 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3023 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3029 if (existing == 0) {
3034 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3036 throw failed_constructor();
3040 /* we now have a unique name for the file, but figure out where to
3046 spath = discover_best_sound_dir ();
3049 string::size_type pos = foo.find_last_of ('/');
3051 if (pos == string::npos) {
3054 spath += foo.substr (pos + 1);
3060 boost::shared_ptr<AudioFileSource>
3061 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3063 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3064 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3067 /* Playlist management */
3069 boost::shared_ptr<Playlist>
3070 Session::playlist_by_name (string name)
3072 Glib::Mutex::Lock lm (playlist_lock);
3073 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3074 if ((*i)->name() == name) {
3078 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3079 if ((*i)->name() == name) {
3084 return boost::shared_ptr<Playlist>();
3088 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3090 if (playlist->hidden()) {
3095 Glib::Mutex::Lock lm (playlist_lock);
3096 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3097 playlists.insert (playlists.begin(), playlist);
3098 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3099 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3105 PlaylistAdded (playlist); /* EMIT SIGNAL */
3109 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3112 Glib::Mutex::Lock lm (playlist_lock);
3113 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3116 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3123 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3125 boost::shared_ptr<Playlist> pl(wpl.lock());
3131 PlaylistList::iterator x;
3134 /* its not supposed to be visible */
3139 Glib::Mutex::Lock lm (playlist_lock);
3143 unused_playlists.insert (pl);
3145 if ((x = playlists.find (pl)) != playlists.end()) {
3146 playlists.erase (x);
3152 playlists.insert (pl);
3154 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3155 unused_playlists.erase (x);
3162 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3164 if (_state_of_the_state & Deletion) {
3168 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3175 Glib::Mutex::Lock lm (playlist_lock);
3177 PlaylistList::iterator i;
3179 i = find (playlists.begin(), playlists.end(), playlist);
3180 if (i != playlists.end()) {
3181 playlists.erase (i);
3184 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3185 if (i != unused_playlists.end()) {
3186 unused_playlists.erase (i);
3193 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3197 Session::set_audition (boost::shared_ptr<Region> r)
3199 pending_audition_region = r;
3200 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3201 schedule_butler_transport_work ();
3205 Session::audition_playlist ()
3207 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3208 ev->region.reset ();
3213 Session::non_realtime_set_audition ()
3215 if (!pending_audition_region) {
3216 auditioner->audition_current_playlist ();
3218 auditioner->audition_region (pending_audition_region);
3219 pending_audition_region.reset ();
3221 AuditionActive (true); /* EMIT SIGNAL */
3225 Session::audition_region (boost::shared_ptr<Region> r)
3227 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3233 Session::cancel_audition ()
3235 if (auditioner->active()) {
3236 auditioner->cancel_audition ();
3237 AuditionActive (false); /* EMIT SIGNAL */
3242 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3244 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3248 Session::remove_empty_sounds ()
3250 PathScanner scanner;
3252 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3254 Glib::Mutex::Lock lm (audio_source_lock);
3256 regex_t compiled_tape_track_pattern;
3259 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3263 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3265 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3269 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3271 /* never remove files that appear to be a tape track */
3273 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3278 if (AudioFileSource::is_empty (*this, *(*i))) {
3280 unlink ((*i)->c_str());
3282 string peak_path = peak_path_from_audio_path (**i);
3283 unlink (peak_path.c_str());
3289 delete possible_audiofiles;
3293 Session::is_auditioning () const
3295 /* can be called before we have an auditioner object */
3297 return auditioner->active();
3304 Session::set_all_solo (bool yn)
3306 shared_ptr<RouteList> r = routes.reader ();
3308 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3309 if (!(*i)->hidden()) {
3310 (*i)->set_solo (yn, this);
3318 Session::set_all_mute (bool yn)
3320 shared_ptr<RouteList> r = routes.reader ();
3322 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3323 if (!(*i)->hidden()) {
3324 (*i)->set_mute (yn, this);
3332 Session::n_diskstreams () const
3336 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3338 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3339 if (!(*i)->hidden()) {
3347 Session::graph_reordered ()
3349 /* don't do this stuff if we are setting up connections
3350 from a set_state() call or creating new tracks.
3353 if (_state_of_the_state & InitialConnecting) {
3357 /* every track/bus asked for this to be handled but it was deferred because
3358 we were connecting. do it now.
3361 request_input_change_handling ();
3365 /* force all diskstreams to update their capture offset values to
3366 reflect any changes in latencies within the graph.
3369 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3371 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3372 (*i)->set_capture_offset ();
3377 Session::record_disenable_all ()
3379 record_enable_change_all (false);
3383 Session::record_enable_all ()
3385 record_enable_change_all (true);
3389 Session::record_enable_change_all (bool yn)
3391 shared_ptr<RouteList> r = routes.reader ();
3393 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3396 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3397 at->set_record_enable (yn, this);
3401 /* since we don't keep rec-enable state, don't mark session dirty */
3405 Session::add_redirect (Redirect* redirect)
3409 PortInsert* port_insert;
3410 PluginInsert* plugin_insert;
3412 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3413 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3414 _port_inserts.insert (_port_inserts.begin(), port_insert);
3415 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3416 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3418 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3421 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3422 _sends.insert (_sends.begin(), send);
3424 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3428 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3434 Session::remove_redirect (Redirect* redirect)
3438 PortInsert* port_insert;
3439 PluginInsert* plugin_insert;
3441 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3442 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3443 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3444 if (x != _port_inserts.end()) {
3445 insert_bitset[port_insert->bit_slot()] = false;
3446 _port_inserts.erase (x);
3448 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3449 _plugin_inserts.remove (plugin_insert);
3451 fatal << string_compose (_("programming error: %1"),
3452 X_("unknown type of Insert deleted!"))
3456 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3457 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3458 if (x != _sends.end()) {
3459 send_bitset[send->bit_slot()] = false;
3463 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3471 Session::available_capture_duration ()
3473 float sample_bytes_on_disk = 4.0; // keep gcc happy
3475 switch (Config->get_native_file_data_format()) {
3477 sample_bytes_on_disk = 4.0;
3481 sample_bytes_on_disk = 3.0;
3485 /* impossible, but keep some gcc versions happy */
3486 fatal << string_compose (_("programming error: %1"),
3487 X_("illegal native file data format"))
3492 double scale = 4096.0 / sample_bytes_on_disk;
3494 if (_total_free_4k_blocks * scale > (double) max_frames) {
3498 return (nframes_t) floor (_total_free_4k_blocks * scale);
3502 Session::add_connection (ARDOUR::Connection* connection)
3505 Glib::Mutex::Lock guard (connection_lock);
3506 _connections.push_back (connection);
3509 ConnectionAdded (connection); /* EMIT SIGNAL */
3515 Session::remove_connection (ARDOUR::Connection* connection)
3517 bool removed = false;
3520 Glib::Mutex::Lock guard (connection_lock);
3521 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3523 if (i != _connections.end()) {
3524 _connections.erase (i);
3530 ConnectionRemoved (connection); /* EMIT SIGNAL */
3536 ARDOUR::Connection *
3537 Session::connection_by_name (string name) const
3539 Glib::Mutex::Lock lm (connection_lock);
3541 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3542 if ((*i)->name() == name) {
3551 Session::tempo_map_changed (Change ignored)
3558 Session::ensure_passthru_buffers (uint32_t howmany)
3560 while (howmany > _passthru_buffers.size()) {
3562 #ifdef NO_POSIX_MEMALIGN
3563 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3565 posix_memalign((void **)&p,16,current_block_size * 4);
3567 _passthru_buffers.push_back (p);
3571 #ifdef NO_POSIX_MEMALIGN
3572 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3574 posix_memalign((void **)&p,16,current_block_size * 4);
3576 memset (p, 0, sizeof (Sample) * current_block_size);
3577 _silent_buffers.push_back (p);
3581 #ifdef NO_POSIX_MEMALIGN
3582 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3584 posix_memalign((void **)&p,16,current_block_size * 4);
3586 memset (p, 0, sizeof (Sample) * current_block_size);
3587 _send_buffers.push_back (p);
3590 allocate_pan_automation_buffers (current_block_size, howmany, false);
3594 Session::next_insert_id ()
3596 /* this doesn't really loop forever. just think about it */
3599 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3600 if (!insert_bitset[n]) {
3601 insert_bitset[n] = true;
3602 cerr << "Returning " << n << " as insert ID\n";
3608 /* none available, so resize and try again */
3610 insert_bitset.resize (insert_bitset.size() + 16, false);
3615 Session::next_send_id ()
3617 /* this doesn't really loop forever. just think about it */
3620 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3621 if (!send_bitset[n]) {
3622 send_bitset[n] = true;
3623 cerr << "Returning " << n << " as send ID\n";
3629 /* none available, so resize and try again */
3631 send_bitset.resize (send_bitset.size() + 16, false);
3636 Session::mark_send_id (uint32_t id)
3638 if (id >= send_bitset.size()) {
3639 send_bitset.resize (id+16, false);
3641 if (send_bitset[id]) {
3642 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3644 send_bitset[id] = true;
3648 Session::mark_insert_id (uint32_t id)
3650 if (id >= insert_bitset.size()) {
3651 insert_bitset.resize (id+16, false);
3653 if (insert_bitset[id]) {
3654 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3656 insert_bitset[id] = true;
3659 /* Named Selection management */
3662 Session::named_selection_by_name (string name)
3664 Glib::Mutex::Lock lm (named_selection_lock);
3665 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3666 if ((*i)->name == name) {
3674 Session::add_named_selection (NamedSelection* named_selection)
3677 Glib::Mutex::Lock lm (named_selection_lock);
3678 named_selections.insert (named_selections.begin(), named_selection);
3681 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3687 NamedSelectionAdded (); /* EMIT SIGNAL */
3691 Session::remove_named_selection (NamedSelection* named_selection)
3693 bool removed = false;
3696 Glib::Mutex::Lock lm (named_selection_lock);
3698 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3700 if (i != named_selections.end()) {
3702 named_selections.erase (i);
3709 NamedSelectionRemoved (); /* EMIT SIGNAL */
3714 Session::reset_native_file_format ()
3716 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3718 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3719 (*i)->reset_write_sources (false);
3724 Session::route_name_unique (string n) const
3726 shared_ptr<RouteList> r = routes.reader ();
3728 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3729 if ((*i)->name() == n) {
3738 Session::n_playlists () const
3740 Glib::Mutex::Lock lm (playlist_lock);
3741 return playlists.size();
3745 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3747 if (!force && howmany <= _npan_buffers) {
3751 if (_pan_automation_buffer) {
3753 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3754 delete [] _pan_automation_buffer[i];
3757 delete [] _pan_automation_buffer;
3760 _pan_automation_buffer = new pan_t*[howmany];
3762 for (uint32_t i = 0; i < howmany; ++i) {
3763 _pan_automation_buffer[i] = new pan_t[nframes];
3766 _npan_buffers = howmany;
3770 Session::freeze (InterThreadInfo& itt)
3772 shared_ptr<RouteList> r = routes.reader ();
3774 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3778 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3779 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3790 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3791 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3794 boost::shared_ptr<Playlist> playlist;
3795 boost::shared_ptr<AudioFileSource> fsource;
3797 char buf[PATH_MAX+1];
3801 nframes_t this_chunk;
3803 vector<Sample*> buffers;
3805 // any bigger than this seems to cause stack overflows in called functions
3806 const nframes_t chunk_size = (128 * 1024)/4;
3808 g_atomic_int_set (&processing_prohibited, 1);
3810 /* call tree *MUST* hold route_lock */
3812 if ((playlist = track.diskstream()->playlist()) == 0) {
3816 /* external redirects will be a problem */
3818 if (track.has_external_redirects()) {
3822 nchans = track.audio_diskstream()->n_channels();
3824 dir = discover_best_sound_dir ();
3826 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3828 for (x = 0; x < 99999; ++x) {
3829 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3830 if (access (buf, F_OK) != 0) {
3836 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3841 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3844 catch (failed_constructor& err) {
3845 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3849 srcs.push_back (fsource);
3852 /* XXX need to flush all redirects */
3857 /* create a set of reasonably-sized buffers */
3859 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3861 #ifdef NO_POSIX_MEMALIGN
3862 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3864 posix_memalign((void **)&b,16,chunk_size * 4);
3866 buffers.push_back (b);
3869 while (to_do && !itt.cancel) {
3871 this_chunk = min (to_do, chunk_size);
3873 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3878 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3879 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3882 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3888 start += this_chunk;
3889 to_do -= this_chunk;
3891 itt.progress = (float) (1.0 - ((double) to_do / len));
3900 xnow = localtime (&now);
3902 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3903 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3906 afs->update_header (position, *xnow, now);
3910 /* build peakfile for new source */
3912 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3913 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3915 afs->build_peaks ();
3919 /* construct a region to represent the bounced material */
3921 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3922 region_name_from_path (srcs.front()->name(), true));
3929 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3930 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3933 afs->mark_for_remove ();
3936 (*src)->drop_references ();
3940 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3944 g_atomic_int_set (&processing_prohibited, 0);
3952 Session::get_silent_buffers (uint32_t howmany)
3954 for (uint32_t i = 0; i < howmany; ++i) {
3955 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3957 return _silent_buffers;
3961 Session::ntracks () const
3964 shared_ptr<RouteList> r = routes.reader ();
3966 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3967 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3976 Session::nbusses () const
3979 shared_ptr<RouteList> r = routes.reader ();
3981 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3982 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3991 Session::add_automation_list(AutomationList *al)
3993 automation_lists[al->id()] = al;
3997 Session::compute_initial_length ()
3999 return _engine.frame_rate() * 60 * 5;