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>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
68 #include <ardour/source_factory.h>
69 #include <ardour/region_factory.h>
72 #include <ardour/osc.h>
78 using namespace ARDOUR;
80 using boost::shared_ptr;
82 const char* Session::_template_suffix = X_(".template");
83 const char* Session::_statefile_suffix = X_(".ardour");
84 const char* Session::_pending_suffix = X_(".pending");
85 const char* Session::old_sound_dir_name = X_("sounds");
86 const char* Session::sound_dir_name = X_("audiofiles");
87 const char* Session::peak_dir_name = X_("peaks");
88 const char* Session::dead_sound_dir_name = X_("dead_sounds");
89 const char* Session::interchange_dir_name = X_("interchange");
91 Session::compute_peak_t Session::compute_peak = 0;
92 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
93 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
94 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
96 sigc::signal<int> Session::AskAboutPendingState;
97 sigc::signal<void> Session::SendFeedback;
99 sigc::signal<void> Session::SMPTEOffsetChanged;
100 sigc::signal<void> Session::StartTimeChanged;
101 sigc::signal<void> Session::EndTimeChanged;
104 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
107 char buf[PATH_MAX+1];
111 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
112 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
118 /* check to see if it exists, and what it is */
120 if (stat (str.c_str(), &statbuf)) {
121 if (errno == ENOENT) {
124 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
132 /* it exists, so it must either be the name
133 of the directory, or the name of the statefile
137 if (S_ISDIR (statbuf.st_mode)) {
139 string::size_type slash = str.find_last_of ('/');
141 if (slash == string::npos) {
143 /* a subdirectory of cwd, so statefile should be ... */
149 tmp += _statefile_suffix;
153 if (stat (tmp.c_str(), &statbuf)) {
154 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
164 /* some directory someplace in the filesystem.
165 the snapshot name is the directory name
170 snapshot = str.substr (slash+1);
174 } else if (S_ISREG (statbuf.st_mode)) {
176 string::size_type slash = str.find_last_of ('/');
177 string::size_type suffix;
179 /* remove the suffix */
181 if (slash != string::npos) {
182 snapshot = str.substr (slash+1);
187 suffix = snapshot.find (_statefile_suffix);
189 if (suffix == string::npos) {
190 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
196 snapshot = snapshot.substr (0, suffix);
198 if (slash == string::npos) {
200 /* we must be in the directory where the
201 statefile lives. get it using cwd().
204 char cwd[PATH_MAX+1];
206 if (getcwd (cwd, sizeof (cwd)) == 0) {
207 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
216 /* full path to the statefile */
218 path = str.substr (0, slash);
223 /* what type of file is it? */
224 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
230 /* its the name of a new directory. get the name
234 string::size_type slash = str.find_last_of ('/');
236 if (slash == string::npos) {
238 /* no slash, just use the name, but clean it up */
240 path = legalize_for_path (str);
246 snapshot = str.substr (slash+1);
253 Session::Session (AudioEngine &eng,
255 string snapshot_name,
256 string* mix_template)
259 _mmc_port (default_mmc_port),
260 _mtc_port (default_mtc_port),
261 _midi_port (default_midi_port),
262 pending_events (2048),
263 midi_requests (128), // the size of this should match the midi request pool size
264 diskstreams (new DiskstreamList),
265 routes (new RouteList),
266 auditioner ((Auditioner*) 0),
272 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
274 n_physical_outputs = _engine.n_physical_outputs();
275 n_physical_inputs = _engine.n_physical_inputs();
277 first_stage_init (fullpath, snapshot_name);
279 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
281 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
282 cerr << "create failed\n";
283 throw failed_constructor ();
287 if (second_stage_init (new_session)) {
288 cerr << "2nd state failed\n";
289 throw failed_constructor ();
292 store_recent_sessions(_name, _path);
294 bool was_dirty = dirty();
296 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
298 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
301 DirtyChanged (); /* EMIT SIGNAL */
305 Session::Session (AudioEngine &eng,
307 string snapshot_name,
308 AutoConnectOption input_ac,
309 AutoConnectOption output_ac,
310 uint32_t control_out_channels,
311 uint32_t master_out_channels,
312 uint32_t requested_physical_in,
313 uint32_t requested_physical_out,
314 nframes_t initial_length)
317 _mmc_port (default_mmc_port),
318 _mtc_port (default_mtc_port),
319 _midi_port (default_midi_port),
320 pending_events (2048),
322 diskstreams (new DiskstreamList),
323 routes (new RouteList),
329 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
331 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
332 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
334 first_stage_init (fullpath, snapshot_name);
336 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
338 if (create (new_session, 0, initial_length)) {
339 throw failed_constructor ();
343 if (control_out_channels) {
344 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
351 if (master_out_channels) {
352 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
358 /* prohibit auto-connect to master, because there isn't one */
359 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
362 Config->set_input_auto_connect (input_ac);
363 Config->set_output_auto_connect (output_ac);
365 if (second_stage_init (new_session)) {
366 throw failed_constructor ();
369 store_recent_sessions(_name, _path);
371 bool was_dirty = dirty ();
373 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
376 DirtyChanged (); /* EMIT SIGNAL */
382 /* if we got to here, leaving pending capture state around
386 remove_pending_capture_state ();
388 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
389 _engine.remove_session ();
391 GoingAway (); /* EMIT SIGNAL */
397 /* clear history so that no references to objects are held any more */
401 /* clear state tree so that no references to objects are held any more */
407 terminate_butler_thread ();
408 terminate_midi_thread ();
410 if (click_data && click_data != default_click) {
411 delete [] click_data;
414 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
415 delete [] click_emphasis_data;
420 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
424 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
428 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
432 AudioDiskstream::free_working_buffers();
434 #undef TRACK_DESTRUCTION
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete named selections\n";
437 #endif /* TRACK_DESTRUCTION */
438 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
439 NamedSelectionList::iterator tmp;
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete playlists\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
452 PlaylistList::iterator tmp;
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete audio regions\n";
464 #endif /* TRACK_DESTRUCTION */
466 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
467 AudioRegionList::iterator tmp;
472 i->second->drop_references ();
477 audio_regions.clear ();
479 #ifdef TRACK_DESTRUCTION
480 cerr << "delete routes\n";
481 #endif /* TRACK_DESTRUCTION */
483 RCUWriter<RouteList> writer (routes);
484 boost::shared_ptr<RouteList> r = writer.get_copy ();
485 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
486 (*i)->drop_references ();
489 /* writer goes out of scope and updates master */
494 #ifdef TRACK_DESTRUCTION
495 cerr << "delete diskstreams\n";
496 #endif /* TRACK_DESTRUCTION */
498 RCUWriter<DiskstreamList> dwriter (diskstreams);
499 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
500 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
501 (*i)->drop_references ();
505 diskstreams.flush ();
507 #ifdef TRACK_DESTRUCTION
508 cerr << "delete audio sources\n";
509 #endif /* TRACK_DESTRUCTION */
510 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
511 AudioSourceList::iterator tmp;
516 i->second->drop_references ();
521 audio_sources.clear ();
523 #ifdef TRACK_DESTRUCTION
524 cerr << "delete mix groups\n";
525 #endif /* TRACK_DESTRUCTION */
526 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
527 list<RouteGroup*>::iterator tmp;
537 #ifdef TRACK_DESTRUCTION
538 cerr << "delete edit groups\n";
539 #endif /* TRACK_DESTRUCTION */
540 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
541 list<RouteGroup*>::iterator tmp;
551 #ifdef TRACK_DESTRUCTION
552 cerr << "delete connections\n";
553 #endif /* TRACK_DESTRUCTION */
554 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
555 ConnectionList::iterator tmp;
565 if (butler_mixdown_buffer) {
566 delete [] butler_mixdown_buffer;
569 if (butler_gain_buffer) {
570 delete [] butler_gain_buffer;
573 Crossfade::set_buffer_size (0);
581 Session::set_worst_io_latencies ()
583 _worst_output_latency = 0;
584 _worst_input_latency = 0;
586 if (!_engine.connected()) {
590 boost::shared_ptr<RouteList> r = routes.reader ();
592 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
593 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
594 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
599 Session::when_engine_running ()
601 string first_physical_output;
603 /* we don't want to run execute this again */
605 first_time_running.disconnect ();
607 set_block_size (_engine.frames_per_cycle());
608 set_frame_rate (_engine.frame_rate());
610 Config->map_parameters (mem_fun (*this, &Session::config_changed));
612 /* every time we reconnect, recompute worst case output latencies */
614 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
616 if (synced_to_jack()) {
617 _engine.transport_stop ();
620 if (Config->get_jack_time_master()) {
621 _engine.transport_locate (_transport_frame);
629 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
631 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
633 /* existing state for Click */
635 if (_click_io->set_state (*child->children().front()) == 0) {
637 _clicking = Config->get_clicking ();
641 error << _("could not setup Click I/O") << endmsg;
647 /* default state for Click */
649 first_physical_output = _engine.get_nth_physical_output (0);
651 if (first_physical_output.length()) {
652 if (_click_io->add_output_port (first_physical_output, this)) {
653 // relax, even though its an error
655 _clicking = Config->get_clicking ();
661 catch (failed_constructor& err) {
662 error << _("cannot setup Click I/O") << endmsg;
665 set_worst_io_latencies ();
668 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
671 if (auditioner == 0) {
673 /* we delay creating the auditioner till now because
674 it makes its own connections to ports named
675 in the ARDOUR_RC config file. the engine has
676 to be running for this to work.
680 auditioner.reset (new Auditioner (*this));
683 catch (failed_constructor& err) {
684 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
688 /* Create a set of Connection objects that map
689 to the physical outputs currently available
694 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
696 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
698 Connection* c = new OutputConnection (buf, true);
701 c->add_connection (0, _engine.get_nth_physical_output (np));
706 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
708 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
710 Connection* c = new InputConnection (buf, true);
713 c->add_connection (0, _engine.get_nth_physical_input (np));
720 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
722 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
724 Connection* c = new OutputConnection (buf, true);
728 c->add_connection (0, _engine.get_nth_physical_output (np));
729 c->add_connection (1, _engine.get_nth_physical_output (np+1));
734 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
736 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
738 Connection* c = new InputConnection (buf, true);
742 c->add_connection (0, _engine.get_nth_physical_input (np));
743 c->add_connection (1, _engine.get_nth_physical_input (np+1));
752 /* create master/control ports */
757 /* force the master to ignore any later call to this */
759 if (_master_out->pending_state_node) {
760 _master_out->ports_became_legal();
763 /* no panner resets till we are through */
765 _master_out->defer_pan_reset ();
767 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
768 if (_master_out->add_input_port ("", this)) {
769 error << _("cannot setup master inputs")
775 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
776 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
777 error << _("cannot setup master outputs")
784 _master_out->allow_pan_reset ();
788 Connection* c = new OutputConnection (_("Master Out"), true);
790 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
792 c->add_connection ((int) n, _master_out->input(n)->name());
799 /* catch up on send+insert cnts */
803 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
806 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
807 if (id > insert_cnt) {
815 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
818 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
825 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
827 /* hook us up to the engine */
829 _engine.set_session (this);
834 osc->set_session (*this);
837 _state_of_the_state = Clean;
839 DirtyChanged (); /* EMIT SIGNAL */
843 Session::hookup_io ()
845 /* stop graph reordering notifications from
846 causing resorts, etc.
849 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
851 /* Tell all IO objects to create their ports */
858 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
859 if (_control_out->add_input_port ("", this)) {
860 error << _("cannot setup control inputs")
866 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
867 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
868 error << _("cannot set up master outputs")
876 /* Tell all IO objects to connect themselves together */
878 IO::enable_connecting ();
880 /* Now reset all panners */
882 IO::reset_panners ();
884 /* Anyone who cares about input state, wake up and do something */
886 IOConnectionsComplete (); /* EMIT SIGNAL */
888 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
890 /* now handle the whole enchilada as if it was one
896 /* update mixer solo state */
902 Session::playlist_length_changed (Playlist* pl)
904 /* we can't just increase end_location->end() if pl->get_maximum_extent()
905 if larger. if the playlist used to be the longest playlist,
906 and its now shorter, we have to decrease end_location->end(). hence,
907 we have to iterate over all diskstreams and check the
908 playlists currently in use.
914 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
918 if ((playlist = dstream->playlist()) != 0) {
919 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
922 /* see comment in playlist_length_changed () */
927 Session::record_enabling_legal () const
929 /* this used to be in here, but survey says.... we don't need to restrict it */
930 // if (record_status() == Recording) {
934 if (Config->get_all_safe()) {
941 Session::reset_input_monitor_state ()
943 if (transport_rolling()) {
945 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
947 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
948 if ((*i)->record_enabled ()) {
949 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
950 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
954 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
956 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
957 if ((*i)->record_enabled ()) {
958 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
959 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
966 Session::auto_punch_start_changed (Location* location)
968 replace_event (Event::PunchIn, location->start());
970 if (get_record_enabled() && Config->get_punch_in()) {
971 /* capture start has been changed, so save new pending state */
972 save_state ("", true);
977 Session::auto_punch_end_changed (Location* location)
979 nframes_t when_to_stop = location->end();
980 // when_to_stop += _worst_output_latency + _worst_input_latency;
981 replace_event (Event::PunchOut, when_to_stop);
985 Session::auto_punch_changed (Location* location)
987 nframes_t when_to_stop = location->end();
989 replace_event (Event::PunchIn, location->start());
990 //when_to_stop += _worst_output_latency + _worst_input_latency;
991 replace_event (Event::PunchOut, when_to_stop);
995 Session::auto_loop_changed (Location* location)
997 replace_event (Event::AutoLoop, location->end(), location->start());
999 if (transport_rolling() && play_loop) {
1001 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1003 if (_transport_frame > location->end()) {
1004 // relocate to beginning of loop
1005 clear_events (Event::LocateRoll);
1007 request_locate (location->start(), true);
1010 else if (Config->get_seamless_loop() && !loop_changing) {
1012 // schedule a locate-roll to refill the diskstreams at the
1013 // previous loop end
1014 loop_changing = true;
1016 if (location->end() > last_loopend) {
1017 clear_events (Event::LocateRoll);
1018 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1025 last_loopend = location->end();
1030 Session::set_auto_punch_location (Location* location)
1034 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1035 auto_punch_start_changed_connection.disconnect();
1036 auto_punch_end_changed_connection.disconnect();
1037 auto_punch_changed_connection.disconnect();
1038 existing->set_auto_punch (false, this);
1039 remove_event (existing->start(), Event::PunchIn);
1040 clear_events (Event::PunchOut);
1041 auto_punch_location_changed (0);
1046 if (location == 0) {
1050 if (location->end() <= location->start()) {
1051 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1055 auto_punch_start_changed_connection.disconnect();
1056 auto_punch_end_changed_connection.disconnect();
1057 auto_punch_changed_connection.disconnect();
1059 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1060 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1061 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1063 location->set_auto_punch (true, this);
1064 auto_punch_location_changed (location);
1068 Session::set_auto_loop_location (Location* location)
1072 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1073 auto_loop_start_changed_connection.disconnect();
1074 auto_loop_end_changed_connection.disconnect();
1075 auto_loop_changed_connection.disconnect();
1076 existing->set_auto_loop (false, this);
1077 remove_event (existing->end(), Event::AutoLoop);
1078 auto_loop_location_changed (0);
1083 if (location == 0) {
1087 if (location->end() <= location->start()) {
1088 error << _("Session: you can't use a mark for auto loop") << endmsg;
1092 last_loopend = location->end();
1094 auto_loop_start_changed_connection.disconnect();
1095 auto_loop_end_changed_connection.disconnect();
1096 auto_loop_changed_connection.disconnect();
1098 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1099 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1100 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1102 location->set_auto_loop (true, this);
1103 auto_loop_location_changed (location);
1107 Session::locations_added (Location* ignored)
1113 Session::locations_changed ()
1115 _locations.apply (*this, &Session::handle_locations_changed);
1119 Session::handle_locations_changed (Locations::LocationList& locations)
1121 Locations::LocationList::iterator i;
1123 bool set_loop = false;
1124 bool set_punch = false;
1126 for (i = locations.begin(); i != locations.end(); ++i) {
1130 if (location->is_auto_punch()) {
1131 set_auto_punch_location (location);
1134 if (location->is_auto_loop()) {
1135 set_auto_loop_location (location);
1142 set_auto_loop_location (0);
1145 set_auto_punch_location (0);
1152 Session::enable_record ()
1154 /* XXX really atomic compare+swap here */
1155 if (g_atomic_int_get (&_record_status) != Recording) {
1156 g_atomic_int_set (&_record_status, Recording);
1157 _last_record_location = _transport_frame;
1158 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1160 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1161 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1162 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1163 if ((*i)->record_enabled ()) {
1164 (*i)->monitor_input (true);
1169 RecordStateChanged ();
1174 Session::disable_record (bool rt_context, bool force)
1178 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1180 if (!Config->get_latched_record_enable () || force) {
1181 g_atomic_int_set (&_record_status, Disabled);
1183 if (rs == Recording) {
1184 g_atomic_int_set (&_record_status, Enabled);
1188 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1190 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1191 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1193 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1194 if ((*i)->record_enabled ()) {
1195 (*i)->monitor_input (false);
1200 RecordStateChanged (); /* emit signal */
1203 remove_pending_capture_state ();
1209 Session::step_back_from_record ()
1211 g_atomic_int_set (&_record_status, Enabled);
1213 if (Config->get_monitoring_model() == HardwareMonitoring) {
1214 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1216 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1217 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1218 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1219 (*i)->monitor_input (false);
1226 Session::maybe_enable_record ()
1228 g_atomic_int_set (&_record_status, Enabled);
1230 /* this function is currently called from somewhere other than an RT thread.
1231 this save_state() call therefore doesn't impact anything.
1234 save_state ("", true);
1236 if (_transport_speed) {
1237 if (!Config->get_punch_in()) {
1241 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1242 RecordStateChanged (); /* EMIT SIGNAL */
1249 Session::audible_frame () const
1255 /* the first of these two possible settings for "offset"
1256 mean that the audible frame is stationary until
1257 audio emerges from the latency compensation
1260 the second means that the audible frame is stationary
1261 until audio would emerge from a physical port
1262 in the absence of any plugin latency compensation
1265 offset = _worst_output_latency;
1267 if (offset > current_block_size) {
1268 offset -= current_block_size;
1270 /* XXX is this correct? if we have no external
1271 physical connections and everything is internal
1272 then surely this is zero? still, how
1273 likely is that anyway?
1275 offset = current_block_size;
1278 if (synced_to_jack()) {
1279 tf = _engine.transport_frame();
1281 tf = _transport_frame;
1284 if (_transport_speed == 0) {
1294 if (!non_realtime_work_pending()) {
1298 /* take latency into account */
1307 Session::set_frame_rate (nframes_t frames_per_second)
1309 /** \fn void Session::set_frame_size(nframes_t)
1310 the AudioEngine object that calls this guarantees
1311 that it will not be called while we are also in
1312 ::process(). Its fine to do things that block
1316 _base_frame_rate = frames_per_second;
1320 // XXX we need some equivalent to this, somehow
1321 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1325 /* XXX need to reset/reinstantiate all LADSPA plugins */
1329 Session::set_block_size (nframes_t nframes)
1331 /* the AudioEngine guarantees
1332 that it will not be called while we are also in
1333 ::process(). It is therefore fine to do things that block
1338 vector<Sample*>::iterator i;
1341 current_block_size = nframes;
1343 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1347 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1351 _passthru_buffers.clear ();
1352 _silent_buffers.clear ();
1354 ensure_passthru_buffers (np);
1356 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1360 #ifdef NO_POSIX_MEMALIGN
1361 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1363 posix_memalign((void **)&buf,16,current_block_size * 4);
1367 memset (*i, 0, sizeof (Sample) * current_block_size);
1371 if (_gain_automation_buffer) {
1372 delete [] _gain_automation_buffer;
1374 _gain_automation_buffer = new gain_t[nframes];
1376 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1378 boost::shared_ptr<RouteList> r = routes.reader ();
1380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1381 (*i)->set_block_size (nframes);
1384 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1385 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1386 (*i)->set_block_size (nframes);
1389 set_worst_io_latencies ();
1394 Session::set_default_fade (float steepness, float fade_msecs)
1397 nframes_t fade_frames;
1399 /* Don't allow fade of less 1 frame */
1401 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1408 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1412 default_fade_msecs = fade_msecs;
1413 default_fade_steepness = steepness;
1416 // jlc, WTF is this!
1417 Glib::RWLock::ReaderLock lm (route_lock);
1418 AudioRegion::set_default_fade (steepness, fade_frames);
1423 /* XXX have to do this at some point */
1424 /* foreach region using default fade, reset, then
1425 refill_all_diskstream_buffers ();
1430 struct RouteSorter {
1431 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1432 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1434 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1437 if (r1->fed_by.empty()) {
1438 if (r2->fed_by.empty()) {
1439 /* no ardour-based connections inbound to either route. just use signal order */
1440 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1442 /* r2 has connections, r1 does not; run r1 early */
1446 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1453 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1455 shared_ptr<Route> r2;
1457 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1458 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1462 /* make a copy of the existing list of routes that feed r1 */
1464 set<shared_ptr<Route> > existing = r1->fed_by;
1466 /* for each route that feeds r1, recurse, marking it as feeding
1470 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1473 /* r2 is a route that feeds r1 which somehow feeds base. mark
1474 base as being fed by r2
1477 rbase->fed_by.insert (r2);
1481 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1485 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1489 /* now recurse, so that we can mark base as being fed by
1490 all routes that feed r2
1493 trace_terminal (r2, rbase);
1500 Session::resort_routes ()
1502 /* don't do anything here with signals emitted
1503 by Routes while we are being destroyed.
1506 if (_state_of_the_state & Deletion) {
1513 RCUWriter<RouteList> writer (routes);
1514 shared_ptr<RouteList> r = writer.get_copy ();
1515 resort_routes_using (r);
1516 /* writer goes out of scope and forces update */
1521 Session::resort_routes_using (shared_ptr<RouteList> r)
1523 RouteList::iterator i, j;
1525 for (i = r->begin(); i != r->end(); ++i) {
1527 (*i)->fed_by.clear ();
1529 for (j = r->begin(); j != r->end(); ++j) {
1531 /* although routes can feed themselves, it will
1532 cause an endless recursive descent if we
1533 detect it. so don't bother checking for
1541 if ((*j)->feeds (*i)) {
1542 (*i)->fed_by.insert (*j);
1547 for (i = r->begin(); i != r->end(); ++i) {
1548 trace_terminal (*i, *i);
1555 cerr << "finished route resort\n";
1557 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1558 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1565 list<boost::shared_ptr<AudioTrack> >
1566 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1568 char track_name[32];
1569 uint32_t track_id = 0;
1571 uint32_t channels_used = 0;
1573 RouteList new_routes;
1574 list<boost::shared_ptr<AudioTrack> > ret;
1576 /* count existing audio tracks */
1579 shared_ptr<RouteList> r = routes.reader ();
1581 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1582 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1583 if (!(*i)->hidden()) {
1585 channels_used += (*i)->n_inputs();
1591 vector<string> physinputs;
1592 vector<string> physoutputs;
1593 uint32_t nphysical_in;
1594 uint32_t nphysical_out;
1596 _engine.get_physical_outputs (physoutputs);
1597 _engine.get_physical_inputs (physinputs);
1601 /* check for duplicate route names, since we might have pre-existing
1602 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1603 save, close,restart,add new route - first named route is now
1611 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1613 if (route_by_name (track_name) == 0) {
1617 } while (track_id < (UINT_MAX-1));
1619 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1620 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1625 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1626 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1632 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1634 if (track->ensure_io (input_channels, output_channels, false, this)) {
1635 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1636 input_channels, output_channels)
1641 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1645 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1646 port = physinputs[(channels_used+x)%nphysical_in];
1649 if (port.length() && track->connect_input (track->input (x), port, this)) {
1655 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1659 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1660 port = physoutputs[(channels_used+x)%nphysical_out];
1661 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1663 port = _master_out->input (x%_master_out->n_inputs())->name();
1667 if (port.length() && track->connect_output (track->output (x), port, this)) {
1672 channels_used += track->n_inputs ();
1675 vector<string> cports;
1676 uint32_t ni = _control_out->n_inputs();
1678 for (n = 0; n < ni; ++n) {
1679 cports.push_back (_control_out->input(n)->name());
1682 track->set_control_outs (cports);
1685 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1686 track->set_remote_control_id (ntracks());
1688 new_routes.push_back (track);
1689 ret.push_back (track);
1692 catch (failed_constructor &err) {
1693 error << _("Session: could not create new audio track.") << endmsg;
1694 // XXX should we delete the tracks already created?
1702 if (!new_routes.empty()) {
1703 add_routes (new_routes, false);
1704 save_state (_current_snapshot_name);
1711 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1714 uint32_t bus_id = 1;
1719 /* count existing audio busses */
1722 shared_ptr<RouteList> r = routes.reader ();
1724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1725 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1726 if (!(*i)->hidden()) {
1733 vector<string> physinputs;
1734 vector<string> physoutputs;
1736 _engine.get_physical_outputs (physoutputs);
1737 _engine.get_physical_inputs (physinputs);
1744 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1746 if (route_by_name (bus_name) == 0) {
1750 } while (bus_id < (UINT_MAX-1));
1753 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1755 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1756 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1757 input_channels, output_channels)
1761 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1765 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1766 port = physinputs[((n+x)%n_physical_inputs)];
1769 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1774 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1778 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1779 port = physoutputs[((n+x)%n_physical_outputs)];
1780 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1782 port = _master_out->input (x%_master_out->n_inputs())->name();
1786 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1792 vector<string> cports;
1793 uint32_t ni = _control_out->n_inputs();
1795 for (uint32_t n = 0; n < ni; ++n) {
1796 cports.push_back (_control_out->input(n)->name());
1798 bus->set_control_outs (cports);
1801 ret.push_back (bus);
1805 catch (failed_constructor &err) {
1806 error << _("Session: could not create new audio route.") << endmsg;
1815 add_routes (ret, false);
1816 save_state (_current_snapshot_name);
1824 Session::add_routes (RouteList& new_routes, bool save)
1827 RCUWriter<RouteList> writer (routes);
1828 shared_ptr<RouteList> r = writer.get_copy ();
1829 r->insert (r->end(), new_routes.begin(), new_routes.end());
1830 resort_routes_using (r);
1833 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1835 boost::weak_ptr<Route> wpr (*x);
1837 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1838 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1839 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1840 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1842 if ((*x)->master()) {
1846 if ((*x)->control()) {
1847 _control_out = (*x);
1854 save_state (_current_snapshot_name);
1857 RouteAdded (new_routes); /* EMIT SIGNAL */
1861 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1863 /* need to do this in case we're rolling at the time, to prevent false underruns */
1864 dstream->do_refill_with_alloc();
1867 RCUWriter<DiskstreamList> writer (diskstreams);
1868 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1869 ds->push_back (dstream);
1872 dstream->set_block_size (current_block_size);
1874 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1875 /* this will connect to future changes, and check the current length */
1876 diskstream_playlist_changed (dstream);
1878 dstream->prepare ();
1882 Session::remove_route (shared_ptr<Route> route)
1885 RCUWriter<RouteList> writer (routes);
1886 shared_ptr<RouteList> rs = writer.get_copy ();
1889 /* deleting the master out seems like a dumb
1890 idea, but its more of a UI policy issue
1894 if (route == _master_out) {
1895 _master_out = shared_ptr<Route> ();
1898 if (route == _control_out) {
1899 _control_out = shared_ptr<Route> ();
1901 /* cancel control outs for all routes */
1903 vector<string> empty;
1905 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1906 (*r)->set_control_outs (empty);
1910 update_route_solo_state ();
1912 /* writer goes out of scope, forces route list update */
1915 // FIXME: audio specific
1917 boost::shared_ptr<AudioDiskstream> ds;
1919 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1920 ds = at->audio_diskstream();
1926 RCUWriter<DiskstreamList> dsl (diskstreams);
1927 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1932 find_current_end ();
1934 update_latency_compensation (false, false);
1937 // We need to disconnect the routes inputs and outputs
1938 route->disconnect_inputs(NULL);
1939 route->disconnect_outputs(NULL);
1941 /* get rid of it from the dead wood collection in the route list manager */
1943 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1947 /* try to cause everyone to drop their references */
1949 route->drop_references ();
1951 /* save the new state of the world */
1953 if (save_state (_current_snapshot_name)) {
1954 save_history (_current_snapshot_name);
1959 Session::route_mute_changed (void* src)
1965 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1967 if (solo_update_disabled) {
1973 boost::shared_ptr<Route> route = wpr.lock ();
1976 /* should not happen */
1977 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1981 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1983 shared_ptr<RouteList> r = routes.reader ();
1985 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1987 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1991 /* don't mess with busses */
1993 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1999 /* don't mess with tracks */
2001 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2006 if ((*i) != route &&
2007 ((*i)->mix_group () == 0 ||
2008 (*i)->mix_group () != route->mix_group () ||
2009 !route->mix_group ()->is_active())) {
2011 if ((*i)->soloed()) {
2013 /* if its already soloed, and solo latching is enabled,
2014 then leave it as it is.
2017 if (Config->get_solo_latched()) {
2024 solo_update_disabled = true;
2025 (*i)->set_solo (false, src);
2026 solo_update_disabled = false;
2030 bool something_soloed = false;
2031 bool same_thing_soloed = false;
2032 bool signal = false;
2034 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2035 if ((*i)->soloed()) {
2036 something_soloed = true;
2037 if (dynamic_cast<AudioTrack*>((*i).get())) {
2039 same_thing_soloed = true;
2044 same_thing_soloed = true;
2052 if (something_soloed != currently_soloing) {
2054 currently_soloing = something_soloed;
2057 modify_solo_mute (is_track, same_thing_soloed);
2060 SoloActive (currently_soloing);
2067 Session::update_route_solo_state ()
2070 bool is_track = false;
2071 bool signal = false;
2073 /* caller must hold RouteLock */
2075 /* this is where we actually implement solo by changing
2076 the solo mute setting of each track.
2079 shared_ptr<RouteList> r = routes.reader ();
2081 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2082 if ((*i)->soloed()) {
2084 if (dynamic_cast<AudioTrack*>((*i).get())) {
2091 if (mute != currently_soloing) {
2093 currently_soloing = mute;
2096 if (!is_track && !mute) {
2098 /* nothing is soloed */
2100 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2101 (*i)->set_solo_mute (false);
2111 modify_solo_mute (is_track, mute);
2114 SoloActive (currently_soloing);
2119 Session::modify_solo_mute (bool is_track, bool mute)
2121 shared_ptr<RouteList> r = routes.reader ();
2123 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2127 /* only alter track solo mute */
2129 if (dynamic_cast<AudioTrack*>((*i).get())) {
2130 if ((*i)->soloed()) {
2131 (*i)->set_solo_mute (!mute);
2133 (*i)->set_solo_mute (mute);
2139 /* only alter bus solo mute */
2141 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2143 if ((*i)->soloed()) {
2145 (*i)->set_solo_mute (false);
2149 /* don't mute master or control outs
2150 in response to another bus solo
2153 if ((*i) != _master_out &&
2154 (*i) != _control_out) {
2155 (*i)->set_solo_mute (mute);
2166 Session::catch_up_on_solo ()
2168 /* this is called after set_state() to catch the full solo
2169 state, which can't be correctly determined on a per-route
2170 basis, but needs the global overview that only the session
2173 update_route_solo_state();
2177 Session::route_by_name (string name)
2179 shared_ptr<RouteList> r = routes.reader ();
2181 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2182 if ((*i)->name() == name) {
2187 return shared_ptr<Route> ((Route*) 0);
2191 Session::route_by_id (PBD::ID id)
2193 shared_ptr<RouteList> r = routes.reader ();
2195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2196 if ((*i)->id() == id) {
2201 return shared_ptr<Route> ((Route*) 0);
2205 Session::route_by_remote_id (uint32_t id)
2207 shared_ptr<RouteList> r = routes.reader ();
2209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2210 if ((*i)->remote_control_id() == id) {
2215 return shared_ptr<Route> ((Route*) 0);
2219 Session::find_current_end ()
2221 if (_state_of_the_state & Loading) {
2225 nframes_t max = get_maximum_extent ();
2227 if (max > end_location->end()) {
2228 end_location->set_end (max);
2230 DurationChanged(); /* EMIT SIGNAL */
2235 Session::get_maximum_extent () const
2240 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2242 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2243 Playlist* pl = (*i)->playlist();
2244 if ((me = pl->get_maximum_extent()) > max) {
2252 boost::shared_ptr<Diskstream>
2253 Session::diskstream_by_name (string name)
2255 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2257 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2258 if ((*i)->name() == name) {
2263 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2266 boost::shared_ptr<Diskstream>
2267 Session::diskstream_by_id (const PBD::ID& id)
2269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2272 if ((*i)->id() == id) {
2277 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2280 /* AudioRegion management */
2283 Session::new_region_name (string old)
2285 string::size_type last_period;
2287 string::size_type len = old.length() + 64;
2290 if ((last_period = old.find_last_of ('.')) == string::npos) {
2292 /* no period present - add one explicitly */
2295 last_period = old.length() - 1;
2300 number = atoi (old.substr (last_period+1).c_str());
2304 while (number < (UINT_MAX-1)) {
2306 AudioRegionList::const_iterator i;
2311 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2314 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2315 if (i->second->name() == sbuf) {
2320 if (i == audio_regions.end()) {
2325 if (number != (UINT_MAX-1)) {
2329 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2334 Session::region_name (string& result, string base, bool newlevel) const
2341 Glib::Mutex::Lock lm (region_lock);
2343 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2351 /* XXX this is going to be slow. optimize me later */
2356 string::size_type pos;
2358 pos = base.find_last_of ('.');
2360 /* pos may be npos, but then we just use entire base */
2362 subbase = base.substr (0, pos);
2366 bool name_taken = true;
2369 Glib::Mutex::Lock lm (region_lock);
2371 for (int n = 1; n < 5000; ++n) {
2374 snprintf (buf, sizeof (buf), ".%d", n);
2379 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2380 if (i->second->name() == result) {
2393 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2401 Session::add_region (boost::shared_ptr<Region> region)
2403 boost::shared_ptr<AudioRegion> ar;
2404 boost::shared_ptr<AudioRegion> oar;
2408 Glib::Mutex::Lock lm (region_lock);
2410 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2412 AudioRegionList::iterator x;
2414 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2416 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2418 if (ar->region_list_equivalent (oar)) {
2423 if (x == audio_regions.end()) {
2425 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2427 entry.first = region->id();
2430 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2442 fatal << _("programming error: ")
2443 << X_("unknown region type passed to Session::add_region()")
2450 /* mark dirty because something has changed even if we didn't
2451 add the region to the region list.
2457 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2458 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2459 AudioRegionAdded (ar); /* EMIT SIGNAL */
2464 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2466 boost::shared_ptr<Region> region (weak_region.lock ());
2472 if (what_changed & Region::HiddenChanged) {
2473 /* relay hidden changes */
2474 RegionHiddenChange (region);
2479 Session::remove_region (boost::weak_ptr<Region> weak_region)
2481 AudioRegionList::iterator i;
2482 boost::shared_ptr<Region> region (weak_region.lock ());
2488 boost::shared_ptr<AudioRegion> ar;
2489 bool removed = false;
2492 Glib::Mutex::Lock lm (region_lock);
2494 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2495 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2496 audio_regions.erase (i);
2502 fatal << _("programming error: ")
2503 << X_("unknown region type passed to Session::remove_region()")
2509 /* mark dirty because something has changed even if we didn't
2510 remove the region from the region list.
2516 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2520 boost::shared_ptr<AudioRegion>
2521 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2523 AudioRegionList::iterator i;
2524 boost::shared_ptr<AudioRegion> region;
2525 Glib::Mutex::Lock lm (region_lock);
2527 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2531 if (region->whole_file()) {
2533 if (child->source_equivalent (region)) {
2539 return boost::shared_ptr<AudioRegion> ();
2543 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2545 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2546 (*i)->get_region_list_equivalent_regions (region, result);
2550 Session::destroy_region (boost::shared_ptr<Region> region)
2552 boost::shared_ptr<AudioRegion> aregion;
2554 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2558 if (aregion->playlist()) {
2559 aregion->playlist()->destroy_region (region);
2562 vector<boost::shared_ptr<Source> > srcs;
2564 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2565 srcs.push_back (aregion->source (n));
2568 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2570 if ((*i).use_count() == 1) {
2571 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2574 (afs)->mark_for_remove ();
2577 (*i)->drop_references ();
2585 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2587 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2588 destroy_region (*i);
2594 Session::remove_last_capture ()
2596 list<boost::shared_ptr<Region> > r;
2598 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2600 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2601 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2604 r.insert (r.end(), l.begin(), l.end());
2609 destroy_regions (r);
2614 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2620 /* Source Management */
2623 Session::add_source (boost::shared_ptr<Source> source)
2625 boost::shared_ptr<AudioFileSource> afs;
2627 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2629 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2630 pair<AudioSourceList::iterator,bool> result;
2632 entry.first = source->id();
2636 Glib::Mutex::Lock lm (audio_source_lock);
2637 result = audio_sources.insert (entry);
2640 if (!result.second) {
2641 cerr << "\tNOT inserted ? " << result.second << endl;
2644 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2647 SourceAdded (source); /* EMIT SIGNAL */
2649 cerr << "\tNOT AUDIO FILE\n";
2654 Session::remove_source (boost::weak_ptr<Source> src)
2656 AudioSourceList::iterator i;
2657 boost::shared_ptr<Source> source = src.lock();
2664 Glib::Mutex::Lock lm (audio_source_lock);
2666 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2667 audio_sources.erase (i);
2671 if (!_state_of_the_state & InCleanup) {
2673 /* save state so we don't end up with a session file
2674 referring to non-existent sources.
2677 save_state (_current_snapshot_name);
2680 SourceRemoved(source); /* EMIT SIGNAL */
2683 boost::shared_ptr<Source>
2684 Session::source_by_id (const PBD::ID& id)
2686 Glib::Mutex::Lock lm (audio_source_lock);
2687 AudioSourceList::iterator i;
2688 boost::shared_ptr<Source> source;
2690 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2694 /* XXX search MIDI or other searches here */
2700 Session::peak_path_from_audio_path (string audio_path) const
2705 res += PBD::basename_nosuffix (audio_path);
2712 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2715 string old_basename = PBD::basename_nosuffix (oldname);
2716 string new_legalized = legalize_for_path (newname);
2718 /* note: we know (or assume) the old path is already valid */
2722 /* destructive file sources have a name of the form:
2724 /path/to/Tnnnn-NAME(%[LR])?.wav
2726 the task here is to replace NAME with the new name.
2729 /* find last slash */
2733 string::size_type slash;
2734 string::size_type dash;
2736 if ((slash = path.find_last_of ('/')) == string::npos) {
2740 dir = path.substr (0, slash+1);
2742 /* '-' is not a legal character for the NAME part of the path */
2744 if ((dash = path.find_last_of ('-')) == string::npos) {
2748 prefix = path.substr (slash+1, dash-(slash+1));
2753 path += new_legalized;
2754 path += ".wav"; /* XXX gag me with a spoon */
2758 /* non-destructive file sources have a name of the form:
2760 /path/to/NAME-nnnnn(%[LR])?.wav
2762 the task here is to replace NAME with the new name.
2767 string::size_type slash;
2768 string::size_type dash;
2769 string::size_type postfix;
2771 /* find last slash */
2773 if ((slash = path.find_last_of ('/')) == string::npos) {
2777 dir = path.substr (0, slash+1);
2779 /* '-' is not a legal character for the NAME part of the path */
2781 if ((dash = path.find_last_of ('-')) == string::npos) {
2785 suffix = path.substr (dash+1);
2787 // Suffix is now everything after the dash. Now we need to eliminate
2788 // the nnnnn part, which is done by either finding a '%' or a '.'
2790 postfix = suffix.find_last_of ("%");
2791 if (postfix == string::npos) {
2792 postfix = suffix.find_last_of ('.');
2795 if (postfix != string::npos) {
2796 suffix = suffix.substr (postfix);
2798 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2802 const uint32_t limit = 10000;
2803 char buf[PATH_MAX+1];
2805 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2807 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2809 if (access (buf, F_OK) != 0) {
2817 error << "FATAL ERROR! Could not find a " << endl;
2826 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2830 char buf[PATH_MAX+1];
2831 const uint32_t limit = 10000;
2835 legalized = legalize_for_path (name);
2837 /* find a "version" of the file name that doesn't exist in
2838 any of the possible directories.
2841 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2843 vector<space_and_path>::iterator i;
2844 uint32_t existing = 0;
2846 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2850 spath += sound_dir (false);
2854 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2855 } else if (nchan == 2) {
2857 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2859 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2861 } else if (nchan < 26) {
2862 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2864 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2872 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2873 } else if (nchan == 2) {
2875 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2877 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2879 } else if (nchan < 26) {
2880 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2882 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2886 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2892 if (existing == 0) {
2897 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2898 throw failed_constructor();
2902 /* we now have a unique name for the file, but figure out where to
2908 spath = discover_best_sound_dir ();
2910 string::size_type pos = foo.find_last_of ('/');
2912 if (pos == string::npos) {
2915 spath += foo.substr (pos + 1);
2921 boost::shared_ptr<AudioFileSource>
2922 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2924 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2925 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2928 /* Playlist management */
2931 Session::playlist_by_name (string name)
2933 Glib::Mutex::Lock lm (playlist_lock);
2934 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2935 if ((*i)->name() == name) {
2939 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2940 if ((*i)->name() == name) {
2948 Session::add_playlist (Playlist* playlist)
2950 if (playlist->hidden()) {
2955 Glib::Mutex::Lock lm (playlist_lock);
2956 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2957 playlists.insert (playlists.begin(), playlist);
2959 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2960 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2966 PlaylistAdded (playlist); /* EMIT SIGNAL */
2970 Session::track_playlist (Playlist* pl, bool inuse)
2972 PlaylistList::iterator x;
2975 Glib::Mutex::Lock lm (playlist_lock);
2978 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2980 unused_playlists.insert (pl);
2982 if ((x = playlists.find (pl)) != playlists.end()) {
2983 playlists.erase (x);
2988 //cerr << "shifting playlist to used: " << pl->name() << endl;
2990 playlists.insert (pl);
2992 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2993 unused_playlists.erase (x);
3000 Session::remove_playlist (Playlist* playlist)
3002 if (_state_of_the_state & Deletion) {
3007 Glib::Mutex::Lock lm (playlist_lock);
3008 // cerr << "removing playlist: " << playlist->name() << endl;
3010 PlaylistList::iterator i;
3012 i = find (playlists.begin(), playlists.end(), playlist);
3014 if (i != playlists.end()) {
3015 playlists.erase (i);
3018 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3019 if (i != unused_playlists.end()) {
3020 unused_playlists.erase (i);
3027 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3031 Session::set_audition (boost::shared_ptr<Region> r)
3033 pending_audition_region = r;
3034 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3035 schedule_butler_transport_work ();
3039 Session::audition_playlist ()
3041 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3042 ev->region.reset ();
3047 Session::non_realtime_set_audition ()
3049 if (!pending_audition_region) {
3050 auditioner->audition_current_playlist ();
3052 auditioner->audition_region (pending_audition_region);
3053 pending_audition_region.reset ();
3055 AuditionActive (true); /* EMIT SIGNAL */
3059 Session::audition_region (boost::shared_ptr<Region> r)
3061 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3067 Session::cancel_audition ()
3069 if (auditioner->active()) {
3070 auditioner->cancel_audition ();
3071 AuditionActive (false); /* EMIT SIGNAL */
3076 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3078 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3082 Session::remove_empty_sounds ()
3084 PathScanner scanner;
3086 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3088 Glib::Mutex::Lock lm (audio_source_lock);
3090 regex_t compiled_tape_track_pattern;
3093 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3097 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3099 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3103 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3105 /* never remove files that appear to be a tape track */
3107 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3112 if (AudioFileSource::is_empty (*this, *(*i))) {
3114 unlink ((*i)->c_str());
3116 string peak_path = peak_path_from_audio_path (**i);
3117 unlink (peak_path.c_str());
3123 delete possible_audiofiles;
3127 Session::is_auditioning () const
3129 /* can be called before we have an auditioner object */
3131 return auditioner->active();
3138 Session::set_all_solo (bool yn)
3140 shared_ptr<RouteList> r = routes.reader ();
3142 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3143 if (!(*i)->hidden()) {
3144 (*i)->set_solo (yn, this);
3152 Session::set_all_mute (bool yn)
3154 shared_ptr<RouteList> r = routes.reader ();
3156 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3157 if (!(*i)->hidden()) {
3158 (*i)->set_mute (yn, this);
3166 Session::n_diskstreams () const
3170 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3172 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3173 if (!(*i)->hidden()) {
3181 Session::graph_reordered ()
3183 /* don't do this stuff if we are setting up connections
3184 from a set_state() call.
3187 if (_state_of_the_state & InitialConnecting) {
3193 /* force all diskstreams to update their capture offset values to
3194 reflect any changes in latencies within the graph.
3197 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3199 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3200 (*i)->set_capture_offset ();
3205 Session::record_disenable_all ()
3207 record_enable_change_all (false);
3211 Session::record_enable_all ()
3213 record_enable_change_all (true);
3217 Session::record_enable_change_all (bool yn)
3219 shared_ptr<RouteList> r = routes.reader ();
3221 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3224 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3225 at->set_record_enable (yn, this);
3229 /* since we don't keep rec-enable state, don't mark session dirty */
3233 Session::add_redirect (Redirect* redirect)
3237 PortInsert* port_insert;
3238 PluginInsert* plugin_insert;
3240 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3241 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3242 _port_inserts.insert (_port_inserts.begin(), port_insert);
3243 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3244 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3246 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3249 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3250 _sends.insert (_sends.begin(), send);
3252 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3256 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3262 Session::remove_redirect (Redirect* redirect)
3266 PortInsert* port_insert;
3267 PluginInsert* plugin_insert;
3269 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3270 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3271 _port_inserts.remove (port_insert);
3272 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3273 _plugin_inserts.remove (plugin_insert);
3275 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3278 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3279 _sends.remove (send);
3281 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3289 Session::available_capture_duration ()
3291 const double scale = 4096.0 / sizeof (Sample);
3293 if (_total_free_4k_blocks * scale > (double) max_frames) {
3297 return (nframes_t) floor (_total_free_4k_blocks * scale);
3301 Session::add_connection (ARDOUR::Connection* connection)
3304 Glib::Mutex::Lock guard (connection_lock);
3305 _connections.push_back (connection);
3308 ConnectionAdded (connection); /* EMIT SIGNAL */
3314 Session::remove_connection (ARDOUR::Connection* connection)
3316 bool removed = false;
3319 Glib::Mutex::Lock guard (connection_lock);
3320 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3322 if (i != _connections.end()) {
3323 _connections.erase (i);
3329 ConnectionRemoved (connection); /* EMIT SIGNAL */
3335 ARDOUR::Connection *
3336 Session::connection_by_name (string name) const
3338 Glib::Mutex::Lock lm (connection_lock);
3340 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3341 if ((*i)->name() == name) {
3350 Session::tempo_map_changed (Change ignored)
3357 Session::ensure_passthru_buffers (uint32_t howmany)
3359 while (howmany > _passthru_buffers.size()) {
3361 #ifdef NO_POSIX_MEMALIGN
3362 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3364 posix_memalign((void **)&p,16,current_block_size * 4);
3366 _passthru_buffers.push_back (p);
3370 #ifdef NO_POSIX_MEMALIGN
3371 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3373 posix_memalign((void **)&p,16,current_block_size * 4);
3375 memset (p, 0, sizeof (Sample) * current_block_size);
3376 _silent_buffers.push_back (p);
3380 #ifdef NO_POSIX_MEMALIGN
3381 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3383 posix_memalign((void **)&p,16,current_block_size * 4);
3385 memset (p, 0, sizeof (Sample) * current_block_size);
3386 _send_buffers.push_back (p);
3389 allocate_pan_automation_buffers (current_block_size, howmany, false);
3393 Session::next_send_name ()
3396 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3401 Session::next_insert_name ()
3404 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3408 /* Named Selection management */
3411 Session::named_selection_by_name (string name)
3413 Glib::Mutex::Lock lm (named_selection_lock);
3414 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3415 if ((*i)->name == name) {
3423 Session::add_named_selection (NamedSelection* named_selection)
3426 Glib::Mutex::Lock lm (named_selection_lock);
3427 named_selections.insert (named_selections.begin(), named_selection);
3432 NamedSelectionAdded (); /* EMIT SIGNAL */
3436 Session::remove_named_selection (NamedSelection* named_selection)
3438 bool removed = false;
3441 Glib::Mutex::Lock lm (named_selection_lock);
3443 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3445 if (i != named_selections.end()) {
3447 named_selections.erase (i);
3454 NamedSelectionRemoved (); /* EMIT SIGNAL */
3459 Session::reset_native_file_format ()
3461 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3463 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3464 (*i)->reset_write_sources (false);
3469 Session::route_name_unique (string n) const
3471 shared_ptr<RouteList> r = routes.reader ();
3473 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3474 if ((*i)->name() == n) {
3483 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3485 return fs->move_to_trash (dead_sound_dir_name);
3489 Session::n_playlists () const
3491 Glib::Mutex::Lock lm (playlist_lock);
3492 return playlists.size();
3496 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3498 if (!force && howmany <= _npan_buffers) {
3502 if (_pan_automation_buffer) {
3504 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3505 delete [] _pan_automation_buffer[i];
3508 delete [] _pan_automation_buffer;
3511 _pan_automation_buffer = new pan_t*[howmany];
3513 for (uint32_t i = 0; i < howmany; ++i) {
3514 _pan_automation_buffer[i] = new pan_t[nframes];
3517 _npan_buffers = howmany;
3521 Session::freeze (InterThreadInfo& itt)
3523 shared_ptr<RouteList> r = routes.reader ();
3525 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3529 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3530 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3541 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3542 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3546 boost::shared_ptr<AudioFileSource> fsource;
3548 char buf[PATH_MAX+1];
3552 nframes_t this_chunk;
3554 vector<Sample*> buffers;
3556 // any bigger than this seems to cause stack overflows in called functions
3557 const nframes_t chunk_size = (128 * 1024)/4;
3559 g_atomic_int_set (&processing_prohibited, 1);
3561 /* call tree *MUST* hold route_lock */
3563 if ((playlist = track.diskstream()->playlist()) == 0) {
3567 /* external redirects will be a problem */
3569 if (track.has_external_redirects()) {
3573 nchans = track.audio_diskstream()->n_channels();
3575 dir = discover_best_sound_dir ();
3577 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3579 for (x = 0; x < 99999; ++x) {
3580 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3581 if (access (buf, F_OK) != 0) {
3587 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3592 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3595 catch (failed_constructor& err) {
3596 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3600 srcs.push_back (fsource);
3603 /* XXX need to flush all redirects */
3608 /* create a set of reasonably-sized buffers */
3610 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3612 #ifdef NO_POSIX_MEMALIGN
3613 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3615 posix_memalign((void **)&b,16,chunk_size * 4);
3617 buffers.push_back (b);
3620 while (to_do && !itt.cancel) {
3622 this_chunk = min (to_do, chunk_size);
3624 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3629 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3630 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3633 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3639 start += this_chunk;
3640 to_do -= this_chunk;
3642 itt.progress = (float) (1.0 - ((double) to_do / len));
3651 xnow = localtime (&now);
3653 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3654 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3657 afs->update_header (position, *xnow, now);
3661 /* build peakfile for new source */
3663 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3664 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3666 afs->build_peaks ();
3670 /* construct a region to represent the bounced material */
3672 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3673 region_name_from_path (srcs.front()->name()));
3680 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3681 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3684 afs->mark_for_remove ();
3687 (*src)->drop_references ();
3691 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3695 g_atomic_int_set (&processing_prohibited, 0);
3703 Session::get_silent_buffers (uint32_t howmany)
3705 for (uint32_t i = 0; i < howmany; ++i) {
3706 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3708 return _silent_buffers;
3712 Session::ntracks () const
3715 shared_ptr<RouteList> r = routes.reader ();
3717 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3718 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3727 Session::nbusses () const
3730 shared_ptr<RouteList> r = routes.reader ();
3732 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3733 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3742 Session::add_curve(Curve *curve)
3744 curves[curve->id()] = curve;
3748 Session::add_automation_list(AutomationList *al)
3750 automation_lists[al->id()] = al;