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 ();
355 if (control_out_channels) {
356 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
363 if (master_out_channels) {
364 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
370 /* prohibit auto-connect to master, because there isn't one */
371 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
374 Config->set_input_auto_connect (input_ac);
375 Config->set_output_auto_connect (output_ac);
377 if (second_stage_init (new_session)) {
379 throw failed_constructor ();
382 store_recent_sessions(_name, _path);
384 bool was_dirty = dirty ();
386 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
389 DirtyChanged (); /* EMIT SIGNAL */
401 /* if we got to here, leaving pending capture state around
405 remove_pending_capture_state ();
407 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
408 _engine.remove_session ();
410 GoingAway (); /* EMIT SIGNAL */
416 /* clear history so that no references to objects are held any more */
420 /* clear state tree so that no references to objects are held any more */
426 terminate_butler_thread ();
427 terminate_midi_thread ();
429 if (click_data && click_data != default_click) {
430 delete [] click_data;
433 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
434 delete [] click_emphasis_data;
439 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
443 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
447 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
451 AudioDiskstream::free_working_buffers();
453 /* this should cause deletion of the auditioner */
455 // auditioner.reset ();
457 #undef TRACK_DESTRUCTION
458 #ifdef TRACK_DESTRUCTION
459 cerr << "delete named selections\n";
460 #endif /* TRACK_DESTRUCTION */
461 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
462 NamedSelectionList::iterator tmp;
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete playlists\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
475 PlaylistList::iterator tmp;
480 (*i)->drop_references ();
485 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
486 PlaylistList::iterator tmp;
491 (*i)->drop_references ();
497 unused_playlists.clear ();
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete audio regions\n";
501 #endif /* TRACK_DESTRUCTION */
503 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
504 AudioRegionList::iterator tmp;
509 i->second->drop_references ();
514 audio_regions.clear ();
516 #ifdef TRACK_DESTRUCTION
517 cerr << "delete routes\n";
518 #endif /* TRACK_DESTRUCTION */
520 RCUWriter<RouteList> writer (routes);
521 boost::shared_ptr<RouteList> r = writer.get_copy ();
522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
523 (*i)->drop_references ();
526 /* writer goes out of scope and updates master */
531 #ifdef TRACK_DESTRUCTION
532 cerr << "delete diskstreams\n";
533 #endif /* TRACK_DESTRUCTION */
535 RCUWriter<DiskstreamList> dwriter (diskstreams);
536 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
537 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
538 (*i)->drop_references ();
542 diskstreams.flush ();
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete audio sources\n";
546 #endif /* TRACK_DESTRUCTION */
547 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
548 AudioSourceList::iterator tmp;
553 i->second->drop_references ();
558 audio_sources.clear ();
560 #ifdef TRACK_DESTRUCTION
561 cerr << "delete mix groups\n";
562 #endif /* TRACK_DESTRUCTION */
563 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
564 list<RouteGroup*>::iterator tmp;
574 #ifdef TRACK_DESTRUCTION
575 cerr << "delete edit groups\n";
576 #endif /* TRACK_DESTRUCTION */
577 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
578 list<RouteGroup*>::iterator tmp;
588 #ifdef TRACK_DESTRUCTION
589 cerr << "delete connections\n";
590 #endif /* TRACK_DESTRUCTION */
591 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
592 ConnectionList::iterator tmp;
602 if (butler_mixdown_buffer) {
603 delete [] butler_mixdown_buffer;
606 if (butler_gain_buffer) {
607 delete [] butler_gain_buffer;
610 Crossfade::set_buffer_size (0);
618 Session::set_worst_io_latencies ()
620 _worst_output_latency = 0;
621 _worst_input_latency = 0;
623 if (!_engine.connected()) {
627 boost::shared_ptr<RouteList> r = routes.reader ();
629 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
630 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
631 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
636 Session::when_engine_running ()
638 string first_physical_output;
640 /* we don't want to run execute this again */
642 set_block_size (_engine.frames_per_cycle());
643 set_frame_rate (_engine.frame_rate());
645 Config->map_parameters (mem_fun (*this, &Session::config_changed));
647 /* every time we reconnect, recompute worst case output latencies */
649 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
651 if (synced_to_jack()) {
652 _engine.transport_stop ();
655 if (Config->get_jack_time_master()) {
656 _engine.transport_locate (_transport_frame);
664 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
666 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
668 /* existing state for Click */
670 if (_click_io->set_state (*child->children().front()) == 0) {
672 _clicking = Config->get_clicking ();
676 error << _("could not setup Click I/O") << endmsg;
682 /* default state for Click */
684 first_physical_output = _engine.get_nth_physical_output (0);
686 if (first_physical_output.length()) {
687 if (_click_io->add_output_port (first_physical_output, this)) {
688 // relax, even though its an error
690 _clicking = Config->get_clicking ();
696 catch (failed_constructor& err) {
697 error << _("cannot setup Click I/O") << endmsg;
700 set_worst_io_latencies ();
703 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
706 /* Create a set of Connection objects that map
707 to the physical outputs currently available
712 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
714 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
716 Connection* c = new OutputConnection (buf, true);
719 c->add_connection (0, _engine.get_nth_physical_output (np));
724 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
726 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
728 Connection* c = new InputConnection (buf, true);
731 c->add_connection (0, _engine.get_nth_physical_input (np));
738 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
740 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
742 Connection* c = new OutputConnection (buf, true);
746 c->add_connection (0, _engine.get_nth_physical_output (np));
747 c->add_connection (1, _engine.get_nth_physical_output (np+1));
752 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
754 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
756 Connection* c = new InputConnection (buf, true);
760 c->add_connection (0, _engine.get_nth_physical_input (np));
761 c->add_connection (1, _engine.get_nth_physical_input (np+1));
770 /* create master/control ports */
775 /* force the master to ignore any later call to this */
777 if (_master_out->pending_state_node) {
778 _master_out->ports_became_legal();
781 /* no panner resets till we are through */
783 _master_out->defer_pan_reset ();
785 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
786 if (_master_out->add_input_port ("", this)) {
787 error << _("cannot setup master inputs")
793 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
794 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
795 error << _("cannot setup master outputs")
802 _master_out->allow_pan_reset ();
806 Connection* c = new OutputConnection (_("Master Out"), true);
808 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
810 c->add_connection ((int) n, _master_out->input(n)->name());
817 /* catch up on send+insert cnts */
821 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
824 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
825 if (id > insert_cnt) {
833 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
836 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
846 /* hook us up to the engine */
848 _engine.set_session (this);
853 osc->set_session (*this);
856 _state_of_the_state = Clean;
858 DirtyChanged (); /* EMIT SIGNAL */
862 Session::hookup_io ()
864 /* stop graph reordering notifications from
865 causing resorts, etc.
868 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
870 if (auditioner == 0) {
872 /* we delay creating the auditioner till now because
873 it makes its own connections to ports.
874 the engine has to be running for this to work.
878 auditioner.reset (new Auditioner (*this));
881 catch (failed_constructor& err) {
882 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
886 /* Tell all IO objects to create their ports */
893 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
894 if (_control_out->add_input_port ("", this)) {
895 error << _("cannot setup control inputs")
901 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
902 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
903 error << _("cannot set up master outputs")
911 /* Tell all IO objects to connect themselves together */
913 IO::enable_connecting ();
915 /* Now reset all panners */
917 IO::reset_panners ();
919 /* Anyone who cares about input state, wake up and do something */
921 IOConnectionsComplete (); /* EMIT SIGNAL */
923 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
925 /* now handle the whole enchilada as if it was one
931 /* update mixer solo state */
937 Session::playlist_length_changed ()
939 /* we can't just increase end_location->end() if pl->get_maximum_extent()
940 if larger. if the playlist used to be the longest playlist,
941 and its now shorter, we have to decrease end_location->end(). hence,
942 we have to iterate over all diskstreams and check the
943 playlists currently in use.
949 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
951 boost::shared_ptr<Playlist> playlist;
953 if ((playlist = dstream->playlist()) != 0) {
954 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
957 /* see comment in playlist_length_changed () */
962 Session::record_enabling_legal () const
964 /* this used to be in here, but survey says.... we don't need to restrict it */
965 // if (record_status() == Recording) {
969 if (Config->get_all_safe()) {
976 Session::reset_input_monitor_state ()
978 if (transport_rolling()) {
980 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
982 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
983 if ((*i)->record_enabled ()) {
984 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
985 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
989 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
991 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
992 if ((*i)->record_enabled ()) {
993 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
994 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1001 Session::auto_punch_start_changed (Location* location)
1003 replace_event (Event::PunchIn, location->start());
1005 if (get_record_enabled() && Config->get_punch_in()) {
1006 /* capture start has been changed, so save new pending state */
1007 save_state ("", true);
1012 Session::auto_punch_end_changed (Location* location)
1014 nframes_t when_to_stop = location->end();
1015 // when_to_stop += _worst_output_latency + _worst_input_latency;
1016 replace_event (Event::PunchOut, when_to_stop);
1020 Session::auto_punch_changed (Location* location)
1022 nframes_t when_to_stop = location->end();
1024 replace_event (Event::PunchIn, location->start());
1025 //when_to_stop += _worst_output_latency + _worst_input_latency;
1026 replace_event (Event::PunchOut, when_to_stop);
1030 Session::auto_loop_changed (Location* location)
1032 replace_event (Event::AutoLoop, location->end(), location->start());
1034 if (transport_rolling() && play_loop) {
1036 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1038 if (_transport_frame > location->end()) {
1039 // relocate to beginning of loop
1040 clear_events (Event::LocateRoll);
1042 request_locate (location->start(), true);
1045 else if (Config->get_seamless_loop() && !loop_changing) {
1047 // schedule a locate-roll to refill the diskstreams at the
1048 // previous loop end
1049 loop_changing = true;
1051 if (location->end() > last_loopend) {
1052 clear_events (Event::LocateRoll);
1053 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1060 last_loopend = location->end();
1065 Session::set_auto_punch_location (Location* location)
1069 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1070 auto_punch_start_changed_connection.disconnect();
1071 auto_punch_end_changed_connection.disconnect();
1072 auto_punch_changed_connection.disconnect();
1073 existing->set_auto_punch (false, this);
1074 remove_event (existing->start(), Event::PunchIn);
1075 clear_events (Event::PunchOut);
1076 auto_punch_location_changed (0);
1081 if (location == 0) {
1085 if (location->end() <= location->start()) {
1086 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1090 auto_punch_start_changed_connection.disconnect();
1091 auto_punch_end_changed_connection.disconnect();
1092 auto_punch_changed_connection.disconnect();
1094 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1095 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1096 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1098 location->set_auto_punch (true, this);
1099 auto_punch_location_changed (location);
1103 Session::set_auto_loop_location (Location* location)
1107 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1108 auto_loop_start_changed_connection.disconnect();
1109 auto_loop_end_changed_connection.disconnect();
1110 auto_loop_changed_connection.disconnect();
1111 existing->set_auto_loop (false, this);
1112 remove_event (existing->end(), Event::AutoLoop);
1113 auto_loop_location_changed (0);
1118 if (location == 0) {
1122 if (location->end() <= location->start()) {
1123 error << _("Session: you can't use a mark for auto loop") << endmsg;
1127 last_loopend = location->end();
1129 auto_loop_start_changed_connection.disconnect();
1130 auto_loop_end_changed_connection.disconnect();
1131 auto_loop_changed_connection.disconnect();
1133 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1134 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1135 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1137 location->set_auto_loop (true, this);
1138 auto_loop_location_changed (location);
1142 Session::locations_added (Location* ignored)
1148 Session::locations_changed ()
1150 _locations.apply (*this, &Session::handle_locations_changed);
1154 Session::handle_locations_changed (Locations::LocationList& locations)
1156 Locations::LocationList::iterator i;
1158 bool set_loop = false;
1159 bool set_punch = false;
1161 for (i = locations.begin(); i != locations.end(); ++i) {
1165 if (location->is_auto_punch()) {
1166 set_auto_punch_location (location);
1169 if (location->is_auto_loop()) {
1170 set_auto_loop_location (location);
1177 set_auto_loop_location (0);
1180 set_auto_punch_location (0);
1187 Session::enable_record ()
1189 /* XXX really atomic compare+swap here */
1190 if (g_atomic_int_get (&_record_status) != Recording) {
1191 g_atomic_int_set (&_record_status, Recording);
1192 _last_record_location = _transport_frame;
1193 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1195 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1196 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1197 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1198 if ((*i)->record_enabled ()) {
1199 (*i)->monitor_input (true);
1204 RecordStateChanged ();
1209 Session::disable_record (bool rt_context, bool force)
1213 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1215 if (!Config->get_latched_record_enable () || force) {
1216 g_atomic_int_set (&_record_status, Disabled);
1218 if (rs == Recording) {
1219 g_atomic_int_set (&_record_status, Enabled);
1223 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1225 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1226 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1228 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1229 if ((*i)->record_enabled ()) {
1230 (*i)->monitor_input (false);
1235 RecordStateChanged (); /* emit signal */
1238 remove_pending_capture_state ();
1244 Session::step_back_from_record ()
1246 g_atomic_int_set (&_record_status, Enabled);
1248 if (Config->get_monitoring_model() == HardwareMonitoring) {
1249 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1251 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1252 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1253 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1254 (*i)->monitor_input (false);
1261 Session::maybe_enable_record ()
1263 g_atomic_int_set (&_record_status, Enabled);
1265 /* this function is currently called from somewhere other than an RT thread.
1266 this save_state() call therefore doesn't impact anything.
1269 save_state ("", true);
1271 if (_transport_speed) {
1272 if (!Config->get_punch_in()) {
1276 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1277 RecordStateChanged (); /* EMIT SIGNAL */
1284 Session::audible_frame () const
1290 /* the first of these two possible settings for "offset"
1291 mean that the audible frame is stationary until
1292 audio emerges from the latency compensation
1295 the second means that the audible frame is stationary
1296 until audio would emerge from a physical port
1297 in the absence of any plugin latency compensation
1300 offset = _worst_output_latency;
1302 if (offset > current_block_size) {
1303 offset -= current_block_size;
1305 /* XXX is this correct? if we have no external
1306 physical connections and everything is internal
1307 then surely this is zero? still, how
1308 likely is that anyway?
1310 offset = current_block_size;
1313 if (synced_to_jack()) {
1314 tf = _engine.transport_frame();
1316 tf = _transport_frame;
1319 if (_transport_speed == 0) {
1329 if (!non_realtime_work_pending()) {
1333 /* take latency into account */
1342 Session::set_frame_rate (nframes_t frames_per_second)
1344 /** \fn void Session::set_frame_size(nframes_t)
1345 the AudioEngine object that calls this guarantees
1346 that it will not be called while we are also in
1347 ::process(). Its fine to do things that block
1351 _base_frame_rate = frames_per_second;
1355 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1357 // XXX we need some equivalent to this, somehow
1358 // SndFileSource::setup_standard_crossfades (frames_per_second);
1362 /* XXX need to reset/reinstantiate all LADSPA plugins */
1366 Session::set_block_size (nframes_t nframes)
1368 /* the AudioEngine guarantees
1369 that it will not be called while we are also in
1370 ::process(). It is therefore fine to do things that block
1375 vector<Sample*>::iterator i;
1378 current_block_size = nframes;
1380 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1384 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1388 _passthru_buffers.clear ();
1389 _silent_buffers.clear ();
1391 ensure_passthru_buffers (np);
1393 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1397 #ifdef NO_POSIX_MEMALIGN
1398 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1400 posix_memalign((void **)&buf,16,current_block_size * 4);
1404 memset (*i, 0, sizeof (Sample) * current_block_size);
1408 if (_gain_automation_buffer) {
1409 delete [] _gain_automation_buffer;
1411 _gain_automation_buffer = new gain_t[nframes];
1413 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1415 boost::shared_ptr<RouteList> r = routes.reader ();
1417 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1418 (*i)->set_block_size (nframes);
1421 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1422 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1423 (*i)->set_block_size (nframes);
1426 set_worst_io_latencies ();
1431 Session::set_default_fade (float steepness, float fade_msecs)
1434 nframes_t fade_frames;
1436 /* Don't allow fade of less 1 frame */
1438 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1445 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1449 default_fade_msecs = fade_msecs;
1450 default_fade_steepness = steepness;
1453 // jlc, WTF is this!
1454 Glib::RWLock::ReaderLock lm (route_lock);
1455 AudioRegion::set_default_fade (steepness, fade_frames);
1460 /* XXX have to do this at some point */
1461 /* foreach region using default fade, reset, then
1462 refill_all_diskstream_buffers ();
1467 struct RouteSorter {
1468 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1469 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1471 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1474 if (r1->fed_by.empty()) {
1475 if (r2->fed_by.empty()) {
1476 /* no ardour-based connections inbound to either route. just use signal order */
1477 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1479 /* r2 has connections, r1 does not; run r1 early */
1483 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1490 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1492 shared_ptr<Route> r2;
1494 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1495 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1499 /* make a copy of the existing list of routes that feed r1 */
1501 set<shared_ptr<Route> > existing = r1->fed_by;
1503 /* for each route that feeds r1, recurse, marking it as feeding
1507 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1510 /* r2 is a route that feeds r1 which somehow feeds base. mark
1511 base as being fed by r2
1514 rbase->fed_by.insert (r2);
1518 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1522 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1526 /* now recurse, so that we can mark base as being fed by
1527 all routes that feed r2
1530 trace_terminal (r2, rbase);
1537 Session::resort_routes ()
1539 /* don't do anything here with signals emitted
1540 by Routes while we are being destroyed.
1543 if (_state_of_the_state & Deletion) {
1550 RCUWriter<RouteList> writer (routes);
1551 shared_ptr<RouteList> r = writer.get_copy ();
1552 resort_routes_using (r);
1553 /* writer goes out of scope and forces update */
1558 Session::resort_routes_using (shared_ptr<RouteList> r)
1560 RouteList::iterator i, j;
1562 for (i = r->begin(); i != r->end(); ++i) {
1564 (*i)->fed_by.clear ();
1566 for (j = r->begin(); j != r->end(); ++j) {
1568 /* although routes can feed themselves, it will
1569 cause an endless recursive descent if we
1570 detect it. so don't bother checking for
1578 if ((*j)->feeds (*i)) {
1579 (*i)->fed_by.insert (*j);
1584 for (i = r->begin(); i != r->end(); ++i) {
1585 trace_terminal (*i, *i);
1591 /* don't leave dangling references to routes in Route::fed_by */
1593 for (i = r->begin(); i != r->end(); ++i) {
1594 (*i)->fed_by.clear ();
1598 cerr << "finished route resort\n";
1600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1601 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1608 list<boost::shared_ptr<AudioTrack> >
1609 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1611 char track_name[32];
1612 uint32_t track_id = 0;
1614 uint32_t channels_used = 0;
1616 RouteList new_routes;
1617 list<boost::shared_ptr<AudioTrack> > ret;
1619 /* count existing audio tracks */
1622 shared_ptr<RouteList> r = routes.reader ();
1624 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1625 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1626 if (!(*i)->hidden()) {
1628 channels_used += (*i)->n_inputs();
1634 vector<string> physinputs;
1635 vector<string> physoutputs;
1636 uint32_t nphysical_in;
1637 uint32_t nphysical_out;
1639 _engine.get_physical_outputs (physoutputs);
1640 _engine.get_physical_inputs (physinputs);
1644 /* check for duplicate route names, since we might have pre-existing
1645 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1646 save, close,restart,add new route - first named route is now
1654 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1656 if (route_by_name (track_name) == 0) {
1660 } while (track_id < (UINT_MAX-1));
1662 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1663 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1668 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1669 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1675 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1677 if (track->ensure_io (input_channels, output_channels, false, this)) {
1678 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1679 input_channels, output_channels)
1684 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1688 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1689 port = physinputs[(channels_used+x)%nphysical_in];
1692 if (port.length() && track->connect_input (track->input (x), port, this)) {
1698 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1702 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1703 port = physoutputs[(channels_used+x)%nphysical_out];
1704 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1706 port = _master_out->input (x%_master_out->n_inputs())->name();
1710 if (port.length() && track->connect_output (track->output (x), port, this)) {
1715 channels_used += track->n_inputs ();
1718 vector<string> cports;
1719 uint32_t ni = _control_out->n_inputs();
1721 for (n = 0; n < ni; ++n) {
1722 cports.push_back (_control_out->input(n)->name());
1725 track->set_control_outs (cports);
1728 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1729 track->set_remote_control_id (ntracks());
1731 new_routes.push_back (track);
1732 ret.push_back (track);
1735 catch (failed_constructor &err) {
1736 error << _("Session: could not create new audio track.") << endmsg;
1737 // XXX should we delete the tracks already created?
1745 if (!new_routes.empty()) {
1746 add_routes (new_routes, false);
1747 save_state (_current_snapshot_name);
1754 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1757 uint32_t bus_id = 1;
1762 /* count existing audio busses */
1765 shared_ptr<RouteList> r = routes.reader ();
1767 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1768 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1769 if (!(*i)->hidden()) {
1776 vector<string> physinputs;
1777 vector<string> physoutputs;
1779 _engine.get_physical_outputs (physoutputs);
1780 _engine.get_physical_inputs (physinputs);
1787 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1789 if (route_by_name (bus_name) == 0) {
1793 } while (bus_id < (UINT_MAX-1));
1796 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1798 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1799 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1800 input_channels, output_channels)
1804 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1808 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1809 port = physinputs[((n+x)%n_physical_inputs)];
1812 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1817 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1821 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1822 port = physoutputs[((n+x)%n_physical_outputs)];
1823 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1825 port = _master_out->input (x%_master_out->n_inputs())->name();
1829 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1835 vector<string> cports;
1836 uint32_t ni = _control_out->n_inputs();
1838 for (uint32_t n = 0; n < ni; ++n) {
1839 cports.push_back (_control_out->input(n)->name());
1841 bus->set_control_outs (cports);
1844 ret.push_back (bus);
1848 catch (failed_constructor &err) {
1849 error << _("Session: could not create new audio route.") << endmsg;
1858 add_routes (ret, false);
1859 save_state (_current_snapshot_name);
1867 Session::add_routes (RouteList& new_routes, bool save)
1870 RCUWriter<RouteList> writer (routes);
1871 shared_ptr<RouteList> r = writer.get_copy ();
1872 r->insert (r->end(), new_routes.begin(), new_routes.end());
1873 resort_routes_using (r);
1876 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1878 boost::weak_ptr<Route> wpr (*x);
1880 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1881 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1882 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1883 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1885 if ((*x)->master()) {
1889 if ((*x)->control()) {
1890 _control_out = (*x);
1897 save_state (_current_snapshot_name);
1900 RouteAdded (new_routes); /* EMIT SIGNAL */
1904 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1906 /* need to do this in case we're rolling at the time, to prevent false underruns */
1907 dstream->do_refill_with_alloc();
1910 RCUWriter<DiskstreamList> writer (diskstreams);
1911 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1912 ds->push_back (dstream);
1915 dstream->set_block_size (current_block_size);
1917 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1918 /* this will connect to future changes, and check the current length */
1919 diskstream_playlist_changed (dstream);
1921 dstream->prepare ();
1925 Session::remove_route (shared_ptr<Route> route)
1928 RCUWriter<RouteList> writer (routes);
1929 shared_ptr<RouteList> rs = writer.get_copy ();
1933 /* deleting the master out seems like a dumb
1934 idea, but its more of a UI policy issue
1938 if (route == _master_out) {
1939 _master_out = shared_ptr<Route> ();
1942 if (route == _control_out) {
1943 _control_out = shared_ptr<Route> ();
1945 /* cancel control outs for all routes */
1947 vector<string> empty;
1949 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1950 (*r)->set_control_outs (empty);
1954 update_route_solo_state ();
1956 /* writer goes out of scope, forces route list update */
1959 // FIXME: audio specific
1961 boost::shared_ptr<AudioDiskstream> ds;
1963 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1964 ds = at->audio_diskstream();
1970 RCUWriter<DiskstreamList> dsl (diskstreams);
1971 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1976 find_current_end ();
1978 update_latency_compensation (false, false);
1981 // We need to disconnect the routes inputs and outputs
1982 route->disconnect_inputs(NULL);
1983 route->disconnect_outputs(NULL);
1985 /* get rid of it from the dead wood collection in the route list manager */
1987 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1991 /* try to cause everyone to drop their references */
1993 route->drop_references ();
1995 /* save the new state of the world */
1997 if (save_state (_current_snapshot_name)) {
1998 save_history (_current_snapshot_name);
2003 Session::route_mute_changed (void* src)
2009 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2011 if (solo_update_disabled) {
2017 boost::shared_ptr<Route> route = wpr.lock ();
2020 /* should not happen */
2021 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2025 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2027 shared_ptr<RouteList> r = routes.reader ();
2029 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2031 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2035 /* don't mess with busses */
2037 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2043 /* don't mess with tracks */
2045 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2050 if ((*i) != route &&
2051 ((*i)->mix_group () == 0 ||
2052 (*i)->mix_group () != route->mix_group () ||
2053 !route->mix_group ()->is_active())) {
2055 if ((*i)->soloed()) {
2057 /* if its already soloed, and solo latching is enabled,
2058 then leave it as it is.
2061 if (Config->get_solo_latched()) {
2068 solo_update_disabled = true;
2069 (*i)->set_solo (false, src);
2070 solo_update_disabled = false;
2074 bool something_soloed = false;
2075 bool same_thing_soloed = false;
2076 bool signal = false;
2078 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2079 if ((*i)->soloed()) {
2080 something_soloed = true;
2081 if (dynamic_cast<AudioTrack*>((*i).get())) {
2083 same_thing_soloed = true;
2088 same_thing_soloed = true;
2096 if (something_soloed != currently_soloing) {
2098 currently_soloing = something_soloed;
2101 modify_solo_mute (is_track, same_thing_soloed);
2104 SoloActive (currently_soloing);
2111 Session::update_route_solo_state ()
2114 bool is_track = false;
2115 bool signal = false;
2117 /* caller must hold RouteLock */
2119 /* this is where we actually implement solo by changing
2120 the solo mute setting of each track.
2123 shared_ptr<RouteList> r = routes.reader ();
2125 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2126 if ((*i)->soloed()) {
2128 if (dynamic_cast<AudioTrack*>((*i).get())) {
2135 if (mute != currently_soloing) {
2137 currently_soloing = mute;
2140 if (!is_track && !mute) {
2142 /* nothing is soloed */
2144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2145 (*i)->set_solo_mute (false);
2155 modify_solo_mute (is_track, mute);
2158 SoloActive (currently_soloing);
2163 Session::modify_solo_mute (bool is_track, bool mute)
2165 shared_ptr<RouteList> r = routes.reader ();
2167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2171 /* only alter track solo mute */
2173 if (dynamic_cast<AudioTrack*>((*i).get())) {
2174 if ((*i)->soloed()) {
2175 (*i)->set_solo_mute (!mute);
2177 (*i)->set_solo_mute (mute);
2183 /* only alter bus solo mute */
2185 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2187 if ((*i)->soloed()) {
2189 (*i)->set_solo_mute (false);
2193 /* don't mute master or control outs
2194 in response to another bus solo
2197 if ((*i) != _master_out &&
2198 (*i) != _control_out) {
2199 (*i)->set_solo_mute (mute);
2210 Session::catch_up_on_solo ()
2212 /* this is called after set_state() to catch the full solo
2213 state, which can't be correctly determined on a per-route
2214 basis, but needs the global overview that only the session
2217 update_route_solo_state();
2221 Session::route_by_name (string name)
2223 shared_ptr<RouteList> r = routes.reader ();
2225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 if ((*i)->name() == name) {
2231 return shared_ptr<Route> ((Route*) 0);
2235 Session::route_by_id (PBD::ID id)
2237 shared_ptr<RouteList> r = routes.reader ();
2239 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2240 if ((*i)->id() == id) {
2245 return shared_ptr<Route> ((Route*) 0);
2249 Session::route_by_remote_id (uint32_t id)
2251 shared_ptr<RouteList> r = routes.reader ();
2253 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2254 if ((*i)->remote_control_id() == id) {
2259 return shared_ptr<Route> ((Route*) 0);
2263 Session::find_current_end ()
2265 if (_state_of_the_state & Loading) {
2269 nframes_t max = get_maximum_extent ();
2271 if (max > end_location->end()) {
2272 end_location->set_end (max);
2274 DurationChanged(); /* EMIT SIGNAL */
2279 Session::get_maximum_extent () const
2284 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2286 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2287 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2288 if ((me = pl->get_maximum_extent()) > max) {
2296 boost::shared_ptr<Diskstream>
2297 Session::diskstream_by_name (string name)
2299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2302 if ((*i)->name() == name) {
2307 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2310 boost::shared_ptr<Diskstream>
2311 Session::diskstream_by_id (const PBD::ID& id)
2313 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2315 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2316 if ((*i)->id() == id) {
2321 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2324 /* AudioRegion management */
2327 Session::new_region_name (string old)
2329 string::size_type last_period;
2331 string::size_type len = old.length() + 64;
2334 if ((last_period = old.find_last_of ('.')) == string::npos) {
2336 /* no period present - add one explicitly */
2339 last_period = old.length() - 1;
2344 number = atoi (old.substr (last_period+1).c_str());
2348 while (number < (UINT_MAX-1)) {
2350 AudioRegionList::const_iterator i;
2355 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2358 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2359 if (i->second->name() == sbuf) {
2364 if (i == audio_regions.end()) {
2369 if (number != (UINT_MAX-1)) {
2373 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2378 Session::region_name (string& result, string base, bool newlevel) const
2385 Glib::Mutex::Lock lm (region_lock);
2387 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2395 /* XXX this is going to be slow. optimize me later */
2400 string::size_type pos;
2402 pos = base.find_last_of ('.');
2404 /* pos may be npos, but then we just use entire base */
2406 subbase = base.substr (0, pos);
2410 bool name_taken = true;
2413 Glib::Mutex::Lock lm (region_lock);
2415 for (int n = 1; n < 5000; ++n) {
2418 snprintf (buf, sizeof (buf), ".%d", n);
2423 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2424 if (i->second->name() == result) {
2437 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2445 Session::add_region (boost::shared_ptr<Region> region)
2447 boost::shared_ptr<AudioRegion> ar;
2448 boost::shared_ptr<AudioRegion> oar;
2452 Glib::Mutex::Lock lm (region_lock);
2454 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2456 AudioRegionList::iterator x;
2458 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2460 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2462 if (ar->region_list_equivalent (oar)) {
2467 if (x == audio_regions.end()) {
2469 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2471 entry.first = region->id();
2474 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2486 fatal << _("programming error: ")
2487 << X_("unknown region type passed to Session::add_region()")
2494 /* mark dirty because something has changed even if we didn't
2495 add the region to the region list.
2501 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2502 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2503 AudioRegionAdded (ar); /* EMIT SIGNAL */
2508 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2510 boost::shared_ptr<Region> region (weak_region.lock ());
2516 if (what_changed & Region::HiddenChanged) {
2517 /* relay hidden changes */
2518 RegionHiddenChange (region);
2523 Session::remove_region (boost::weak_ptr<Region> weak_region)
2525 AudioRegionList::iterator i;
2526 boost::shared_ptr<Region> region (weak_region.lock ());
2532 boost::shared_ptr<AudioRegion> ar;
2533 bool removed = false;
2536 Glib::Mutex::Lock lm (region_lock);
2538 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2539 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2540 audio_regions.erase (i);
2546 fatal << _("programming error: ")
2547 << X_("unknown region type passed to Session::remove_region()")
2553 /* mark dirty because something has changed even if we didn't
2554 remove the region from the region list.
2560 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2564 boost::shared_ptr<AudioRegion>
2565 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2567 AudioRegionList::iterator i;
2568 boost::shared_ptr<AudioRegion> region;
2569 Glib::Mutex::Lock lm (region_lock);
2571 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2575 if (region->whole_file()) {
2577 if (child->source_equivalent (region)) {
2583 return boost::shared_ptr<AudioRegion> ();
2587 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2589 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2590 (*i)->get_region_list_equivalent_regions (region, result);
2594 Session::destroy_region (boost::shared_ptr<Region> region)
2596 vector<boost::shared_ptr<Source> > srcs;
2599 boost::shared_ptr<AudioRegion> aregion;
2601 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2605 if (aregion->playlist()) {
2606 aregion->playlist()->destroy_region (region);
2609 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2610 srcs.push_back (aregion->source (n));
2614 region->drop_references ();
2616 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2618 if (!(*i)->used()) {
2619 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2622 (afs)->mark_for_remove ();
2625 (*i)->drop_references ();
2627 cerr << "source was not used by any playlist\n";
2635 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2637 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2638 destroy_region (*i);
2644 Session::remove_last_capture ()
2646 list<boost::shared_ptr<Region> > r;
2648 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2650 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2651 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2654 r.insert (r.end(), l.begin(), l.end());
2659 destroy_regions (r);
2664 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2670 /* Source Management */
2673 Session::add_source (boost::shared_ptr<Source> source)
2675 boost::shared_ptr<AudioFileSource> afs;
2677 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2679 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2680 pair<AudioSourceList::iterator,bool> result;
2682 entry.first = source->id();
2686 Glib::Mutex::Lock lm (audio_source_lock);
2687 result = audio_sources.insert (entry);
2690 if (result.second) {
2691 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2699 Session::remove_source (boost::weak_ptr<Source> src)
2701 AudioSourceList::iterator i;
2702 boost::shared_ptr<Source> source = src.lock();
2709 Glib::Mutex::Lock lm (audio_source_lock);
2711 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2712 audio_sources.erase (i);
2716 if (!_state_of_the_state & InCleanup) {
2718 /* save state so we don't end up with a session file
2719 referring to non-existent sources.
2722 save_state (_current_snapshot_name);
2726 boost::shared_ptr<Source>
2727 Session::source_by_id (const PBD::ID& id)
2729 Glib::Mutex::Lock lm (audio_source_lock);
2730 AudioSourceList::iterator i;
2731 boost::shared_ptr<Source> source;
2733 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2737 /* XXX search MIDI or other searches here */
2743 Session::peak_path_from_audio_path (string audio_path) const
2748 res += PBD::basename_nosuffix (audio_path);
2755 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2758 string old_basename = PBD::basename_nosuffix (oldname);
2759 string new_legalized = legalize_for_path (newname);
2761 /* note: we know (or assume) the old path is already valid */
2765 /* destructive file sources have a name of the form:
2767 /path/to/Tnnnn-NAME(%[LR])?.wav
2769 the task here is to replace NAME with the new name.
2772 /* find last slash */
2776 string::size_type slash;
2777 string::size_type dash;
2779 if ((slash = path.find_last_of ('/')) == string::npos) {
2783 dir = path.substr (0, slash+1);
2785 /* '-' is not a legal character for the NAME part of the path */
2787 if ((dash = path.find_last_of ('-')) == string::npos) {
2791 prefix = path.substr (slash+1, dash-(slash+1));
2796 path += new_legalized;
2797 path += ".wav"; /* XXX gag me with a spoon */
2801 /* non-destructive file sources have a name of the form:
2803 /path/to/NAME-nnnnn(%[LR])?.wav
2805 the task here is to replace NAME with the new name.
2810 string::size_type slash;
2811 string::size_type dash;
2812 string::size_type postfix;
2814 /* find last slash */
2816 if ((slash = path.find_last_of ('/')) == string::npos) {
2820 dir = path.substr (0, slash+1);
2822 /* '-' is not a legal character for the NAME part of the path */
2824 if ((dash = path.find_last_of ('-')) == string::npos) {
2828 suffix = path.substr (dash+1);
2830 // Suffix is now everything after the dash. Now we need to eliminate
2831 // the nnnnn part, which is done by either finding a '%' or a '.'
2833 postfix = suffix.find_last_of ("%");
2834 if (postfix == string::npos) {
2835 postfix = suffix.find_last_of ('.');
2838 if (postfix != string::npos) {
2839 suffix = suffix.substr (postfix);
2841 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2845 const uint32_t limit = 10000;
2846 char buf[PATH_MAX+1];
2848 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2850 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2852 if (access (buf, F_OK) != 0) {
2860 error << "FATAL ERROR! Could not find a " << endl;
2869 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2873 char buf[PATH_MAX+1];
2874 const uint32_t limit = 10000;
2878 legalized = legalize_for_path (name);
2880 /* find a "version" of the file name that doesn't exist in
2881 any of the possible directories.
2884 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2886 vector<space_and_path>::iterator i;
2887 uint32_t existing = 0;
2889 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2893 spath += sound_dir (false);
2897 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2898 } else if (nchan == 2) {
2900 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2902 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2904 } else if (nchan < 26) {
2905 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2907 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2916 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2917 } else if (nchan == 2) {
2919 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2921 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2923 } else if (nchan < 26) {
2924 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2926 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2930 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2936 if (existing == 0) {
2941 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2943 throw failed_constructor();
2947 /* we now have a unique name for the file, but figure out where to
2953 spath = discover_best_sound_dir ();
2956 string::size_type pos = foo.find_last_of ('/');
2958 if (pos == string::npos) {
2961 spath += foo.substr (pos + 1);
2967 boost::shared_ptr<AudioFileSource>
2968 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2970 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2971 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2974 /* Playlist management */
2976 boost::shared_ptr<Playlist>
2977 Session::playlist_by_name (string name)
2979 Glib::Mutex::Lock lm (playlist_lock);
2980 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2981 if ((*i)->name() == name) {
2985 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2986 if ((*i)->name() == name) {
2991 return boost::shared_ptr<Playlist>();
2995 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
2997 if (playlist->hidden()) {
3002 Glib::Mutex::Lock lm (playlist_lock);
3003 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3004 playlists.insert (playlists.begin(), playlist);
3005 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3006 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3012 PlaylistAdded (playlist); /* EMIT SIGNAL */
3016 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3019 Glib::Mutex::Lock lm (playlist_lock);
3020 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3023 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3030 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3032 boost::shared_ptr<Playlist> pl(wpl.lock());
3038 PlaylistList::iterator x;
3041 /* its not supposed to be visible */
3046 Glib::Mutex::Lock lm (playlist_lock);
3050 unused_playlists.insert (pl);
3052 if ((x = playlists.find (pl)) != playlists.end()) {
3053 playlists.erase (x);
3059 playlists.insert (pl);
3061 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3062 unused_playlists.erase (x);
3069 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3071 if (_state_of_the_state & Deletion) {
3075 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3082 Glib::Mutex::Lock lm (playlist_lock);
3083 cerr << "removing playlist: " << playlist->name() << endl;
3085 PlaylistList::iterator i;
3087 i = find (playlists.begin(), playlists.end(), playlist);
3088 if (i != playlists.end()) {
3089 cerr << "\tfound it in used playlist\n";
3090 playlists.erase (i);
3093 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3094 if (i != unused_playlists.end()) {
3095 cerr << "\tfound it in unused playlist\n";
3096 unused_playlists.erase (i);
3103 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3107 Session::set_audition (boost::shared_ptr<Region> r)
3109 pending_audition_region = r;
3110 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3111 schedule_butler_transport_work ();
3115 Session::audition_playlist ()
3117 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3118 ev->region.reset ();
3123 Session::non_realtime_set_audition ()
3125 if (!pending_audition_region) {
3126 auditioner->audition_current_playlist ();
3128 auditioner->audition_region (pending_audition_region);
3129 pending_audition_region.reset ();
3131 AuditionActive (true); /* EMIT SIGNAL */
3135 Session::audition_region (boost::shared_ptr<Region> r)
3137 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3143 Session::cancel_audition ()
3145 if (auditioner->active()) {
3146 auditioner->cancel_audition ();
3147 AuditionActive (false); /* EMIT SIGNAL */
3152 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3154 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3158 Session::remove_empty_sounds ()
3160 PathScanner scanner;
3162 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3164 Glib::Mutex::Lock lm (audio_source_lock);
3166 regex_t compiled_tape_track_pattern;
3169 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3173 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3175 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3179 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3181 /* never remove files that appear to be a tape track */
3183 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3188 if (AudioFileSource::is_empty (*this, *(*i))) {
3190 unlink ((*i)->c_str());
3192 string peak_path = peak_path_from_audio_path (**i);
3193 unlink (peak_path.c_str());
3199 delete possible_audiofiles;
3203 Session::is_auditioning () const
3205 /* can be called before we have an auditioner object */
3207 return auditioner->active();
3214 Session::set_all_solo (bool yn)
3216 shared_ptr<RouteList> r = routes.reader ();
3218 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3219 if (!(*i)->hidden()) {
3220 (*i)->set_solo (yn, this);
3228 Session::set_all_mute (bool yn)
3230 shared_ptr<RouteList> r = routes.reader ();
3232 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3233 if (!(*i)->hidden()) {
3234 (*i)->set_mute (yn, this);
3242 Session::n_diskstreams () const
3246 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3248 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3249 if (!(*i)->hidden()) {
3257 Session::graph_reordered ()
3259 /* don't do this stuff if we are setting up connections
3260 from a set_state() call.
3263 if (_state_of_the_state & InitialConnecting) {
3267 /* every track/bus asked for this to be handled but it was deferred because
3268 we were connecting. do it now.
3271 request_input_change_handling ();
3275 /* force all diskstreams to update their capture offset values to
3276 reflect any changes in latencies within the graph.
3279 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3281 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3282 (*i)->set_capture_offset ();
3287 Session::record_disenable_all ()
3289 record_enable_change_all (false);
3293 Session::record_enable_all ()
3295 record_enable_change_all (true);
3299 Session::record_enable_change_all (bool yn)
3301 shared_ptr<RouteList> r = routes.reader ();
3303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3306 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3307 at->set_record_enable (yn, this);
3311 /* since we don't keep rec-enable state, don't mark session dirty */
3315 Session::add_redirect (Redirect* redirect)
3319 PortInsert* port_insert;
3320 PluginInsert* plugin_insert;
3322 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3323 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3324 _port_inserts.insert (_port_inserts.begin(), port_insert);
3325 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3326 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3328 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3331 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3332 _sends.insert (_sends.begin(), send);
3334 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3338 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3344 Session::remove_redirect (Redirect* redirect)
3348 PortInsert* port_insert;
3349 PluginInsert* plugin_insert;
3351 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3352 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3353 _port_inserts.remove (port_insert);
3354 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3355 _plugin_inserts.remove (plugin_insert);
3357 fatal << string_compose (_("programming error: %1"),
3358 X_("unknown type of Insert deleted!"))
3362 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3363 _sends.remove (send);
3365 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3373 Session::available_capture_duration ()
3375 float sample_bytes_on_disk;
3377 switch (Config->get_native_file_data_format()) {
3379 sample_bytes_on_disk = 4;
3383 sample_bytes_on_disk = 3;
3387 /* impossible, but keep some gcc versions happy */
3388 fatal << string_compose (_("programming error: %1"),
3389 X_("illegal native file data format"))
3394 double scale = 4096.0 / sample_bytes_on_disk;
3396 if (_total_free_4k_blocks * scale > (double) max_frames) {
3400 return (nframes_t) floor (_total_free_4k_blocks * scale);
3404 Session::add_connection (ARDOUR::Connection* connection)
3407 Glib::Mutex::Lock guard (connection_lock);
3408 _connections.push_back (connection);
3411 ConnectionAdded (connection); /* EMIT SIGNAL */
3417 Session::remove_connection (ARDOUR::Connection* connection)
3419 bool removed = false;
3422 Glib::Mutex::Lock guard (connection_lock);
3423 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3425 if (i != _connections.end()) {
3426 _connections.erase (i);
3432 ConnectionRemoved (connection); /* EMIT SIGNAL */
3438 ARDOUR::Connection *
3439 Session::connection_by_name (string name) const
3441 Glib::Mutex::Lock lm (connection_lock);
3443 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3444 if ((*i)->name() == name) {
3453 Session::tempo_map_changed (Change ignored)
3460 Session::ensure_passthru_buffers (uint32_t howmany)
3462 while (howmany > _passthru_buffers.size()) {
3464 #ifdef NO_POSIX_MEMALIGN
3465 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3467 posix_memalign((void **)&p,16,current_block_size * 4);
3469 _passthru_buffers.push_back (p);
3473 #ifdef NO_POSIX_MEMALIGN
3474 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3476 posix_memalign((void **)&p,16,current_block_size * 4);
3478 memset (p, 0, sizeof (Sample) * current_block_size);
3479 _silent_buffers.push_back (p);
3483 #ifdef NO_POSIX_MEMALIGN
3484 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3486 posix_memalign((void **)&p,16,current_block_size * 4);
3488 memset (p, 0, sizeof (Sample) * current_block_size);
3489 _send_buffers.push_back (p);
3492 allocate_pan_automation_buffers (current_block_size, howmany, false);
3496 Session::next_send_name ()
3500 shared_ptr<RouteList> r = routes.reader ();
3502 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3503 cnt += (*i)->count_sends ();
3506 return string_compose (_("send %1"), ++cnt);
3510 Session::next_insert_name ()
3513 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3517 /* Named Selection management */
3520 Session::named_selection_by_name (string name)
3522 Glib::Mutex::Lock lm (named_selection_lock);
3523 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3524 if ((*i)->name == name) {
3532 Session::add_named_selection (NamedSelection* named_selection)
3535 Glib::Mutex::Lock lm (named_selection_lock);
3536 named_selections.insert (named_selections.begin(), named_selection);
3541 NamedSelectionAdded (); /* EMIT SIGNAL */
3545 Session::remove_named_selection (NamedSelection* named_selection)
3547 bool removed = false;
3550 Glib::Mutex::Lock lm (named_selection_lock);
3552 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3554 if (i != named_selections.end()) {
3556 named_selections.erase (i);
3563 NamedSelectionRemoved (); /* EMIT SIGNAL */
3568 Session::reset_native_file_format ()
3570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3572 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3573 (*i)->reset_write_sources (false);
3578 Session::route_name_unique (string n) const
3580 shared_ptr<RouteList> r = routes.reader ();
3582 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3583 if ((*i)->name() == n) {
3592 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3594 return fs->move_to_trash (dead_sound_dir_name);
3598 Session::n_playlists () const
3600 Glib::Mutex::Lock lm (playlist_lock);
3601 return playlists.size();
3605 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3607 if (!force && howmany <= _npan_buffers) {
3611 if (_pan_automation_buffer) {
3613 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3614 delete [] _pan_automation_buffer[i];
3617 delete [] _pan_automation_buffer;
3620 _pan_automation_buffer = new pan_t*[howmany];
3622 for (uint32_t i = 0; i < howmany; ++i) {
3623 _pan_automation_buffer[i] = new pan_t[nframes];
3626 _npan_buffers = howmany;
3630 Session::freeze (InterThreadInfo& itt)
3632 shared_ptr<RouteList> r = routes.reader ();
3634 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3638 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3639 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3650 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3651 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3654 boost::shared_ptr<Playlist> playlist;
3655 boost::shared_ptr<AudioFileSource> fsource;
3657 char buf[PATH_MAX+1];
3661 nframes_t this_chunk;
3663 vector<Sample*> buffers;
3665 // any bigger than this seems to cause stack overflows in called functions
3666 const nframes_t chunk_size = (128 * 1024)/4;
3668 g_atomic_int_set (&processing_prohibited, 1);
3670 /* call tree *MUST* hold route_lock */
3672 if ((playlist = track.diskstream()->playlist()) == 0) {
3676 /* external redirects will be a problem */
3678 if (track.has_external_redirects()) {
3682 nchans = track.audio_diskstream()->n_channels();
3684 dir = discover_best_sound_dir ();
3686 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3688 for (x = 0; x < 99999; ++x) {
3689 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3690 if (access (buf, F_OK) != 0) {
3696 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3701 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3704 catch (failed_constructor& err) {
3705 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3709 srcs.push_back (fsource);
3712 /* XXX need to flush all redirects */
3717 /* create a set of reasonably-sized buffers */
3719 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3721 #ifdef NO_POSIX_MEMALIGN
3722 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3724 posix_memalign((void **)&b,16,chunk_size * 4);
3726 buffers.push_back (b);
3729 while (to_do && !itt.cancel) {
3731 this_chunk = min (to_do, chunk_size);
3733 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3738 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3739 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3742 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3748 start += this_chunk;
3749 to_do -= this_chunk;
3751 itt.progress = (float) (1.0 - ((double) to_do / len));
3760 xnow = localtime (&now);
3762 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3763 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3766 afs->update_header (position, *xnow, now);
3770 /* build peakfile for new source */
3772 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3773 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3775 afs->build_peaks ();
3779 /* construct a region to represent the bounced material */
3781 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3782 region_name_from_path (srcs.front()->name(), true));
3789 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3790 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3793 afs->mark_for_remove ();
3796 (*src)->drop_references ();
3800 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3804 g_atomic_int_set (&processing_prohibited, 0);
3812 Session::get_silent_buffers (uint32_t howmany)
3814 for (uint32_t i = 0; i < howmany; ++i) {
3815 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3817 return _silent_buffers;
3821 Session::ntracks () const
3824 shared_ptr<RouteList> r = routes.reader ();
3826 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3827 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3836 Session::nbusses () const
3839 shared_ptr<RouteList> r = routes.reader ();
3841 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3842 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3851 Session::add_automation_list(AutomationList *al)
3853 automation_lists[al->id()] = al;
3857 Session::compute_initial_length ()
3859 return _engine.frame_rate() * 60 * 5;