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 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1743 track->set_remote_control_id (control_id);
1746 new_routes.push_back (track);
1747 ret.push_back (track);
1750 catch (failed_constructor &err) {
1751 error << _("Session: could not create new audio track.") << endmsg;
1752 // XXX should we delete the tracks already created?
1760 if (!new_routes.empty()) {
1761 add_routes (new_routes, false);
1762 save_state (_current_snapshot_name);
1769 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1772 uint32_t bus_id = 1;
1776 uint32_t control_id;
1778 /* count existing audio busses */
1781 shared_ptr<RouteList> r = routes.reader ();
1783 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1784 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1785 if (!(*i)->hidden()) {
1792 vector<string> physinputs;
1793 vector<string> physoutputs;
1795 _engine.get_physical_outputs (physoutputs);
1796 _engine.get_physical_inputs (physinputs);
1797 control_id = ntracks() + nbusses() + 1;
1804 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1806 if (route_by_name (bus_name) == 0) {
1810 } while (bus_id < (UINT_MAX-1));
1813 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1815 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1816 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1817 input_channels, output_channels)
1821 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1825 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1826 port = physinputs[((n+x)%n_physical_inputs)];
1829 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1834 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1838 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1839 port = physoutputs[((n+x)%n_physical_outputs)];
1840 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1842 port = _master_out->input (x%_master_out->n_inputs())->name();
1846 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1852 vector<string> cports;
1853 uint32_t ni = _control_out->n_inputs();
1855 for (uint32_t n = 0; n < ni; ++n) {
1856 cports.push_back (_control_out->input(n)->name());
1858 bus->set_control_outs (cports);
1861 bus->set_remote_control_id (control_id);
1864 ret.push_back (bus);
1868 catch (failed_constructor &err) {
1869 error << _("Session: could not create new audio route.") << endmsg;
1878 add_routes (ret, false);
1879 save_state (_current_snapshot_name);
1887 Session::add_routes (RouteList& new_routes, bool save)
1890 RCUWriter<RouteList> writer (routes);
1891 shared_ptr<RouteList> r = writer.get_copy ();
1892 r->insert (r->end(), new_routes.begin(), new_routes.end());
1893 resort_routes_using (r);
1896 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1898 boost::weak_ptr<Route> wpr (*x);
1900 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1901 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1902 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1903 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1905 if ((*x)->master()) {
1909 if ((*x)->control()) {
1910 _control_out = (*x);
1917 save_state (_current_snapshot_name);
1920 RouteAdded (new_routes); /* EMIT SIGNAL */
1924 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1926 /* need to do this in case we're rolling at the time, to prevent false underruns */
1927 dstream->do_refill_with_alloc();
1930 RCUWriter<DiskstreamList> writer (diskstreams);
1931 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1932 ds->push_back (dstream);
1935 dstream->set_block_size (current_block_size);
1937 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1938 /* this will connect to future changes, and check the current length */
1939 diskstream_playlist_changed (dstream);
1941 dstream->prepare ();
1945 Session::remove_route (shared_ptr<Route> route)
1948 RCUWriter<RouteList> writer (routes);
1949 shared_ptr<RouteList> rs = writer.get_copy ();
1953 /* deleting the master out seems like a dumb
1954 idea, but its more of a UI policy issue
1958 if (route == _master_out) {
1959 _master_out = shared_ptr<Route> ();
1962 if (route == _control_out) {
1963 _control_out = shared_ptr<Route> ();
1965 /* cancel control outs for all routes */
1967 vector<string> empty;
1969 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1970 (*r)->set_control_outs (empty);
1974 update_route_solo_state ();
1976 /* writer goes out of scope, forces route list update */
1979 // FIXME: audio specific
1981 boost::shared_ptr<AudioDiskstream> ds;
1983 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1984 ds = at->audio_diskstream();
1990 RCUWriter<DiskstreamList> dsl (diskstreams);
1991 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1996 find_current_end ();
1998 update_latency_compensation (false, false);
2001 // We need to disconnect the routes inputs and outputs
2002 route->disconnect_inputs(NULL);
2003 route->disconnect_outputs(NULL);
2005 /* get rid of it from the dead wood collection in the route list manager */
2007 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2011 /* try to cause everyone to drop their references */
2013 route->drop_references ();
2015 /* save the new state of the world */
2017 if (save_state (_current_snapshot_name)) {
2018 save_history (_current_snapshot_name);
2023 Session::route_mute_changed (void* src)
2029 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2031 if (solo_update_disabled) {
2037 boost::shared_ptr<Route> route = wpr.lock ();
2040 /* should not happen */
2041 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2045 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2047 shared_ptr<RouteList> r = routes.reader ();
2049 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2051 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2055 /* don't mess with busses */
2057 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2063 /* don't mess with tracks */
2065 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2070 if ((*i) != route &&
2071 ((*i)->mix_group () == 0 ||
2072 (*i)->mix_group () != route->mix_group () ||
2073 !route->mix_group ()->is_active())) {
2075 if ((*i)->soloed()) {
2077 /* if its already soloed, and solo latching is enabled,
2078 then leave it as it is.
2081 if (Config->get_solo_latched()) {
2088 solo_update_disabled = true;
2089 (*i)->set_solo (false, src);
2090 solo_update_disabled = false;
2094 bool something_soloed = false;
2095 bool same_thing_soloed = false;
2096 bool signal = false;
2098 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2099 if ((*i)->soloed()) {
2100 something_soloed = true;
2101 if (dynamic_cast<AudioTrack*>((*i).get())) {
2103 same_thing_soloed = true;
2108 same_thing_soloed = true;
2116 if (something_soloed != currently_soloing) {
2118 currently_soloing = something_soloed;
2121 modify_solo_mute (is_track, same_thing_soloed);
2124 SoloActive (currently_soloing);
2131 Session::update_route_solo_state ()
2134 bool is_track = false;
2135 bool signal = false;
2137 /* caller must hold RouteLock */
2139 /* this is where we actually implement solo by changing
2140 the solo mute setting of each track.
2143 shared_ptr<RouteList> r = routes.reader ();
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2146 if ((*i)->soloed()) {
2148 if (dynamic_cast<AudioTrack*>((*i).get())) {
2155 if (mute != currently_soloing) {
2157 currently_soloing = mute;
2160 if (!is_track && !mute) {
2162 /* nothing is soloed */
2164 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2165 (*i)->set_solo_mute (false);
2175 modify_solo_mute (is_track, mute);
2178 SoloActive (currently_soloing);
2183 Session::modify_solo_mute (bool is_track, bool mute)
2185 shared_ptr<RouteList> r = routes.reader ();
2187 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2191 /* only alter track solo mute */
2193 if (dynamic_cast<AudioTrack*>((*i).get())) {
2194 if ((*i)->soloed()) {
2195 (*i)->set_solo_mute (!mute);
2197 (*i)->set_solo_mute (mute);
2203 /* only alter bus solo mute */
2205 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2207 if ((*i)->soloed()) {
2209 (*i)->set_solo_mute (false);
2213 /* don't mute master or control outs
2214 in response to another bus solo
2217 if ((*i) != _master_out &&
2218 (*i) != _control_out) {
2219 (*i)->set_solo_mute (mute);
2230 Session::catch_up_on_solo ()
2232 /* this is called after set_state() to catch the full solo
2233 state, which can't be correctly determined on a per-route
2234 basis, but needs the global overview that only the session
2237 update_route_solo_state();
2241 Session::route_by_name (string name)
2243 shared_ptr<RouteList> r = routes.reader ();
2245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2246 if ((*i)->name() == name) {
2251 return shared_ptr<Route> ((Route*) 0);
2255 Session::route_by_id (PBD::ID id)
2257 shared_ptr<RouteList> r = routes.reader ();
2259 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2260 if ((*i)->id() == id) {
2265 return shared_ptr<Route> ((Route*) 0);
2269 Session::route_by_remote_id (uint32_t id)
2271 shared_ptr<RouteList> r = routes.reader ();
2273 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2274 if ((*i)->remote_control_id() == id) {
2279 return shared_ptr<Route> ((Route*) 0);
2283 Session::find_current_end ()
2285 if (_state_of_the_state & Loading) {
2289 nframes_t max = get_maximum_extent ();
2291 if (max > end_location->end()) {
2292 end_location->set_end (max);
2294 DurationChanged(); /* EMIT SIGNAL */
2299 Session::get_maximum_extent () const
2304 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2306 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2307 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2308 if ((me = pl->get_maximum_extent()) > max) {
2316 boost::shared_ptr<Diskstream>
2317 Session::diskstream_by_name (string name)
2319 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2321 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2322 if ((*i)->name() == name) {
2327 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2330 boost::shared_ptr<Diskstream>
2331 Session::diskstream_by_id (const PBD::ID& id)
2333 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2335 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2336 if ((*i)->id() == id) {
2341 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2344 /* AudioRegion management */
2347 Session::new_region_name (string old)
2349 string::size_type last_period;
2351 string::size_type len = old.length() + 64;
2354 if ((last_period = old.find_last_of ('.')) == string::npos) {
2356 /* no period present - add one explicitly */
2359 last_period = old.length() - 1;
2364 number = atoi (old.substr (last_period+1).c_str());
2368 while (number < (UINT_MAX-1)) {
2370 AudioRegionList::const_iterator i;
2375 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2378 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2379 if (i->second->name() == sbuf) {
2384 if (i == audio_regions.end()) {
2389 if (number != (UINT_MAX-1)) {
2393 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2398 Session::region_name (string& result, string base, bool newlevel) const
2405 Glib::Mutex::Lock lm (region_lock);
2407 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2415 /* XXX this is going to be slow. optimize me later */
2420 string::size_type pos;
2422 pos = base.find_last_of ('.');
2424 /* pos may be npos, but then we just use entire base */
2426 subbase = base.substr (0, pos);
2430 bool name_taken = true;
2433 Glib::Mutex::Lock lm (region_lock);
2435 for (int n = 1; n < 5000; ++n) {
2438 snprintf (buf, sizeof (buf), ".%d", n);
2443 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2444 if (i->second->name() == result) {
2457 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2465 Session::add_region (boost::shared_ptr<Region> region)
2467 boost::shared_ptr<AudioRegion> ar;
2468 boost::shared_ptr<AudioRegion> oar;
2472 Glib::Mutex::Lock lm (region_lock);
2474 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2476 AudioRegionList::iterator x;
2478 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2480 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2482 if (ar->region_list_equivalent (oar)) {
2487 if (x == audio_regions.end()) {
2489 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2491 entry.first = region->id();
2494 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2506 fatal << _("programming error: ")
2507 << X_("unknown region type passed to Session::add_region()")
2514 /* mark dirty because something has changed even if we didn't
2515 add the region to the region list.
2521 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2522 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2523 AudioRegionAdded (ar); /* EMIT SIGNAL */
2528 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2530 boost::shared_ptr<Region> region (weak_region.lock ());
2536 if (what_changed & Region::HiddenChanged) {
2537 /* relay hidden changes */
2538 RegionHiddenChange (region);
2543 Session::remove_region (boost::weak_ptr<Region> weak_region)
2545 AudioRegionList::iterator i;
2546 boost::shared_ptr<Region> region (weak_region.lock ());
2552 boost::shared_ptr<AudioRegion> ar;
2553 bool removed = false;
2556 Glib::Mutex::Lock lm (region_lock);
2558 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2559 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2560 audio_regions.erase (i);
2566 fatal << _("programming error: ")
2567 << X_("unknown region type passed to Session::remove_region()")
2573 /* mark dirty because something has changed even if we didn't
2574 remove the region from the region list.
2580 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2584 boost::shared_ptr<AudioRegion>
2585 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2587 AudioRegionList::iterator i;
2588 boost::shared_ptr<AudioRegion> region;
2589 Glib::Mutex::Lock lm (region_lock);
2591 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2595 if (region->whole_file()) {
2597 if (child->source_equivalent (region)) {
2603 return boost::shared_ptr<AudioRegion> ();
2607 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2609 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2610 (*i)->get_region_list_equivalent_regions (region, result);
2614 Session::destroy_region (boost::shared_ptr<Region> region)
2616 vector<boost::shared_ptr<Source> > srcs;
2619 boost::shared_ptr<AudioRegion> aregion;
2621 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2625 if (aregion->playlist()) {
2626 aregion->playlist()->destroy_region (region);
2629 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2630 srcs.push_back (aregion->source (n));
2634 region->drop_references ();
2636 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2638 if (!(*i)->used()) {
2639 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2642 (afs)->mark_for_remove ();
2645 (*i)->drop_references ();
2647 cerr << "source was not used by any playlist\n";
2655 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2657 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2658 destroy_region (*i);
2664 Session::remove_last_capture ()
2666 list<boost::shared_ptr<Region> > r;
2668 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2670 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2671 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2674 r.insert (r.end(), l.begin(), l.end());
2679 destroy_regions (r);
2684 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2690 /* Source Management */
2693 Session::add_source (boost::shared_ptr<Source> source)
2695 boost::shared_ptr<AudioFileSource> afs;
2697 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2699 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2700 pair<AudioSourceList::iterator,bool> result;
2702 entry.first = source->id();
2706 Glib::Mutex::Lock lm (audio_source_lock);
2707 result = audio_sources.insert (entry);
2710 if (result.second) {
2711 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2719 Session::remove_source (boost::weak_ptr<Source> src)
2721 AudioSourceList::iterator i;
2722 boost::shared_ptr<Source> source = src.lock();
2729 Glib::Mutex::Lock lm (audio_source_lock);
2731 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2732 audio_sources.erase (i);
2736 if (!_state_of_the_state & InCleanup) {
2738 /* save state so we don't end up with a session file
2739 referring to non-existent sources.
2742 save_state (_current_snapshot_name);
2746 boost::shared_ptr<Source>
2747 Session::source_by_id (const PBD::ID& id)
2749 Glib::Mutex::Lock lm (audio_source_lock);
2750 AudioSourceList::iterator i;
2751 boost::shared_ptr<Source> source;
2753 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2757 /* XXX search MIDI or other searches here */
2763 Session::peak_path_from_audio_path (string audio_path) const
2768 res += PBD::basename_nosuffix (audio_path);
2775 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2778 string old_basename = PBD::basename_nosuffix (oldname);
2779 string new_legalized = legalize_for_path (newname);
2781 /* note: we know (or assume) the old path is already valid */
2785 /* destructive file sources have a name of the form:
2787 /path/to/Tnnnn-NAME(%[LR])?.wav
2789 the task here is to replace NAME with the new name.
2792 /* find last slash */
2796 string::size_type slash;
2797 string::size_type dash;
2799 if ((slash = path.find_last_of ('/')) == string::npos) {
2803 dir = path.substr (0, slash+1);
2805 /* '-' is not a legal character for the NAME part of the path */
2807 if ((dash = path.find_last_of ('-')) == string::npos) {
2811 prefix = path.substr (slash+1, dash-(slash+1));
2816 path += new_legalized;
2817 path += ".wav"; /* XXX gag me with a spoon */
2821 /* non-destructive file sources have a name of the form:
2823 /path/to/NAME-nnnnn(%[LR])?.wav
2825 the task here is to replace NAME with the new name.
2830 string::size_type slash;
2831 string::size_type dash;
2832 string::size_type postfix;
2834 /* find last slash */
2836 if ((slash = path.find_last_of ('/')) == string::npos) {
2840 dir = path.substr (0, slash+1);
2842 /* '-' is not a legal character for the NAME part of the path */
2844 if ((dash = path.find_last_of ('-')) == string::npos) {
2848 suffix = path.substr (dash+1);
2850 // Suffix is now everything after the dash. Now we need to eliminate
2851 // the nnnnn part, which is done by either finding a '%' or a '.'
2853 postfix = suffix.find_last_of ("%");
2854 if (postfix == string::npos) {
2855 postfix = suffix.find_last_of ('.');
2858 if (postfix != string::npos) {
2859 suffix = suffix.substr (postfix);
2861 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2865 const uint32_t limit = 10000;
2866 char buf[PATH_MAX+1];
2868 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2870 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2872 if (access (buf, F_OK) != 0) {
2880 error << "FATAL ERROR! Could not find a " << endl;
2889 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2893 char buf[PATH_MAX+1];
2894 const uint32_t limit = 10000;
2898 legalized = legalize_for_path (name);
2900 /* find a "version" of the file name that doesn't exist in
2901 any of the possible directories.
2904 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2906 vector<space_and_path>::iterator i;
2907 uint32_t existing = 0;
2909 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2913 spath += sound_dir (false);
2917 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2918 } else if (nchan == 2) {
2920 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2922 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2924 } else if (nchan < 26) {
2925 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2927 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2936 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2937 } else if (nchan == 2) {
2939 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2941 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2943 } else if (nchan < 26) {
2944 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2946 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2950 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2956 if (existing == 0) {
2961 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2963 throw failed_constructor();
2967 /* we now have a unique name for the file, but figure out where to
2973 spath = discover_best_sound_dir ();
2976 string::size_type pos = foo.find_last_of ('/');
2978 if (pos == string::npos) {
2981 spath += foo.substr (pos + 1);
2987 boost::shared_ptr<AudioFileSource>
2988 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2990 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2991 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2994 /* Playlist management */
2996 boost::shared_ptr<Playlist>
2997 Session::playlist_by_name (string name)
2999 Glib::Mutex::Lock lm (playlist_lock);
3000 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3001 if ((*i)->name() == name) {
3005 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3006 if ((*i)->name() == name) {
3011 return boost::shared_ptr<Playlist>();
3015 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3017 if (playlist->hidden()) {
3022 Glib::Mutex::Lock lm (playlist_lock);
3023 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3024 playlists.insert (playlists.begin(), playlist);
3025 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3026 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3032 PlaylistAdded (playlist); /* EMIT SIGNAL */
3036 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3039 Glib::Mutex::Lock lm (playlist_lock);
3040 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3043 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3050 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3052 boost::shared_ptr<Playlist> pl(wpl.lock());
3058 PlaylistList::iterator x;
3061 /* its not supposed to be visible */
3066 Glib::Mutex::Lock lm (playlist_lock);
3070 unused_playlists.insert (pl);
3072 if ((x = playlists.find (pl)) != playlists.end()) {
3073 playlists.erase (x);
3079 playlists.insert (pl);
3081 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3082 unused_playlists.erase (x);
3089 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3091 if (_state_of_the_state & Deletion) {
3095 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3102 Glib::Mutex::Lock lm (playlist_lock);
3104 PlaylistList::iterator i;
3106 i = find (playlists.begin(), playlists.end(), playlist);
3107 if (i != playlists.end()) {
3108 playlists.erase (i);
3111 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3112 if (i != unused_playlists.end()) {
3113 unused_playlists.erase (i);
3120 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3124 Session::set_audition (boost::shared_ptr<Region> r)
3126 pending_audition_region = r;
3127 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3128 schedule_butler_transport_work ();
3132 Session::audition_playlist ()
3134 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3135 ev->region.reset ();
3140 Session::non_realtime_set_audition ()
3142 if (!pending_audition_region) {
3143 auditioner->audition_current_playlist ();
3145 auditioner->audition_region (pending_audition_region);
3146 pending_audition_region.reset ();
3148 AuditionActive (true); /* EMIT SIGNAL */
3152 Session::audition_region (boost::shared_ptr<Region> r)
3154 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3160 Session::cancel_audition ()
3162 if (auditioner->active()) {
3163 auditioner->cancel_audition ();
3164 AuditionActive (false); /* EMIT SIGNAL */
3169 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3171 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3175 Session::remove_empty_sounds ()
3177 PathScanner scanner;
3179 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3181 Glib::Mutex::Lock lm (audio_source_lock);
3183 regex_t compiled_tape_track_pattern;
3186 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3190 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3192 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3196 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3198 /* never remove files that appear to be a tape track */
3200 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3205 if (AudioFileSource::is_empty (*this, *(*i))) {
3207 unlink ((*i)->c_str());
3209 string peak_path = peak_path_from_audio_path (**i);
3210 unlink (peak_path.c_str());
3216 delete possible_audiofiles;
3220 Session::is_auditioning () const
3222 /* can be called before we have an auditioner object */
3224 return auditioner->active();
3231 Session::set_all_solo (bool yn)
3233 shared_ptr<RouteList> r = routes.reader ();
3235 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3236 if (!(*i)->hidden()) {
3237 (*i)->set_solo (yn, this);
3245 Session::set_all_mute (bool yn)
3247 shared_ptr<RouteList> r = routes.reader ();
3249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3250 if (!(*i)->hidden()) {
3251 (*i)->set_mute (yn, this);
3259 Session::n_diskstreams () const
3263 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3265 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3266 if (!(*i)->hidden()) {
3274 Session::graph_reordered ()
3276 /* don't do this stuff if we are setting up connections
3277 from a set_state() call.
3280 if (_state_of_the_state & InitialConnecting) {
3284 /* every track/bus asked for this to be handled but it was deferred because
3285 we were connecting. do it now.
3288 request_input_change_handling ();
3292 /* force all diskstreams to update their capture offset values to
3293 reflect any changes in latencies within the graph.
3296 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3298 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3299 (*i)->set_capture_offset ();
3304 Session::record_disenable_all ()
3306 record_enable_change_all (false);
3310 Session::record_enable_all ()
3312 record_enable_change_all (true);
3316 Session::record_enable_change_all (bool yn)
3318 shared_ptr<RouteList> r = routes.reader ();
3320 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3323 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3324 at->set_record_enable (yn, this);
3328 /* since we don't keep rec-enable state, don't mark session dirty */
3332 Session::add_redirect (Redirect* redirect)
3336 PortInsert* port_insert;
3337 PluginInsert* plugin_insert;
3339 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3340 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3341 _port_inserts.insert (_port_inserts.begin(), port_insert);
3342 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3343 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3345 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3348 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3349 _sends.insert (_sends.begin(), send);
3351 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3355 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3361 Session::remove_redirect (Redirect* redirect)
3365 PortInsert* port_insert;
3366 PluginInsert* plugin_insert;
3368 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3369 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3370 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3371 if (x != _port_inserts.end()) {
3372 insert_bitset[port_insert->bit_slot()] = false;
3373 _port_inserts.erase (x);
3375 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3376 _plugin_inserts.remove (plugin_insert);
3378 fatal << string_compose (_("programming error: %1"),
3379 X_("unknown type of Insert deleted!"))
3383 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3384 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3385 if (x != _sends.end()) {
3386 send_bitset[send->bit_slot()] = false;
3390 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3398 Session::available_capture_duration ()
3400 float sample_bytes_on_disk;
3402 switch (Config->get_native_file_data_format()) {
3404 sample_bytes_on_disk = 4;
3408 sample_bytes_on_disk = 3;
3412 /* impossible, but keep some gcc versions happy */
3413 fatal << string_compose (_("programming error: %1"),
3414 X_("illegal native file data format"))
3419 double scale = 4096.0 / sample_bytes_on_disk;
3421 if (_total_free_4k_blocks * scale > (double) max_frames) {
3425 return (nframes_t) floor (_total_free_4k_blocks * scale);
3429 Session::add_connection (ARDOUR::Connection* connection)
3432 Glib::Mutex::Lock guard (connection_lock);
3433 _connections.push_back (connection);
3436 ConnectionAdded (connection); /* EMIT SIGNAL */
3442 Session::remove_connection (ARDOUR::Connection* connection)
3444 bool removed = false;
3447 Glib::Mutex::Lock guard (connection_lock);
3448 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3450 if (i != _connections.end()) {
3451 _connections.erase (i);
3457 ConnectionRemoved (connection); /* EMIT SIGNAL */
3463 ARDOUR::Connection *
3464 Session::connection_by_name (string name) const
3466 Glib::Mutex::Lock lm (connection_lock);
3468 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3469 if ((*i)->name() == name) {
3478 Session::tempo_map_changed (Change ignored)
3485 Session::ensure_passthru_buffers (uint32_t howmany)
3487 while (howmany > _passthru_buffers.size()) {
3489 #ifdef NO_POSIX_MEMALIGN
3490 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3492 posix_memalign((void **)&p,16,current_block_size * 4);
3494 _passthru_buffers.push_back (p);
3498 #ifdef NO_POSIX_MEMALIGN
3499 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3501 posix_memalign((void **)&p,16,current_block_size * 4);
3503 memset (p, 0, sizeof (Sample) * current_block_size);
3504 _silent_buffers.push_back (p);
3508 #ifdef NO_POSIX_MEMALIGN
3509 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3511 posix_memalign((void **)&p,16,current_block_size * 4);
3513 memset (p, 0, sizeof (Sample) * current_block_size);
3514 _send_buffers.push_back (p);
3517 allocate_pan_automation_buffers (current_block_size, howmany, false);
3521 Session::next_insert_id ()
3523 /* this doesn't really loop forever. just think about it */
3526 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3527 if (!insert_bitset[n]) {
3528 insert_bitset[n] = true;
3529 cerr << "Returning " << n << " as insert ID\n";
3535 /* none available, so resize and try again */
3537 insert_bitset.resize (insert_bitset.size() + 16, false);
3542 Session::next_send_id ()
3544 /* this doesn't really loop forever. just think about it */
3547 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3548 if (!send_bitset[n]) {
3549 send_bitset[n] = true;
3550 cerr << "Returning " << n << " as send ID\n";
3556 /* none available, so resize and try again */
3558 send_bitset.resize (send_bitset.size() + 16, false);
3563 Session::mark_send_id (uint32_t id)
3565 if (id >= send_bitset.size()) {
3566 send_bitset.resize (id+16, false);
3568 if (send_bitset[id]) {
3569 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3571 send_bitset[id] = true;
3575 Session::mark_insert_id (uint32_t id)
3577 if (id >= insert_bitset.size()) {
3578 insert_bitset.resize (id+16, false);
3580 if (insert_bitset[id]) {
3581 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3583 insert_bitset[id] = true;
3586 /* Named Selection management */
3589 Session::named_selection_by_name (string name)
3591 Glib::Mutex::Lock lm (named_selection_lock);
3592 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3593 if ((*i)->name == name) {
3601 Session::add_named_selection (NamedSelection* named_selection)
3604 Glib::Mutex::Lock lm (named_selection_lock);
3605 named_selections.insert (named_selections.begin(), named_selection);
3608 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3614 NamedSelectionAdded (); /* EMIT SIGNAL */
3618 Session::remove_named_selection (NamedSelection* named_selection)
3620 bool removed = false;
3623 Glib::Mutex::Lock lm (named_selection_lock);
3625 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3627 if (i != named_selections.end()) {
3629 named_selections.erase (i);
3636 NamedSelectionRemoved (); /* EMIT SIGNAL */
3641 Session::reset_native_file_format ()
3643 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3645 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3646 (*i)->reset_write_sources (false);
3651 Session::route_name_unique (string n) const
3653 shared_ptr<RouteList> r = routes.reader ();
3655 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3656 if ((*i)->name() == n) {
3665 Session::n_playlists () const
3667 Glib::Mutex::Lock lm (playlist_lock);
3668 return playlists.size();
3672 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3674 if (!force && howmany <= _npan_buffers) {
3678 if (_pan_automation_buffer) {
3680 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3681 delete [] _pan_automation_buffer[i];
3684 delete [] _pan_automation_buffer;
3687 _pan_automation_buffer = new pan_t*[howmany];
3689 for (uint32_t i = 0; i < howmany; ++i) {
3690 _pan_automation_buffer[i] = new pan_t[nframes];
3693 _npan_buffers = howmany;
3697 Session::freeze (InterThreadInfo& itt)
3699 shared_ptr<RouteList> r = routes.reader ();
3701 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3705 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3706 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3717 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3718 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3721 boost::shared_ptr<Playlist> playlist;
3722 boost::shared_ptr<AudioFileSource> fsource;
3724 char buf[PATH_MAX+1];
3728 nframes_t this_chunk;
3730 vector<Sample*> buffers;
3732 // any bigger than this seems to cause stack overflows in called functions
3733 const nframes_t chunk_size = (128 * 1024)/4;
3735 g_atomic_int_set (&processing_prohibited, 1);
3737 /* call tree *MUST* hold route_lock */
3739 if ((playlist = track.diskstream()->playlist()) == 0) {
3743 /* external redirects will be a problem */
3745 if (track.has_external_redirects()) {
3749 nchans = track.audio_diskstream()->n_channels();
3751 dir = discover_best_sound_dir ();
3753 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3755 for (x = 0; x < 99999; ++x) {
3756 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3757 if (access (buf, F_OK) != 0) {
3763 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3768 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3771 catch (failed_constructor& err) {
3772 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3776 srcs.push_back (fsource);
3779 /* XXX need to flush all redirects */
3784 /* create a set of reasonably-sized buffers */
3786 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3788 #ifdef NO_POSIX_MEMALIGN
3789 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3791 posix_memalign((void **)&b,16,chunk_size * 4);
3793 buffers.push_back (b);
3796 while (to_do && !itt.cancel) {
3798 this_chunk = min (to_do, chunk_size);
3800 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3805 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3806 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3809 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3815 start += this_chunk;
3816 to_do -= this_chunk;
3818 itt.progress = (float) (1.0 - ((double) to_do / len));
3827 xnow = localtime (&now);
3829 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3830 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3833 afs->update_header (position, *xnow, now);
3837 /* build peakfile for new source */
3839 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3840 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3842 afs->build_peaks ();
3846 /* construct a region to represent the bounced material */
3848 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3849 region_name_from_path (srcs.front()->name(), true));
3856 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3857 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3860 afs->mark_for_remove ();
3863 (*src)->drop_references ();
3867 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3871 g_atomic_int_set (&processing_prohibited, 0);
3879 Session::get_silent_buffers (uint32_t howmany)
3881 for (uint32_t i = 0; i < howmany; ++i) {
3882 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3884 return _silent_buffers;
3888 Session::ntracks () const
3891 shared_ptr<RouteList> r = routes.reader ();
3893 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3894 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3903 Session::nbusses () const
3906 shared_ptr<RouteList> r = routes.reader ();
3908 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3909 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3918 Session::add_automation_list(AutomationList *al)
3920 automation_lists[al->id()] = al;
3924 Session::compute_initial_length ()
3926 return _engine.frame_rate() * 60 * 5;