2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/utils.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/destructive_filesource.h>
54 #include <ardour/auditioner.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/redirect.h>
57 #include <ardour/send.h>
58 #include <ardour/insert.h>
59 #include <ardour/connection.h>
60 #include <ardour/slave.h>
61 #include <ardour/tempo.h>
62 #include <ardour/audio_track.h>
63 #include <ardour/cycle_timer.h>
64 #include <ardour/named_selection.h>
65 #include <ardour/crossfade.h>
66 #include <ardour/playlist.h>
67 #include <ardour/click.h>
68 #include <ardour/data_type.h>
69 #include <ardour/source_factory.h>
70 #include <ardour/region_factory.h>
73 #include <ardour/osc.h>
79 using namespace ARDOUR;
81 using boost::shared_ptr;
83 const char* Session::_template_suffix = X_(".template");
84 const char* Session::_statefile_suffix = X_(".ardour");
85 const char* Session::_pending_suffix = X_(".pending");
86 const char* Session::old_sound_dir_name = X_("sounds");
87 const char* Session::sound_dir_name = X_("audiofiles");
88 const char* Session::peak_dir_name = X_("peaks");
89 const char* Session::dead_sound_dir_name = X_("dead_sounds");
90 const char* Session::interchange_dir_name = X_("interchange");
92 Session::compute_peak_t Session::compute_peak = 0;
93 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
94 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
95 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
97 sigc::signal<int> Session::AskAboutPendingState;
98 sigc::signal<void> Session::SendFeedback;
100 sigc::signal<void> Session::SMPTEOffsetChanged;
101 sigc::signal<void> Session::StartTimeChanged;
102 sigc::signal<void> Session::EndTimeChanged;
105 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
108 char buf[PATH_MAX+1];
112 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
113 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
119 /* check to see if it exists, and what it is */
121 if (stat (str.c_str(), &statbuf)) {
122 if (errno == ENOENT) {
125 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
133 /* it exists, so it must either be the name
134 of the directory, or the name of the statefile
138 if (S_ISDIR (statbuf.st_mode)) {
140 string::size_type slash = str.find_last_of ('/');
142 if (slash == string::npos) {
144 /* a subdirectory of cwd, so statefile should be ... */
150 tmp += _statefile_suffix;
154 if (stat (tmp.c_str(), &statbuf)) {
155 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
165 /* some directory someplace in the filesystem.
166 the snapshot name is the directory name
171 snapshot = str.substr (slash+1);
175 } else if (S_ISREG (statbuf.st_mode)) {
177 string::size_type slash = str.find_last_of ('/');
178 string::size_type suffix;
180 /* remove the suffix */
182 if (slash != string::npos) {
183 snapshot = str.substr (slash+1);
188 suffix = snapshot.find (_statefile_suffix);
190 if (suffix == string::npos) {
191 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
197 snapshot = snapshot.substr (0, suffix);
199 if (slash == string::npos) {
201 /* we must be in the directory where the
202 statefile lives. get it using cwd().
205 char cwd[PATH_MAX+1];
207 if (getcwd (cwd, sizeof (cwd)) == 0) {
208 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
217 /* full path to the statefile */
219 path = str.substr (0, slash);
224 /* what type of file is it? */
225 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
231 /* its the name of a new directory. get the name
235 string::size_type slash = str.find_last_of ('/');
237 if (slash == string::npos) {
239 /* no slash, just use the name, but clean it up */
241 path = legalize_for_path (str);
247 snapshot = str.substr (slash+1);
254 Session::Session (AudioEngine &eng,
256 string snapshot_name,
257 string* mix_template)
260 _mmc_port (default_mmc_port),
261 _mtc_port (default_mtc_port),
262 _midi_port (default_midi_port),
263 pending_events (2048),
264 midi_requests (128), // the size of this should match the midi request pool size
265 diskstreams (new DiskstreamList),
266 routes (new RouteList),
267 auditioner ((Auditioner*) 0),
273 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
275 n_physical_outputs = _engine.n_physical_outputs();
276 n_physical_inputs = _engine.n_physical_inputs();
278 first_stage_init (fullpath, snapshot_name);
280 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
282 if (create (new_session, mix_template, compute_initial_length())) {
283 cerr << "create failed\n";
285 throw failed_constructor ();
289 if (second_stage_init (new_session)) {
291 throw failed_constructor ();
294 store_recent_sessions(_name, _path);
296 bool was_dirty = dirty();
298 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
300 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
303 DirtyChanged (); /* EMIT SIGNAL */
307 Session::Session (AudioEngine &eng,
309 string snapshot_name,
310 AutoConnectOption input_ac,
311 AutoConnectOption output_ac,
312 uint32_t control_out_channels,
313 uint32_t master_out_channels,
314 uint32_t requested_physical_in,
315 uint32_t requested_physical_out,
316 nframes_t initial_length)
319 _mmc_port (default_mmc_port),
320 _mtc_port (default_mtc_port),
321 _midi_port (default_midi_port),
322 pending_events (2048),
324 diskstreams (new DiskstreamList),
325 routes (new RouteList),
331 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
333 n_physical_outputs = _engine.n_physical_outputs();
334 n_physical_inputs = _engine.n_physical_inputs();
336 if (n_physical_inputs) {
337 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
340 if (n_physical_outputs) {
341 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
344 first_stage_init (fullpath, snapshot_name);
346 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
349 if (create (new_session, 0, initial_length)) {
351 throw failed_constructor ();
356 /* set up Master Out and Control Out if necessary */
361 if (control_out_channels) {
362 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
363 r->set_remote_control_id (control_id++);
368 if (master_out_channels) {
369 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
370 r->set_remote_control_id (control_id);
374 /* prohibit auto-connect to master, because there isn't one */
375 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
384 Config->set_input_auto_connect (input_ac);
385 Config->set_output_auto_connect (output_ac);
387 if (second_stage_init (new_session)) {
389 throw failed_constructor ();
392 store_recent_sessions(_name, _path);
394 bool was_dirty = dirty ();
396 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
398 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
401 DirtyChanged (); /* EMIT SIGNAL */
413 /* if we got to here, leaving pending capture state around
417 remove_pending_capture_state ();
419 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
420 _engine.remove_session ();
422 GoingAway (); /* EMIT SIGNAL */
428 /* clear history so that no references to objects are held any more */
432 /* clear state tree so that no references to objects are held any more */
438 terminate_butler_thread ();
439 terminate_midi_thread ();
441 if (click_data && click_data != default_click) {
442 delete [] click_data;
445 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
446 delete [] click_emphasis_data;
451 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
455 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
459 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
463 AudioDiskstream::free_working_buffers();
465 /* this should cause deletion of the auditioner */
467 // auditioner.reset ();
469 #undef TRACK_DESTRUCTION
470 #ifdef TRACK_DESTRUCTION
471 cerr << "delete named selections\n";
472 #endif /* TRACK_DESTRUCTION */
473 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
474 NamedSelectionList::iterator tmp;
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete playlists\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
487 PlaylistList::iterator tmp;
492 (*i)->drop_references ();
497 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
498 PlaylistList::iterator tmp;
503 (*i)->drop_references ();
509 unused_playlists.clear ();
511 #ifdef TRACK_DESTRUCTION
512 cerr << "delete audio regions\n";
513 #endif /* TRACK_DESTRUCTION */
515 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
516 AudioRegionList::iterator tmp;
521 i->second->drop_references ();
526 audio_regions.clear ();
528 #ifdef TRACK_DESTRUCTION
529 cerr << "delete routes\n";
530 #endif /* TRACK_DESTRUCTION */
532 RCUWriter<RouteList> writer (routes);
533 boost::shared_ptr<RouteList> r = writer.get_copy ();
534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
535 (*i)->drop_references ();
538 /* writer goes out of scope and updates master */
543 #ifdef TRACK_DESTRUCTION
544 cerr << "delete diskstreams\n";
545 #endif /* TRACK_DESTRUCTION */
547 RCUWriter<DiskstreamList> dwriter (diskstreams);
548 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
549 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
550 (*i)->drop_references ();
554 diskstreams.flush ();
556 #ifdef TRACK_DESTRUCTION
557 cerr << "delete audio sources\n";
558 #endif /* TRACK_DESTRUCTION */
559 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
560 AudioSourceList::iterator tmp;
565 i->second->drop_references ();
570 audio_sources.clear ();
572 #ifdef TRACK_DESTRUCTION
573 cerr << "delete mix groups\n";
574 #endif /* TRACK_DESTRUCTION */
575 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
576 list<RouteGroup*>::iterator tmp;
586 #ifdef TRACK_DESTRUCTION
587 cerr << "delete edit groups\n";
588 #endif /* TRACK_DESTRUCTION */
589 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
590 list<RouteGroup*>::iterator tmp;
600 #ifdef TRACK_DESTRUCTION
601 cerr << "delete connections\n";
602 #endif /* TRACK_DESTRUCTION */
603 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
604 ConnectionList::iterator tmp;
614 if (butler_mixdown_buffer) {
615 delete [] butler_mixdown_buffer;
618 if (butler_gain_buffer) {
619 delete [] butler_gain_buffer;
622 Crossfade::set_buffer_size (0);
630 Session::set_worst_io_latencies ()
632 _worst_output_latency = 0;
633 _worst_input_latency = 0;
635 if (!_engine.connected()) {
639 boost::shared_ptr<RouteList> r = routes.reader ();
641 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
642 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
643 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
648 Session::when_engine_running ()
650 string first_physical_output;
652 /* we don't want to run execute this again */
654 set_block_size (_engine.frames_per_cycle());
655 set_frame_rate (_engine.frame_rate());
657 Config->map_parameters (mem_fun (*this, &Session::config_changed));
659 /* every time we reconnect, recompute worst case output latencies */
661 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
663 if (synced_to_jack()) {
664 _engine.transport_stop ();
667 if (Config->get_jack_time_master()) {
668 _engine.transport_locate (_transport_frame);
676 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
678 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
680 /* existing state for Click */
682 if (_click_io->set_state (*child->children().front()) == 0) {
684 _clicking = Config->get_clicking ();
688 error << _("could not setup Click I/O") << endmsg;
694 /* default state for Click */
696 first_physical_output = _engine.get_nth_physical_output (0);
698 if (first_physical_output.length()) {
699 if (_click_io->add_output_port (first_physical_output, this)) {
700 // relax, even though its an error
702 _clicking = Config->get_clicking ();
708 catch (failed_constructor& err) {
709 error << _("cannot setup Click I/O") << endmsg;
712 set_worst_io_latencies ();
715 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
718 /* Create a set of Connection objects that map
719 to the physical outputs currently available
724 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
726 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
728 Connection* c = new OutputConnection (buf, true);
731 c->add_connection (0, _engine.get_nth_physical_output (np));
736 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
738 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
740 Connection* c = new InputConnection (buf, true);
743 c->add_connection (0, _engine.get_nth_physical_input (np));
750 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
752 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
754 Connection* c = new OutputConnection (buf, true);
758 c->add_connection (0, _engine.get_nth_physical_output (np));
759 c->add_connection (1, _engine.get_nth_physical_output (np+1));
764 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
766 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
768 Connection* c = new InputConnection (buf, true);
772 c->add_connection (0, _engine.get_nth_physical_input (np));
773 c->add_connection (1, _engine.get_nth_physical_input (np+1));
782 /* create master/control ports */
787 /* force the master to ignore any later call to this */
789 if (_master_out->pending_state_node) {
790 _master_out->ports_became_legal();
793 /* no panner resets till we are through */
795 _master_out->defer_pan_reset ();
797 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
798 if (_master_out->add_input_port ("", this)) {
799 error << _("cannot setup master inputs")
805 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
806 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
807 error << _("cannot setup master outputs")
814 _master_out->allow_pan_reset ();
818 Connection* c = new OutputConnection (_("Master Out"), true);
820 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
822 c->add_connection ((int) n, _master_out->input(n)->name());
829 /* catch up on send+insert cnts */
833 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
836 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
837 if (id > insert_cnt) {
845 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
848 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
856 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
858 /* hook us up to the engine */
860 _engine.set_session (this);
865 osc->set_session (*this);
868 _state_of_the_state = Clean;
870 DirtyChanged (); /* EMIT SIGNAL */
874 Session::hookup_io ()
876 /* stop graph reordering notifications from
877 causing resorts, etc.
880 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
882 if (auditioner == 0) {
884 /* we delay creating the auditioner till now because
885 it makes its own connections to ports.
886 the engine has to be running for this to work.
890 auditioner.reset (new Auditioner (*this));
893 catch (failed_constructor& err) {
894 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
898 /* Tell all IO objects to create their ports */
905 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
906 if (_control_out->add_input_port ("", this)) {
907 error << _("cannot setup control inputs")
913 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
914 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
915 error << _("cannot set up master outputs")
923 /* Tell all IO objects to connect themselves together */
925 IO::enable_connecting ();
927 /* Now reset all panners */
929 IO::reset_panners ();
931 /* Anyone who cares about input state, wake up and do something */
933 IOConnectionsComplete (); /* EMIT SIGNAL */
935 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
937 /* now handle the whole enchilada as if it was one
943 /* update mixer solo state */
949 Session::playlist_length_changed ()
951 /* we can't just increase end_location->end() if pl->get_maximum_extent()
952 if larger. if the playlist used to be the longest playlist,
953 and its now shorter, we have to decrease end_location->end(). hence,
954 we have to iterate over all diskstreams and check the
955 playlists currently in use.
961 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
963 boost::shared_ptr<Playlist> playlist;
965 if ((playlist = dstream->playlist()) != 0) {
966 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
969 /* see comment in playlist_length_changed () */
974 Session::record_enabling_legal () const
976 /* this used to be in here, but survey says.... we don't need to restrict it */
977 // if (record_status() == Recording) {
981 if (Config->get_all_safe()) {
988 Session::reset_input_monitor_state ()
990 if (transport_rolling()) {
992 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
994 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
995 if ((*i)->record_enabled ()) {
996 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
997 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1001 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1003 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1004 if ((*i)->record_enabled ()) {
1005 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1006 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1013 Session::auto_punch_start_changed (Location* location)
1015 replace_event (Event::PunchIn, location->start());
1017 if (get_record_enabled() && Config->get_punch_in()) {
1018 /* capture start has been changed, so save new pending state */
1019 save_state ("", true);
1024 Session::auto_punch_end_changed (Location* location)
1026 nframes_t when_to_stop = location->end();
1027 // when_to_stop += _worst_output_latency + _worst_input_latency;
1028 replace_event (Event::PunchOut, when_to_stop);
1032 Session::auto_punch_changed (Location* location)
1034 nframes_t when_to_stop = location->end();
1036 replace_event (Event::PunchIn, location->start());
1037 //when_to_stop += _worst_output_latency + _worst_input_latency;
1038 replace_event (Event::PunchOut, when_to_stop);
1042 Session::auto_loop_changed (Location* location)
1044 replace_event (Event::AutoLoop, location->end(), location->start());
1046 if (transport_rolling() && play_loop) {
1048 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1050 if (_transport_frame > location->end()) {
1051 // relocate to beginning of loop
1052 clear_events (Event::LocateRoll);
1054 request_locate (location->start(), true);
1057 else if (Config->get_seamless_loop() && !loop_changing) {
1059 // schedule a locate-roll to refill the diskstreams at the
1060 // previous loop end
1061 loop_changing = true;
1063 if (location->end() > last_loopend) {
1064 clear_events (Event::LocateRoll);
1065 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1072 last_loopend = location->end();
1077 Session::set_auto_punch_location (Location* location)
1081 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1082 auto_punch_start_changed_connection.disconnect();
1083 auto_punch_end_changed_connection.disconnect();
1084 auto_punch_changed_connection.disconnect();
1085 existing->set_auto_punch (false, this);
1086 remove_event (existing->start(), Event::PunchIn);
1087 clear_events (Event::PunchOut);
1088 auto_punch_location_changed (0);
1093 if (location == 0) {
1097 if (location->end() <= location->start()) {
1098 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1102 auto_punch_start_changed_connection.disconnect();
1103 auto_punch_end_changed_connection.disconnect();
1104 auto_punch_changed_connection.disconnect();
1106 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1107 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1108 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1110 location->set_auto_punch (true, this);
1111 auto_punch_location_changed (location);
1115 Session::set_auto_loop_location (Location* location)
1119 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1120 auto_loop_start_changed_connection.disconnect();
1121 auto_loop_end_changed_connection.disconnect();
1122 auto_loop_changed_connection.disconnect();
1123 existing->set_auto_loop (false, this);
1124 remove_event (existing->end(), Event::AutoLoop);
1125 auto_loop_location_changed (0);
1130 if (location == 0) {
1134 if (location->end() <= location->start()) {
1135 error << _("Session: you can't use a mark for auto loop") << endmsg;
1139 last_loopend = location->end();
1141 auto_loop_start_changed_connection.disconnect();
1142 auto_loop_end_changed_connection.disconnect();
1143 auto_loop_changed_connection.disconnect();
1145 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1146 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1147 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1149 location->set_auto_loop (true, this);
1150 auto_loop_location_changed (location);
1154 Session::locations_added (Location* ignored)
1160 Session::locations_changed ()
1162 _locations.apply (*this, &Session::handle_locations_changed);
1166 Session::handle_locations_changed (Locations::LocationList& locations)
1168 Locations::LocationList::iterator i;
1170 bool set_loop = false;
1171 bool set_punch = false;
1173 for (i = locations.begin(); i != locations.end(); ++i) {
1177 if (location->is_auto_punch()) {
1178 set_auto_punch_location (location);
1181 if (location->is_auto_loop()) {
1182 set_auto_loop_location (location);
1189 set_auto_loop_location (0);
1192 set_auto_punch_location (0);
1199 Session::enable_record ()
1201 /* XXX really atomic compare+swap here */
1202 if (g_atomic_int_get (&_record_status) != Recording) {
1203 g_atomic_int_set (&_record_status, Recording);
1204 _last_record_location = _transport_frame;
1205 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1207 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1208 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1209 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1210 if ((*i)->record_enabled ()) {
1211 (*i)->monitor_input (true);
1216 RecordStateChanged ();
1221 Session::disable_record (bool rt_context, bool force)
1225 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1227 if (!Config->get_latched_record_enable () || force) {
1228 g_atomic_int_set (&_record_status, Disabled);
1230 if (rs == Recording) {
1231 g_atomic_int_set (&_record_status, Enabled);
1235 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1237 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1238 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1240 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1241 if ((*i)->record_enabled ()) {
1242 (*i)->monitor_input (false);
1247 RecordStateChanged (); /* emit signal */
1250 remove_pending_capture_state ();
1256 Session::step_back_from_record ()
1258 g_atomic_int_set (&_record_status, Enabled);
1260 if (Config->get_monitoring_model() == HardwareMonitoring) {
1261 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1263 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1264 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1265 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1266 (*i)->monitor_input (false);
1273 Session::maybe_enable_record ()
1275 g_atomic_int_set (&_record_status, Enabled);
1277 /* this function is currently called from somewhere other than an RT thread.
1278 this save_state() call therefore doesn't impact anything.
1281 save_state ("", true);
1283 if (_transport_speed) {
1284 if (!Config->get_punch_in()) {
1288 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1289 RecordStateChanged (); /* EMIT SIGNAL */
1296 Session::audible_frame () const
1302 /* the first of these two possible settings for "offset"
1303 mean that the audible frame is stationary until
1304 audio emerges from the latency compensation
1307 the second means that the audible frame is stationary
1308 until audio would emerge from a physical port
1309 in the absence of any plugin latency compensation
1312 offset = _worst_output_latency;
1314 if (offset > current_block_size) {
1315 offset -= current_block_size;
1317 /* XXX is this correct? if we have no external
1318 physical connections and everything is internal
1319 then surely this is zero? still, how
1320 likely is that anyway?
1322 offset = current_block_size;
1325 if (synced_to_jack()) {
1326 tf = _engine.transport_frame();
1328 tf = _transport_frame;
1331 if (_transport_speed == 0) {
1341 if (!non_realtime_work_pending()) {
1345 /* take latency into account */
1354 Session::set_frame_rate (nframes_t frames_per_second)
1356 /** \fn void Session::set_frame_size(nframes_t)
1357 the AudioEngine object that calls this guarantees
1358 that it will not be called while we are also in
1359 ::process(). Its fine to do things that block
1363 _base_frame_rate = frames_per_second;
1367 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1369 // XXX we need some equivalent to this, somehow
1370 // SndFileSource::setup_standard_crossfades (frames_per_second);
1374 /* XXX need to reset/reinstantiate all LADSPA plugins */
1378 Session::set_block_size (nframes_t nframes)
1380 /* the AudioEngine guarantees
1381 that it will not be called while we are also in
1382 ::process(). It is therefore fine to do things that block
1387 vector<Sample*>::iterator i;
1390 current_block_size = nframes;
1392 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1396 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1400 _passthru_buffers.clear ();
1401 _silent_buffers.clear ();
1403 ensure_passthru_buffers (np);
1405 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1409 #ifdef NO_POSIX_MEMALIGN
1410 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1412 posix_memalign((void **)&buf,16,current_block_size * 4);
1416 memset (*i, 0, sizeof (Sample) * current_block_size);
1420 if (_gain_automation_buffer) {
1421 delete [] _gain_automation_buffer;
1423 _gain_automation_buffer = new gain_t[nframes];
1425 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1427 boost::shared_ptr<RouteList> r = routes.reader ();
1429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1430 (*i)->set_block_size (nframes);
1433 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1434 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1435 (*i)->set_block_size (nframes);
1438 set_worst_io_latencies ();
1443 Session::set_default_fade (float steepness, float fade_msecs)
1446 nframes_t fade_frames;
1448 /* Don't allow fade of less 1 frame */
1450 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1457 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1461 default_fade_msecs = fade_msecs;
1462 default_fade_steepness = steepness;
1465 // jlc, WTF is this!
1466 Glib::RWLock::ReaderLock lm (route_lock);
1467 AudioRegion::set_default_fade (steepness, fade_frames);
1472 /* XXX have to do this at some point */
1473 /* foreach region using default fade, reset, then
1474 refill_all_diskstream_buffers ();
1479 struct RouteSorter {
1480 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1481 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1483 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1486 if (r1->fed_by.empty()) {
1487 if (r2->fed_by.empty()) {
1488 /* no ardour-based connections inbound to either route. just use signal order */
1489 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1491 /* r2 has connections, r1 does not; run r1 early */
1495 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1502 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1504 shared_ptr<Route> r2;
1506 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1507 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1511 /* make a copy of the existing list of routes that feed r1 */
1513 set<shared_ptr<Route> > existing = r1->fed_by;
1515 /* for each route that feeds r1, recurse, marking it as feeding
1519 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1522 /* r2 is a route that feeds r1 which somehow feeds base. mark
1523 base as being fed by r2
1526 rbase->fed_by.insert (r2);
1530 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1534 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1538 /* now recurse, so that we can mark base as being fed by
1539 all routes that feed r2
1542 trace_terminal (r2, rbase);
1549 Session::resort_routes ()
1551 /* don't do anything here with signals emitted
1552 by Routes while we are being destroyed.
1555 if (_state_of_the_state & Deletion) {
1562 RCUWriter<RouteList> writer (routes);
1563 shared_ptr<RouteList> r = writer.get_copy ();
1564 resort_routes_using (r);
1565 /* writer goes out of scope and forces update */
1570 Session::resort_routes_using (shared_ptr<RouteList> r)
1572 RouteList::iterator i, j;
1574 for (i = r->begin(); i != r->end(); ++i) {
1576 (*i)->fed_by.clear ();
1578 for (j = r->begin(); j != r->end(); ++j) {
1580 /* although routes can feed themselves, it will
1581 cause an endless recursive descent if we
1582 detect it. so don't bother checking for
1590 if ((*j)->feeds (*i)) {
1591 (*i)->fed_by.insert (*j);
1596 for (i = r->begin(); i != r->end(); ++i) {
1597 trace_terminal (*i, *i);
1603 /* don't leave dangling references to routes in Route::fed_by */
1605 for (i = r->begin(); i != r->end(); ++i) {
1606 (*i)->fed_by.clear ();
1610 cerr << "finished route resort\n";
1612 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1613 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1620 list<boost::shared_ptr<AudioTrack> >
1621 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1623 char track_name[32];
1624 uint32_t track_id = 0;
1626 uint32_t channels_used = 0;
1628 RouteList new_routes;
1629 list<boost::shared_ptr<AudioTrack> > ret;
1630 uint32_t control_id;
1632 /* count existing audio tracks */
1635 shared_ptr<RouteList> r = routes.reader ();
1637 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1638 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1639 if (!(*i)->hidden()) {
1641 channels_used += (*i)->n_inputs();
1647 vector<string> physinputs;
1648 vector<string> physoutputs;
1649 uint32_t nphysical_in;
1650 uint32_t nphysical_out;
1652 _engine.get_physical_outputs (physoutputs);
1653 _engine.get_physical_inputs (physinputs);
1654 control_id = ntracks() + nbusses() + 1;
1658 /* check for duplicate route names, since we might have pre-existing
1659 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1660 save, close,restart,add new route - first named route is now
1668 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1670 if (route_by_name (track_name) == 0) {
1674 } while (track_id < (UINT_MAX-1));
1676 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1677 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1682 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1683 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1689 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1691 if (track->ensure_io (input_channels, output_channels, false, this)) {
1692 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1693 input_channels, output_channels)
1698 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1702 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1703 port = physinputs[(channels_used+x)%nphysical_in];
1706 if (port.length() && track->connect_input (track->input (x), port, this)) {
1712 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1716 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1717 port = physoutputs[(channels_used+x)%nphysical_out];
1718 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1720 port = _master_out->input (x%_master_out->n_inputs())->name();
1724 if (port.length() && track->connect_output (track->output (x), port, this)) {
1729 channels_used += track->n_inputs ();
1732 vector<string> cports;
1733 uint32_t ni = _control_out->n_inputs();
1735 for (n = 0; n < ni; ++n) {
1736 cports.push_back (_control_out->input(n)->name());
1739 track->set_control_outs (cports);
1742 // assert (current_thread != RT_thread)
1744 track->audio_diskstream()->non_realtime_input_change();
1746 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1747 track->set_remote_control_id (control_id);
1750 new_routes.push_back (track);
1751 ret.push_back (track);
1754 catch (failed_constructor &err) {
1755 error << _("Session: could not create new audio track.") << endmsg;
1756 // XXX should we delete the tracks already created?
1764 if (!new_routes.empty()) {
1765 add_routes (new_routes, false);
1766 save_state (_current_snapshot_name);
1773 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1776 uint32_t bus_id = 1;
1780 uint32_t control_id;
1782 /* count existing audio busses */
1785 shared_ptr<RouteList> r = routes.reader ();
1787 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1788 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1789 if (!(*i)->hidden()) {
1796 vector<string> physinputs;
1797 vector<string> physoutputs;
1799 _engine.get_physical_outputs (physoutputs);
1800 _engine.get_physical_inputs (physinputs);
1801 control_id = ntracks() + nbusses() + 1;
1808 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1810 if (route_by_name (bus_name) == 0) {
1814 } while (bus_id < (UINT_MAX-1));
1817 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1819 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1820 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1821 input_channels, output_channels)
1825 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1829 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1830 port = physinputs[((n+x)%n_physical_inputs)];
1833 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1838 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1842 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1843 port = physoutputs[((n+x)%n_physical_outputs)];
1844 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1846 port = _master_out->input (x%_master_out->n_inputs())->name();
1850 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1856 vector<string> cports;
1857 uint32_t ni = _control_out->n_inputs();
1859 for (uint32_t n = 0; n < ni; ++n) {
1860 cports.push_back (_control_out->input(n)->name());
1862 bus->set_control_outs (cports);
1865 bus->set_remote_control_id (control_id);
1868 ret.push_back (bus);
1872 catch (failed_constructor &err) {
1873 error << _("Session: could not create new audio route.") << endmsg;
1882 add_routes (ret, false);
1883 save_state (_current_snapshot_name);
1891 Session::add_routes (RouteList& new_routes, bool save)
1894 RCUWriter<RouteList> writer (routes);
1895 shared_ptr<RouteList> r = writer.get_copy ();
1896 r->insert (r->end(), new_routes.begin(), new_routes.end());
1897 resort_routes_using (r);
1900 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1902 boost::weak_ptr<Route> wpr (*x);
1904 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1905 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1906 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1907 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1909 if ((*x)->master()) {
1913 if ((*x)->control()) {
1914 _control_out = (*x);
1921 save_state (_current_snapshot_name);
1924 RouteAdded (new_routes); /* EMIT SIGNAL */
1928 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1930 /* need to do this in case we're rolling at the time, to prevent false underruns */
1931 dstream->do_refill_with_alloc();
1934 RCUWriter<DiskstreamList> writer (diskstreams);
1935 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1936 ds->push_back (dstream);
1939 dstream->set_block_size (current_block_size);
1941 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1942 /* this will connect to future changes, and check the current length */
1943 diskstream_playlist_changed (dstream);
1945 dstream->prepare ();
1949 Session::remove_route (shared_ptr<Route> route)
1952 RCUWriter<RouteList> writer (routes);
1953 shared_ptr<RouteList> rs = writer.get_copy ();
1957 /* deleting the master out seems like a dumb
1958 idea, but its more of a UI policy issue
1962 if (route == _master_out) {
1963 _master_out = shared_ptr<Route> ();
1966 if (route == _control_out) {
1967 _control_out = shared_ptr<Route> ();
1969 /* cancel control outs for all routes */
1971 vector<string> empty;
1973 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1974 (*r)->set_control_outs (empty);
1978 update_route_solo_state ();
1980 /* writer goes out of scope, forces route list update */
1983 // FIXME: audio specific
1985 boost::shared_ptr<AudioDiskstream> ds;
1987 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1988 ds = at->audio_diskstream();
1994 RCUWriter<DiskstreamList> dsl (diskstreams);
1995 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2000 find_current_end ();
2002 update_latency_compensation (false, false);
2005 // We need to disconnect the routes inputs and outputs
2006 route->disconnect_inputs(NULL);
2007 route->disconnect_outputs(NULL);
2009 /* get rid of it from the dead wood collection in the route list manager */
2011 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2015 /* try to cause everyone to drop their references */
2017 route->drop_references ();
2019 /* save the new state of the world */
2021 if (save_state (_current_snapshot_name)) {
2022 save_history (_current_snapshot_name);
2027 Session::route_mute_changed (void* src)
2033 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2035 if (solo_update_disabled) {
2041 boost::shared_ptr<Route> route = wpr.lock ();
2044 /* should not happen */
2045 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2049 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2051 shared_ptr<RouteList> r = routes.reader ();
2053 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2055 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2059 /* don't mess with busses */
2061 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2067 /* don't mess with tracks */
2069 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2074 if ((*i) != route &&
2075 ((*i)->mix_group () == 0 ||
2076 (*i)->mix_group () != route->mix_group () ||
2077 !route->mix_group ()->is_active())) {
2079 if ((*i)->soloed()) {
2081 /* if its already soloed, and solo latching is enabled,
2082 then leave it as it is.
2085 if (Config->get_solo_latched()) {
2092 solo_update_disabled = true;
2093 (*i)->set_solo (false, src);
2094 solo_update_disabled = false;
2098 bool something_soloed = false;
2099 bool same_thing_soloed = false;
2100 bool signal = false;
2102 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2103 if ((*i)->soloed()) {
2104 something_soloed = true;
2105 if (dynamic_cast<AudioTrack*>((*i).get())) {
2107 same_thing_soloed = true;
2112 same_thing_soloed = true;
2120 if (something_soloed != currently_soloing) {
2122 currently_soloing = something_soloed;
2125 modify_solo_mute (is_track, same_thing_soloed);
2128 SoloActive (currently_soloing); /* EMIT SIGNAL */
2131 SoloChanged (); /* EMIT SIGNAL */
2137 Session::update_route_solo_state ()
2140 bool is_track = false;
2141 bool signal = false;
2143 /* caller must hold RouteLock */
2145 /* this is where we actually implement solo by changing
2146 the solo mute setting of each track.
2149 shared_ptr<RouteList> r = routes.reader ();
2151 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2152 if ((*i)->soloed()) {
2154 if (dynamic_cast<AudioTrack*>((*i).get())) {
2161 if (mute != currently_soloing) {
2163 currently_soloing = mute;
2166 if (!is_track && !mute) {
2168 /* nothing is soloed */
2170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2171 (*i)->set_solo_mute (false);
2181 modify_solo_mute (is_track, mute);
2184 SoloActive (currently_soloing);
2189 Session::modify_solo_mute (bool is_track, bool mute)
2191 shared_ptr<RouteList> r = routes.reader ();
2193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2197 /* only alter track solo mute */
2199 if (dynamic_cast<AudioTrack*>((*i).get())) {
2200 if ((*i)->soloed()) {
2201 (*i)->set_solo_mute (!mute);
2203 (*i)->set_solo_mute (mute);
2209 /* only alter bus solo mute */
2211 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2213 if ((*i)->soloed()) {
2215 (*i)->set_solo_mute (false);
2219 /* don't mute master or control outs
2220 in response to another bus solo
2223 if ((*i) != _master_out &&
2224 (*i) != _control_out) {
2225 (*i)->set_solo_mute (mute);
2236 Session::catch_up_on_solo ()
2238 /* this is called after set_state() to catch the full solo
2239 state, which can't be correctly determined on a per-route
2240 basis, but needs the global overview that only the session
2243 update_route_solo_state();
2247 Session::route_by_name (string name)
2249 shared_ptr<RouteList> r = routes.reader ();
2251 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2252 if ((*i)->name() == name) {
2257 return shared_ptr<Route> ((Route*) 0);
2261 Session::route_by_id (PBD::ID id)
2263 shared_ptr<RouteList> r = routes.reader ();
2265 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2266 if ((*i)->id() == id) {
2271 return shared_ptr<Route> ((Route*) 0);
2275 Session::route_by_remote_id (uint32_t id)
2277 shared_ptr<RouteList> r = routes.reader ();
2279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2280 if ((*i)->remote_control_id() == id) {
2285 return shared_ptr<Route> ((Route*) 0);
2289 Session::find_current_end ()
2291 if (_state_of_the_state & Loading) {
2295 nframes_t max = get_maximum_extent ();
2297 if (max > end_location->end()) {
2298 end_location->set_end (max);
2300 DurationChanged(); /* EMIT SIGNAL */
2305 Session::get_maximum_extent () const
2310 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2312 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2313 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2314 if ((me = pl->get_maximum_extent()) > max) {
2322 boost::shared_ptr<Diskstream>
2323 Session::diskstream_by_name (string name)
2325 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2327 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2328 if ((*i)->name() == name) {
2333 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2336 boost::shared_ptr<Diskstream>
2337 Session::diskstream_by_id (const PBD::ID& id)
2339 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2341 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2342 if ((*i)->id() == id) {
2347 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2350 /* AudioRegion management */
2353 Session::new_region_name (string old)
2355 string::size_type last_period;
2357 string::size_type len = old.length() + 64;
2360 if ((last_period = old.find_last_of ('.')) == string::npos) {
2362 /* no period present - add one explicitly */
2365 last_period = old.length() - 1;
2370 number = atoi (old.substr (last_period+1).c_str());
2374 while (number < (UINT_MAX-1)) {
2376 AudioRegionList::const_iterator i;
2381 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2384 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2385 if (i->second->name() == sbuf) {
2390 if (i == audio_regions.end()) {
2395 if (number != (UINT_MAX-1)) {
2399 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2404 Session::region_name (string& result, string base, bool newlevel) const
2411 Glib::Mutex::Lock lm (region_lock);
2413 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2421 /* XXX this is going to be slow. optimize me later */
2426 string::size_type pos;
2428 pos = base.find_last_of ('.');
2430 /* pos may be npos, but then we just use entire base */
2432 subbase = base.substr (0, pos);
2436 bool name_taken = true;
2439 Glib::Mutex::Lock lm (region_lock);
2441 for (int n = 1; n < 5000; ++n) {
2444 snprintf (buf, sizeof (buf), ".%d", n);
2449 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2450 if (i->second->name() == result) {
2463 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2471 Session::add_region (boost::shared_ptr<Region> region)
2473 boost::shared_ptr<AudioRegion> ar;
2474 boost::shared_ptr<AudioRegion> oar;
2478 Glib::Mutex::Lock lm (region_lock);
2480 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2482 AudioRegionList::iterator x;
2484 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2486 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2488 if (ar->region_list_equivalent (oar)) {
2493 if (x == audio_regions.end()) {
2495 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2497 entry.first = region->id();
2500 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2512 fatal << _("programming error: ")
2513 << X_("unknown region type passed to Session::add_region()")
2520 /* mark dirty because something has changed even if we didn't
2521 add the region to the region list.
2527 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2528 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2529 AudioRegionAdded (ar); /* EMIT SIGNAL */
2534 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2536 boost::shared_ptr<Region> region (weak_region.lock ());
2542 if (what_changed & Region::HiddenChanged) {
2543 /* relay hidden changes */
2544 RegionHiddenChange (region);
2549 Session::remove_region (boost::weak_ptr<Region> weak_region)
2551 AudioRegionList::iterator i;
2552 boost::shared_ptr<Region> region (weak_region.lock ());
2558 boost::shared_ptr<AudioRegion> ar;
2559 bool removed = false;
2562 Glib::Mutex::Lock lm (region_lock);
2564 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2565 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2566 audio_regions.erase (i);
2572 fatal << _("programming error: ")
2573 << X_("unknown region type passed to Session::remove_region()")
2579 /* mark dirty because something has changed even if we didn't
2580 remove the region from the region list.
2586 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2590 boost::shared_ptr<AudioRegion>
2591 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2593 AudioRegionList::iterator i;
2594 boost::shared_ptr<AudioRegion> region;
2595 Glib::Mutex::Lock lm (region_lock);
2597 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2601 if (region->whole_file()) {
2603 if (child->source_equivalent (region)) {
2609 return boost::shared_ptr<AudioRegion> ();
2613 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2615 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2616 (*i)->get_region_list_equivalent_regions (region, result);
2620 Session::destroy_region (boost::shared_ptr<Region> region)
2622 vector<boost::shared_ptr<Source> > srcs;
2625 boost::shared_ptr<AudioRegion> aregion;
2627 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2631 if (aregion->playlist()) {
2632 aregion->playlist()->destroy_region (region);
2635 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2636 srcs.push_back (aregion->source (n));
2640 region->drop_references ();
2642 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2644 if (!(*i)->used()) {
2645 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2648 (afs)->mark_for_remove ();
2651 (*i)->drop_references ();
2653 cerr << "source was not used by any playlist\n";
2661 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2663 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2664 destroy_region (*i);
2670 Session::remove_last_capture ()
2672 list<boost::shared_ptr<Region> > r;
2674 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2676 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2677 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2680 r.insert (r.end(), l.begin(), l.end());
2685 destroy_regions (r);
2690 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2696 /* Source Management */
2699 Session::add_source (boost::shared_ptr<Source> source)
2701 boost::shared_ptr<AudioFileSource> afs;
2703 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2705 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2706 pair<AudioSourceList::iterator,bool> result;
2708 entry.first = source->id();
2712 Glib::Mutex::Lock lm (audio_source_lock);
2713 result = audio_sources.insert (entry);
2716 if (result.second) {
2717 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2725 Session::remove_source (boost::weak_ptr<Source> src)
2727 AudioSourceList::iterator i;
2728 boost::shared_ptr<Source> source = src.lock();
2735 Glib::Mutex::Lock lm (audio_source_lock);
2737 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2738 audio_sources.erase (i);
2742 if (!_state_of_the_state & InCleanup) {
2744 /* save state so we don't end up with a session file
2745 referring to non-existent sources.
2748 save_state (_current_snapshot_name);
2752 boost::shared_ptr<Source>
2753 Session::source_by_id (const PBD::ID& id)
2755 Glib::Mutex::Lock lm (audio_source_lock);
2756 AudioSourceList::iterator i;
2757 boost::shared_ptr<Source> source;
2759 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2763 /* XXX search MIDI or other searches here */
2769 Session::peak_path_from_audio_path (string audio_path) const
2774 res += PBD::basename_nosuffix (audio_path);
2781 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2784 string old_basename = PBD::basename_nosuffix (oldname);
2785 string new_legalized = legalize_for_path (newname);
2787 /* note: we know (or assume) the old path is already valid */
2791 /* destructive file sources have a name of the form:
2793 /path/to/Tnnnn-NAME(%[LR])?.wav
2795 the task here is to replace NAME with the new name.
2798 /* find last slash */
2802 string::size_type slash;
2803 string::size_type dash;
2805 if ((slash = path.find_last_of ('/')) == string::npos) {
2809 dir = path.substr (0, slash+1);
2811 /* '-' is not a legal character for the NAME part of the path */
2813 if ((dash = path.find_last_of ('-')) == string::npos) {
2817 prefix = path.substr (slash+1, dash-(slash+1));
2822 path += new_legalized;
2823 path += ".wav"; /* XXX gag me with a spoon */
2827 /* non-destructive file sources have a name of the form:
2829 /path/to/NAME-nnnnn(%[LR])?.wav
2831 the task here is to replace NAME with the new name.
2836 string::size_type slash;
2837 string::size_type dash;
2838 string::size_type postfix;
2840 /* find last slash */
2842 if ((slash = path.find_last_of ('/')) == string::npos) {
2846 dir = path.substr (0, slash+1);
2848 /* '-' is not a legal character for the NAME part of the path */
2850 if ((dash = path.find_last_of ('-')) == string::npos) {
2854 suffix = path.substr (dash+1);
2856 // Suffix is now everything after the dash. Now we need to eliminate
2857 // the nnnnn part, which is done by either finding a '%' or a '.'
2859 postfix = suffix.find_last_of ("%");
2860 if (postfix == string::npos) {
2861 postfix = suffix.find_last_of ('.');
2864 if (postfix != string::npos) {
2865 suffix = suffix.substr (postfix);
2867 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2871 const uint32_t limit = 10000;
2872 char buf[PATH_MAX+1];
2874 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2876 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2878 if (access (buf, F_OK) != 0) {
2886 error << "FATAL ERROR! Could not find a " << endl;
2895 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2899 char buf[PATH_MAX+1];
2900 const uint32_t limit = 10000;
2904 legalized = legalize_for_path (name);
2906 /* find a "version" of the file name that doesn't exist in
2907 any of the possible directories.
2910 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2912 vector<space_and_path>::iterator i;
2913 uint32_t existing = 0;
2915 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2919 spath += sound_dir (false);
2923 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2924 } else if (nchan == 2) {
2926 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2928 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2930 } else if (nchan < 26) {
2931 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2933 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2942 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2943 } else if (nchan == 2) {
2945 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2947 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2949 } else if (nchan < 26) {
2950 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2952 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2956 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2962 if (existing == 0) {
2967 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2969 throw failed_constructor();
2973 /* we now have a unique name for the file, but figure out where to
2979 spath = discover_best_sound_dir ();
2982 string::size_type pos = foo.find_last_of ('/');
2984 if (pos == string::npos) {
2987 spath += foo.substr (pos + 1);
2993 boost::shared_ptr<AudioFileSource>
2994 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2996 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2997 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3000 /* Playlist management */
3002 boost::shared_ptr<Playlist>
3003 Session::playlist_by_name (string name)
3005 Glib::Mutex::Lock lm (playlist_lock);
3006 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3007 if ((*i)->name() == name) {
3011 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3012 if ((*i)->name() == name) {
3017 return boost::shared_ptr<Playlist>();
3021 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3023 if (playlist->hidden()) {
3028 Glib::Mutex::Lock lm (playlist_lock);
3029 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3030 playlists.insert (playlists.begin(), playlist);
3031 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3032 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3038 PlaylistAdded (playlist); /* EMIT SIGNAL */
3042 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3045 Glib::Mutex::Lock lm (playlist_lock);
3046 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3049 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3056 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3058 boost::shared_ptr<Playlist> pl(wpl.lock());
3064 PlaylistList::iterator x;
3067 /* its not supposed to be visible */
3072 Glib::Mutex::Lock lm (playlist_lock);
3076 unused_playlists.insert (pl);
3078 if ((x = playlists.find (pl)) != playlists.end()) {
3079 playlists.erase (x);
3085 playlists.insert (pl);
3087 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3088 unused_playlists.erase (x);
3095 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3097 if (_state_of_the_state & Deletion) {
3101 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3108 Glib::Mutex::Lock lm (playlist_lock);
3110 PlaylistList::iterator i;
3112 i = find (playlists.begin(), playlists.end(), playlist);
3113 if (i != playlists.end()) {
3114 playlists.erase (i);
3117 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3118 if (i != unused_playlists.end()) {
3119 unused_playlists.erase (i);
3126 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3130 Session::set_audition (boost::shared_ptr<Region> r)
3132 pending_audition_region = r;
3133 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3134 schedule_butler_transport_work ();
3138 Session::audition_playlist ()
3140 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3141 ev->region.reset ();
3146 Session::non_realtime_set_audition ()
3148 if (!pending_audition_region) {
3149 auditioner->audition_current_playlist ();
3151 auditioner->audition_region (pending_audition_region);
3152 pending_audition_region.reset ();
3154 AuditionActive (true); /* EMIT SIGNAL */
3158 Session::audition_region (boost::shared_ptr<Region> r)
3160 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3166 Session::cancel_audition ()
3168 if (auditioner->active()) {
3169 auditioner->cancel_audition ();
3170 AuditionActive (false); /* EMIT SIGNAL */
3175 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3177 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3181 Session::remove_empty_sounds ()
3183 PathScanner scanner;
3185 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3187 Glib::Mutex::Lock lm (audio_source_lock);
3189 regex_t compiled_tape_track_pattern;
3192 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3196 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3198 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3202 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3204 /* never remove files that appear to be a tape track */
3206 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3211 if (AudioFileSource::is_empty (*this, *(*i))) {
3213 unlink ((*i)->c_str());
3215 string peak_path = peak_path_from_audio_path (**i);
3216 unlink (peak_path.c_str());
3222 delete possible_audiofiles;
3226 Session::is_auditioning () const
3228 /* can be called before we have an auditioner object */
3230 return auditioner->active();
3237 Session::set_all_solo (bool yn)
3239 shared_ptr<RouteList> r = routes.reader ();
3241 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3242 if (!(*i)->hidden()) {
3243 (*i)->set_solo (yn, this);
3251 Session::set_all_mute (bool yn)
3253 shared_ptr<RouteList> r = routes.reader ();
3255 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3256 if (!(*i)->hidden()) {
3257 (*i)->set_mute (yn, this);
3265 Session::n_diskstreams () const
3269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3271 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3272 if (!(*i)->hidden()) {
3280 Session::graph_reordered ()
3282 /* don't do this stuff if we are setting up connections
3283 from a set_state() call.
3286 if (_state_of_the_state & InitialConnecting) {
3290 /* every track/bus asked for this to be handled but it was deferred because
3291 we were connecting. do it now.
3294 request_input_change_handling ();
3298 /* force all diskstreams to update their capture offset values to
3299 reflect any changes in latencies within the graph.
3302 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3304 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3305 (*i)->set_capture_offset ();
3310 Session::record_disenable_all ()
3312 record_enable_change_all (false);
3316 Session::record_enable_all ()
3318 record_enable_change_all (true);
3322 Session::record_enable_change_all (bool yn)
3324 shared_ptr<RouteList> r = routes.reader ();
3326 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3329 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3330 at->set_record_enable (yn, this);
3334 /* since we don't keep rec-enable state, don't mark session dirty */
3338 Session::add_redirect (Redirect* redirect)
3342 PortInsert* port_insert;
3343 PluginInsert* plugin_insert;
3345 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3346 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3347 _port_inserts.insert (_port_inserts.begin(), port_insert);
3348 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3349 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3351 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3354 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3355 _sends.insert (_sends.begin(), send);
3357 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3361 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3367 Session::remove_redirect (Redirect* redirect)
3371 PortInsert* port_insert;
3372 PluginInsert* plugin_insert;
3374 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3375 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3376 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3377 if (x != _port_inserts.end()) {
3378 insert_bitset[port_insert->bit_slot()] = false;
3379 _port_inserts.erase (x);
3381 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3382 _plugin_inserts.remove (plugin_insert);
3384 fatal << string_compose (_("programming error: %1"),
3385 X_("unknown type of Insert deleted!"))
3389 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3390 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3391 if (x != _sends.end()) {
3392 send_bitset[send->bit_slot()] = false;
3396 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3404 Session::available_capture_duration ()
3406 float sample_bytes_on_disk = 4.0; // keep gcc happy
3408 switch (Config->get_native_file_data_format()) {
3410 sample_bytes_on_disk = 4;
3414 sample_bytes_on_disk = 3;
3418 /* impossible, but keep some gcc versions happy */
3419 fatal << string_compose (_("programming error: %1"),
3420 X_("illegal native file data format"))
3425 double scale = 4096.0 / sample_bytes_on_disk;
3427 if (_total_free_4k_blocks * scale > (double) max_frames) {
3431 return (nframes_t) floor (_total_free_4k_blocks * scale);
3435 Session::add_connection (ARDOUR::Connection* connection)
3438 Glib::Mutex::Lock guard (connection_lock);
3439 _connections.push_back (connection);
3442 ConnectionAdded (connection); /* EMIT SIGNAL */
3448 Session::remove_connection (ARDOUR::Connection* connection)
3450 bool removed = false;
3453 Glib::Mutex::Lock guard (connection_lock);
3454 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3456 if (i != _connections.end()) {
3457 _connections.erase (i);
3463 ConnectionRemoved (connection); /* EMIT SIGNAL */
3469 ARDOUR::Connection *
3470 Session::connection_by_name (string name) const
3472 Glib::Mutex::Lock lm (connection_lock);
3474 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3475 if ((*i)->name() == name) {
3484 Session::tempo_map_changed (Change ignored)
3491 Session::ensure_passthru_buffers (uint32_t howmany)
3493 while (howmany > _passthru_buffers.size()) {
3495 #ifdef NO_POSIX_MEMALIGN
3496 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3498 posix_memalign((void **)&p,16,current_block_size * 4);
3500 _passthru_buffers.push_back (p);
3504 #ifdef NO_POSIX_MEMALIGN
3505 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3507 posix_memalign((void **)&p,16,current_block_size * 4);
3509 memset (p, 0, sizeof (Sample) * current_block_size);
3510 _silent_buffers.push_back (p);
3514 #ifdef NO_POSIX_MEMALIGN
3515 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3517 posix_memalign((void **)&p,16,current_block_size * 4);
3519 memset (p, 0, sizeof (Sample) * current_block_size);
3520 _send_buffers.push_back (p);
3523 allocate_pan_automation_buffers (current_block_size, howmany, false);
3527 Session::next_insert_id ()
3529 /* this doesn't really loop forever. just think about it */
3532 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3533 if (!insert_bitset[n]) {
3534 insert_bitset[n] = true;
3535 cerr << "Returning " << n << " as insert ID\n";
3541 /* none available, so resize and try again */
3543 insert_bitset.resize (insert_bitset.size() + 16, false);
3548 Session::next_send_id ()
3550 /* this doesn't really loop forever. just think about it */
3553 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3554 if (!send_bitset[n]) {
3555 send_bitset[n] = true;
3556 cerr << "Returning " << n << " as send ID\n";
3562 /* none available, so resize and try again */
3564 send_bitset.resize (send_bitset.size() + 16, false);
3569 Session::mark_send_id (uint32_t id)
3571 if (id >= send_bitset.size()) {
3572 send_bitset.resize (id+16, false);
3574 if (send_bitset[id]) {
3575 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3577 send_bitset[id] = true;
3581 Session::mark_insert_id (uint32_t id)
3583 if (id >= insert_bitset.size()) {
3584 insert_bitset.resize (id+16, false);
3586 if (insert_bitset[id]) {
3587 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3589 insert_bitset[id] = true;
3592 /* Named Selection management */
3595 Session::named_selection_by_name (string name)
3597 Glib::Mutex::Lock lm (named_selection_lock);
3598 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3599 if ((*i)->name == name) {
3607 Session::add_named_selection (NamedSelection* named_selection)
3610 Glib::Mutex::Lock lm (named_selection_lock);
3611 named_selections.insert (named_selections.begin(), named_selection);
3614 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3620 NamedSelectionAdded (); /* EMIT SIGNAL */
3624 Session::remove_named_selection (NamedSelection* named_selection)
3626 bool removed = false;
3629 Glib::Mutex::Lock lm (named_selection_lock);
3631 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3633 if (i != named_selections.end()) {
3635 named_selections.erase (i);
3642 NamedSelectionRemoved (); /* EMIT SIGNAL */
3647 Session::reset_native_file_format ()
3649 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3651 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3652 (*i)->reset_write_sources (false);
3657 Session::route_name_unique (string n) const
3659 shared_ptr<RouteList> r = routes.reader ();
3661 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3662 if ((*i)->name() == n) {
3671 Session::n_playlists () const
3673 Glib::Mutex::Lock lm (playlist_lock);
3674 return playlists.size();
3678 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3680 if (!force && howmany <= _npan_buffers) {
3684 if (_pan_automation_buffer) {
3686 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3687 delete [] _pan_automation_buffer[i];
3690 delete [] _pan_automation_buffer;
3693 _pan_automation_buffer = new pan_t*[howmany];
3695 for (uint32_t i = 0; i < howmany; ++i) {
3696 _pan_automation_buffer[i] = new pan_t[nframes];
3699 _npan_buffers = howmany;
3703 Session::freeze (InterThreadInfo& itt)
3705 shared_ptr<RouteList> r = routes.reader ();
3707 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3711 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3712 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3723 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3724 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3727 boost::shared_ptr<Playlist> playlist;
3728 boost::shared_ptr<AudioFileSource> fsource;
3730 char buf[PATH_MAX+1];
3734 nframes_t this_chunk;
3736 vector<Sample*> buffers;
3738 // any bigger than this seems to cause stack overflows in called functions
3739 const nframes_t chunk_size = (128 * 1024)/4;
3741 g_atomic_int_set (&processing_prohibited, 1);
3743 /* call tree *MUST* hold route_lock */
3745 if ((playlist = track.diskstream()->playlist()) == 0) {
3749 /* external redirects will be a problem */
3751 if (track.has_external_redirects()) {
3755 nchans = track.audio_diskstream()->n_channels();
3757 dir = discover_best_sound_dir ();
3759 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3761 for (x = 0; x < 99999; ++x) {
3762 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3763 if (access (buf, F_OK) != 0) {
3769 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3774 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3777 catch (failed_constructor& err) {
3778 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3782 srcs.push_back (fsource);
3785 /* XXX need to flush all redirects */
3790 /* create a set of reasonably-sized buffers */
3792 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3794 #ifdef NO_POSIX_MEMALIGN
3795 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3797 posix_memalign((void **)&b,16,chunk_size * 4);
3799 buffers.push_back (b);
3802 while (to_do && !itt.cancel) {
3804 this_chunk = min (to_do, chunk_size);
3806 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3811 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3812 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3815 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3821 start += this_chunk;
3822 to_do -= this_chunk;
3824 itt.progress = (float) (1.0 - ((double) to_do / len));
3833 xnow = localtime (&now);
3835 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3836 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3839 afs->update_header (position, *xnow, now);
3843 /* build peakfile for new source */
3845 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3846 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3848 afs->build_peaks ();
3852 /* construct a region to represent the bounced material */
3854 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3855 region_name_from_path (srcs.front()->name(), true));
3862 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3863 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3866 afs->mark_for_remove ();
3869 (*src)->drop_references ();
3873 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3877 g_atomic_int_set (&processing_prohibited, 0);
3885 Session::get_silent_buffers (uint32_t howmany)
3887 for (uint32_t i = 0; i < howmany; ++i) {
3888 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3890 return _silent_buffers;
3894 Session::ntracks () const
3897 shared_ptr<RouteList> r = routes.reader ();
3899 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3900 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3909 Session::nbusses () const
3912 shared_ptr<RouteList> r = routes.reader ();
3914 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3915 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3924 Session::add_automation_list(AutomationList *al)
3926 automation_lists[al->id()] = al;
3930 Session::compute_initial_length ()
3932 return _engine.frame_rate() * 60 * 5;