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/utils.h>
49 #include <ardour/audio_diskstream.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/midi_diskstream.h>
54 #include <ardour/midi_playlist.h>
55 #include <ardour/midi_region.h>
56 #include <ardour/smf_source.h>
57 #include <ardour/destructive_filesource.h>
58 #include <ardour/auditioner.h>
59 #include <ardour/recent_sessions.h>
60 #include <ardour/redirect.h>
61 #include <ardour/send.h>
62 #include <ardour/insert.h>
63 #include <ardour/connection.h>
64 #include <ardour/slave.h>
65 #include <ardour/tempo.h>
66 #include <ardour/audio_track.h>
67 #include <ardour/midi_track.h>
68 #include <ardour/cycle_timer.h>
69 #include <ardour/named_selection.h>
70 #include <ardour/crossfade.h>
71 #include <ardour/playlist.h>
72 #include <ardour/click.h>
73 #include <ardour/data_type.h>
74 #include <ardour/buffer_set.h>
75 #include <ardour/source_factory.h>
76 #include <ardour/region_factory.h>
79 #include <ardour/osc.h>
85 using namespace ARDOUR;
87 using boost::shared_ptr;
89 const char* Session::_template_suffix = X_(".template");
90 const char* Session::_statefile_suffix = X_(".ardour");
91 const char* Session::_pending_suffix = X_(".pending");
92 const char* Session::old_sound_dir_name = X_("sounds");
93 const char* Session::sound_dir_name = X_("audiofiles");
94 const char* Session::peak_dir_name = X_("peaks");
95 const char* Session::dead_sound_dir_name = X_("dead_sounds");
96 const char* Session::interchange_dir_name = X_("interchange");
98 Session::compute_peak_t Session::compute_peak = 0;
99 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
100 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
101 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
111 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
114 char buf[PATH_MAX+1];
118 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
119 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
125 /* check to see if it exists, and what it is */
127 if (stat (str.c_str(), &statbuf)) {
128 if (errno == ENOENT) {
131 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
139 /* it exists, so it must either be the name
140 of the directory, or the name of the statefile
144 if (S_ISDIR (statbuf.st_mode)) {
146 string::size_type slash = str.find_last_of ('/');
148 if (slash == string::npos) {
150 /* a subdirectory of cwd, so statefile should be ... */
156 tmp += _statefile_suffix;
160 if (stat (tmp.c_str(), &statbuf)) {
161 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
171 /* some directory someplace in the filesystem.
172 the snapshot name is the directory name
177 snapshot = str.substr (slash+1);
181 } else if (S_ISREG (statbuf.st_mode)) {
183 string::size_type slash = str.find_last_of ('/');
184 string::size_type suffix;
186 /* remove the suffix */
188 if (slash != string::npos) {
189 snapshot = str.substr (slash+1);
194 suffix = snapshot.find (_statefile_suffix);
196 if (suffix == string::npos) {
197 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
203 snapshot = snapshot.substr (0, suffix);
205 if (slash == string::npos) {
207 /* we must be in the directory where the
208 statefile lives. get it using cwd().
211 char cwd[PATH_MAX+1];
213 if (getcwd (cwd, sizeof (cwd)) == 0) {
214 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
223 /* full path to the statefile */
225 path = str.substr (0, slash);
230 /* what type of file is it? */
231 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
237 /* its the name of a new directory. get the name
241 string::size_type slash = str.find_last_of ('/');
243 if (slash == string::npos) {
245 /* no slash, just use the name, but clean it up */
247 path = legalize_for_path (str);
253 snapshot = str.substr (slash+1);
260 Session::Session (AudioEngine &eng,
262 string snapshot_name,
263 string* mix_template)
266 _scratch_buffers(new BufferSet()),
267 _silent_buffers(new BufferSet()),
268 _send_buffers(new BufferSet()),
269 _mmc_port (default_mmc_port),
270 _mtc_port (default_mtc_port),
271 _midi_port (default_midi_port),
272 pending_events (2048),
273 //midi_requests (128), // the size of this should match the midi request pool size
274 _send_smpte_update (false),
275 diskstreams (new DiskstreamList),
276 routes (new RouteList),
277 auditioner ((Auditioner*) 0),
283 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
285 n_physical_outputs = _engine.n_physical_outputs();
286 n_physical_inputs = _engine.n_physical_inputs();
288 first_stage_init (fullpath, snapshot_name);
290 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
292 if (create (new_session, mix_template, compute_initial_length())) {
293 cerr << "create failed\n";
295 throw failed_constructor ();
299 if (second_stage_init (new_session)) {
301 throw failed_constructor ();
304 store_recent_sessions(_name, _path);
306 bool was_dirty = dirty();
308 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
310 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
313 DirtyChanged (); /* EMIT SIGNAL */
317 Session::Session (AudioEngine &eng,
319 string snapshot_name,
320 AutoConnectOption input_ac,
321 AutoConnectOption output_ac,
322 uint32_t control_out_channels,
323 uint32_t master_out_channels,
324 uint32_t requested_physical_in,
325 uint32_t requested_physical_out,
326 nframes_t initial_length)
329 _scratch_buffers(new BufferSet()),
330 _silent_buffers(new BufferSet()),
331 _send_buffers(new BufferSet()),
332 _mmc_port (default_mmc_port),
333 _mtc_port (default_mtc_port),
334 _midi_port (default_midi_port),
335 pending_events (2048),
336 //midi_requests (16),
337 _send_smpte_update (false),
338 diskstreams (new DiskstreamList),
339 routes (new RouteList),
345 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
347 n_physical_outputs = _engine.n_physical_outputs();
348 n_physical_inputs = _engine.n_physical_inputs();
350 if (n_physical_inputs) {
351 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
354 if (n_physical_outputs) {
355 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
358 first_stage_init (fullpath, snapshot_name);
360 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
363 if (create (new_session, 0, initial_length)) {
365 throw failed_constructor ();
370 /* set up Master Out and Control Out if necessary */
375 if (control_out_channels) {
376 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
377 r->set_remote_control_id (control_id++);
382 if (master_out_channels) {
383 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
384 r->set_remote_control_id (control_id);
388 /* prohibit auto-connect to master, because there isn't one */
389 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
398 Config->set_input_auto_connect (input_ac);
399 Config->set_output_auto_connect (output_ac);
401 if (second_stage_init (new_session)) {
403 throw failed_constructor ();
406 store_recent_sessions(_name, _path);
408 bool was_dirty = dirty ();
410 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
412 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
415 DirtyChanged (); /* EMIT SIGNAL */
427 /* if we got to here, leaving pending capture state around
431 remove_pending_capture_state ();
433 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
434 _engine.remove_session ();
436 GoingAway (); /* EMIT SIGNAL */
442 /* clear history so that no references to objects are held any more */
446 /* clear state tree so that no references to objects are held any more */
452 terminate_butler_thread ();
453 //terminate_midi_thread ();
455 if (click_data && click_data != default_click) {
456 delete [] click_data;
459 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
460 delete [] click_emphasis_data;
465 delete _scratch_buffers;
466 delete _silent_buffers;
467 delete _send_buffers;
469 AudioDiskstream::free_working_buffers();
471 #undef TRACK_DESTRUCTION
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete named selections\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
476 NamedSelectionList::iterator tmp;
485 #ifdef TRACK_DESTRUCTION
486 cerr << "delete playlists\n";
487 #endif /* TRACK_DESTRUCTION */
488 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
489 PlaylistList::iterator tmp;
494 (*i)->drop_references ();
499 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
500 PlaylistList::iterator tmp;
505 (*i)->drop_references ();
511 unused_playlists.clear ();
513 #ifdef TRACK_DESTRUCTION
514 cerr << "delete regions\n";
515 #endif /* TRACK_DESTRUCTION */
517 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
518 RegionList::iterator tmp;
523 cerr << "dropping refs on a region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl;
524 i->second->drop_references ();
525 cerr << "AFTER: UC = " << i->second.use_count() << endl;
532 #ifdef TRACK_DESTRUCTION
533 cerr << "delete routes\n";
534 #endif /* TRACK_DESTRUCTION */
536 RCUWriter<RouteList> writer (routes);
537 boost::shared_ptr<RouteList> r = writer.get_copy ();
538 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
539 (*i)->drop_references ();
542 /* writer goes out of scope and updates master */
547 #ifdef TRACK_DESTRUCTION
548 cerr << "delete diskstreams\n";
549 #endif /* TRACK_DESTRUCTION */
551 RCUWriter<DiskstreamList> dwriter (diskstreams);
552 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
553 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
554 (*i)->drop_references ();
558 diskstreams.flush ();
560 #ifdef TRACK_DESTRUCTION
561 cerr << "delete audio sources\n";
562 #endif /* TRACK_DESTRUCTION */
563 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
564 SourceMap::iterator tmp;
569 i->second->drop_references ();
576 #ifdef TRACK_DESTRUCTION
577 cerr << "delete mix groups\n";
578 #endif /* TRACK_DESTRUCTION */
579 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
580 list<RouteGroup*>::iterator tmp;
590 #ifdef TRACK_DESTRUCTION
591 cerr << "delete edit groups\n";
592 #endif /* TRACK_DESTRUCTION */
593 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
594 list<RouteGroup*>::iterator tmp;
604 #ifdef TRACK_DESTRUCTION
605 cerr << "delete connections\n";
606 #endif /* TRACK_DESTRUCTION */
607 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
608 ConnectionList::iterator tmp;
618 if (butler_mixdown_buffer) {
619 delete [] butler_mixdown_buffer;
622 if (butler_gain_buffer) {
623 delete [] butler_gain_buffer;
626 Crossfade::set_buffer_size (0);
634 Session::set_worst_io_latencies ()
636 _worst_output_latency = 0;
637 _worst_input_latency = 0;
639 if (!_engine.connected()) {
643 boost::shared_ptr<RouteList> r = routes.reader ();
645 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
646 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
647 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
652 Session::when_engine_running ()
654 string first_physical_output;
656 /* we don't want to run execute this again */
658 set_block_size (_engine.frames_per_cycle());
659 set_frame_rate (_engine.frame_rate());
661 Config->map_parameters (mem_fun (*this, &Session::config_changed));
663 /* every time we reconnect, recompute worst case output latencies */
665 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
667 if (synced_to_jack()) {
668 _engine.transport_stop ();
671 if (Config->get_jack_time_master()) {
672 _engine.transport_locate (_transport_frame);
680 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
682 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
684 /* existing state for Click */
686 if (_click_io->set_state (*child->children().front()) == 0) {
688 _clicking = Config->get_clicking ();
692 error << _("could not setup Click I/O") << endmsg;
698 /* default state for Click */
700 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
702 if (first_physical_output.length()) {
703 if (_click_io->add_output_port (first_physical_output, this)) {
704 // relax, even though its an error
706 _clicking = Config->get_clicking ();
712 catch (failed_constructor& err) {
713 error << _("cannot setup Click I/O") << endmsg;
716 set_worst_io_latencies ();
719 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
722 /* Create a set of Connection objects that map
723 to the physical outputs currently available
728 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
730 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
732 Connection* c = new OutputConnection (buf, true);
735 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
740 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
742 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
744 Connection* c = new InputConnection (buf, true);
747 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
754 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
756 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
758 Connection* c = new OutputConnection (buf, true);
762 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
763 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
768 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
770 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
772 Connection* c = new InputConnection (buf, true);
776 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
777 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
786 /* create master/control ports */
791 /* force the master to ignore any later call to this */
793 if (_master_out->pending_state_node) {
794 _master_out->ports_became_legal();
797 /* no panner resets till we are through */
799 _master_out->defer_pan_reset ();
801 while (_master_out->n_inputs().get(DataType::AUDIO)
802 < _master_out->input_maximum().get(DataType::AUDIO)) {
803 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
804 error << _("cannot setup master inputs")
810 while (_master_out->n_outputs().get(DataType::AUDIO)
811 < _master_out->output_maximum().get(DataType::AUDIO)) {
812 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
813 error << _("cannot setup master outputs")
820 _master_out->allow_pan_reset ();
824 Connection* c = new OutputConnection (_("Master Out"), true);
826 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
828 c->add_connection ((int) n, _master_out->input(n)->name());
835 /* catch up on send+insert cnts */
839 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
842 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
843 if (id > insert_cnt) {
851 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
854 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
862 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
864 /* hook us up to the engine */
866 _engine.set_session (this);
871 osc->set_session (*this);
874 _state_of_the_state = Clean;
876 DirtyChanged (); /* EMIT SIGNAL */
880 Session::hookup_io ()
882 /* stop graph reordering notifications from
883 causing resorts, etc.
886 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
888 if (auditioner == 0) {
890 /* we delay creating the auditioner till now because
891 it makes its own connections to ports.
892 the engine has to be running for this to work.
896 auditioner.reset (new Auditioner (*this));
899 catch (failed_constructor& err) {
900 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
904 /* Tell all IO objects to create their ports */
911 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
912 if (_control_out->add_input_port ("", this)) {
913 error << _("cannot setup control inputs")
919 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
920 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
921 error << _("cannot set up master outputs")
929 /* Tell all IO objects to connect themselves together */
931 IO::enable_connecting ();
933 /* Now reset all panners */
935 IO::reset_panners ();
937 /* Anyone who cares about input state, wake up and do something */
939 IOConnectionsComplete (); /* EMIT SIGNAL */
941 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
943 /* now handle the whole enchilada as if it was one
949 /* update mixer solo state */
955 Session::playlist_length_changed ()
957 /* we can't just increase end_location->end() if pl->get_maximum_extent()
958 if larger. if the playlist used to be the longest playlist,
959 and its now shorter, we have to decrease end_location->end(). hence,
960 we have to iterate over all diskstreams and check the
961 playlists currently in use.
967 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
969 boost::shared_ptr<Playlist> playlist;
971 if ((playlist = dstream->playlist()) != 0) {
972 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
975 /* see comment in playlist_length_changed () */
980 Session::record_enabling_legal () const
982 /* this used to be in here, but survey says.... we don't need to restrict it */
983 // if (record_status() == Recording) {
987 if (Config->get_all_safe()) {
994 Session::reset_input_monitor_state ()
996 if (transport_rolling()) {
998 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1000 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1001 if ((*i)->record_enabled ()) {
1002 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1003 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1007 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1009 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1010 if ((*i)->record_enabled ()) {
1011 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1012 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1019 Session::auto_punch_start_changed (Location* location)
1021 replace_event (Event::PunchIn, location->start());
1023 if (get_record_enabled() && Config->get_punch_in()) {
1024 /* capture start has been changed, so save new pending state */
1025 save_state ("", true);
1030 Session::auto_punch_end_changed (Location* location)
1032 nframes_t when_to_stop = location->end();
1033 // when_to_stop += _worst_output_latency + _worst_input_latency;
1034 replace_event (Event::PunchOut, when_to_stop);
1038 Session::auto_punch_changed (Location* location)
1040 nframes_t when_to_stop = location->end();
1042 replace_event (Event::PunchIn, location->start());
1043 //when_to_stop += _worst_output_latency + _worst_input_latency;
1044 replace_event (Event::PunchOut, when_to_stop);
1048 Session::auto_loop_changed (Location* location)
1050 replace_event (Event::AutoLoop, location->end(), location->start());
1052 if (transport_rolling() && play_loop) {
1054 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1056 if (_transport_frame > location->end()) {
1057 // relocate to beginning of loop
1058 clear_events (Event::LocateRoll);
1060 request_locate (location->start(), true);
1063 else if (Config->get_seamless_loop() && !loop_changing) {
1065 // schedule a locate-roll to refill the diskstreams at the
1066 // previous loop end
1067 loop_changing = true;
1069 if (location->end() > last_loopend) {
1070 clear_events (Event::LocateRoll);
1071 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1078 last_loopend = location->end();
1083 Session::set_auto_punch_location (Location* location)
1087 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1088 auto_punch_start_changed_connection.disconnect();
1089 auto_punch_end_changed_connection.disconnect();
1090 auto_punch_changed_connection.disconnect();
1091 existing->set_auto_punch (false, this);
1092 remove_event (existing->start(), Event::PunchIn);
1093 clear_events (Event::PunchOut);
1094 auto_punch_location_changed (0);
1099 if (location == 0) {
1103 if (location->end() <= location->start()) {
1104 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1108 auto_punch_start_changed_connection.disconnect();
1109 auto_punch_end_changed_connection.disconnect();
1110 auto_punch_changed_connection.disconnect();
1112 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1113 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1114 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1116 location->set_auto_punch (true, this);
1117 auto_punch_location_changed (location);
1121 Session::set_auto_loop_location (Location* location)
1125 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1126 auto_loop_start_changed_connection.disconnect();
1127 auto_loop_end_changed_connection.disconnect();
1128 auto_loop_changed_connection.disconnect();
1129 existing->set_auto_loop (false, this);
1130 remove_event (existing->end(), Event::AutoLoop);
1131 auto_loop_location_changed (0);
1136 if (location == 0) {
1140 if (location->end() <= location->start()) {
1141 error << _("Session: you can't use a mark for auto loop") << endmsg;
1145 last_loopend = location->end();
1147 auto_loop_start_changed_connection.disconnect();
1148 auto_loop_end_changed_connection.disconnect();
1149 auto_loop_changed_connection.disconnect();
1151 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1152 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1153 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1155 location->set_auto_loop (true, this);
1156 auto_loop_location_changed (location);
1160 Session::locations_added (Location* ignored)
1166 Session::locations_changed ()
1168 _locations.apply (*this, &Session::handle_locations_changed);
1172 Session::handle_locations_changed (Locations::LocationList& locations)
1174 Locations::LocationList::iterator i;
1176 bool set_loop = false;
1177 bool set_punch = false;
1179 for (i = locations.begin(); i != locations.end(); ++i) {
1183 if (location->is_auto_punch()) {
1184 set_auto_punch_location (location);
1187 if (location->is_auto_loop()) {
1188 set_auto_loop_location (location);
1195 set_auto_loop_location (0);
1198 set_auto_punch_location (0);
1205 Session::enable_record ()
1207 /* XXX really atomic compare+swap here */
1208 if (g_atomic_int_get (&_record_status) != Recording) {
1209 g_atomic_int_set (&_record_status, Recording);
1210 _last_record_location = _transport_frame;
1211 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1213 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1214 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1215 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1216 if ((*i)->record_enabled ()) {
1217 (*i)->monitor_input (true);
1222 RecordStateChanged ();
1227 Session::disable_record (bool rt_context, bool force)
1231 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1233 if (!Config->get_latched_record_enable () || force) {
1234 g_atomic_int_set (&_record_status, Disabled);
1236 if (rs == Recording) {
1237 g_atomic_int_set (&_record_status, Enabled);
1241 // FIXME: timestamp correct? [DR]
1242 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1243 // does this /need/ to be sent in all cases?
1245 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1247 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1248 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1250 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1251 if ((*i)->record_enabled ()) {
1252 (*i)->monitor_input (false);
1257 RecordStateChanged (); /* emit signal */
1260 remove_pending_capture_state ();
1266 Session::step_back_from_record ()
1268 g_atomic_int_set (&_record_status, Enabled);
1270 if (Config->get_monitoring_model() == HardwareMonitoring) {
1271 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1273 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1274 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1275 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1276 (*i)->monitor_input (false);
1283 Session::maybe_enable_record ()
1285 g_atomic_int_set (&_record_status, Enabled);
1287 /* this function is currently called from somewhere other than an RT thread.
1288 this save_state() call therefore doesn't impact anything.
1291 save_state ("", true);
1293 if (_transport_speed) {
1294 if (!Config->get_punch_in()) {
1298 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1299 RecordStateChanged (); /* EMIT SIGNAL */
1306 Session::audible_frame () const
1312 /* the first of these two possible settings for "offset"
1313 mean that the audible frame is stationary until
1314 audio emerges from the latency compensation
1317 the second means that the audible frame is stationary
1318 until audio would emerge from a physical port
1319 in the absence of any plugin latency compensation
1322 offset = _worst_output_latency;
1324 if (offset > current_block_size) {
1325 offset -= current_block_size;
1327 /* XXX is this correct? if we have no external
1328 physical connections and everything is internal
1329 then surely this is zero? still, how
1330 likely is that anyway?
1332 offset = current_block_size;
1335 if (synced_to_jack()) {
1336 tf = _engine.transport_frame();
1338 tf = _transport_frame;
1341 if (_transport_speed == 0) {
1351 if (!non_realtime_work_pending()) {
1355 /* take latency into account */
1364 Session::set_frame_rate (nframes_t frames_per_second)
1366 /** \fn void Session::set_frame_size(nframes_t)
1367 the AudioEngine object that calls this guarantees
1368 that it will not be called while we are also in
1369 ::process(). Its fine to do things that block
1373 _base_frame_rate = frames_per_second;
1377 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1379 // XXX we need some equivalent to this, somehow
1380 // SndFileSource::setup_standard_crossfades (frames_per_second);
1384 /* XXX need to reset/reinstantiate all LADSPA plugins */
1388 Session::set_block_size (nframes_t nframes)
1390 /* the AudioEngine guarantees
1391 that it will not be called while we are also in
1392 ::process(). It is therefore fine to do things that block
1398 current_block_size = nframes;
1400 ensure_buffers(_scratch_buffers->available());
1402 if (_gain_automation_buffer) {
1403 delete [] _gain_automation_buffer;
1405 _gain_automation_buffer = new gain_t[nframes];
1407 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1409 boost::shared_ptr<RouteList> r = routes.reader ();
1411 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1412 (*i)->set_block_size (nframes);
1415 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1416 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1417 (*i)->set_block_size (nframes);
1420 set_worst_io_latencies ();
1425 Session::set_default_fade (float steepness, float fade_msecs)
1428 nframes_t fade_frames;
1430 /* Don't allow fade of less 1 frame */
1432 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1439 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1443 default_fade_msecs = fade_msecs;
1444 default_fade_steepness = steepness;
1447 // jlc, WTF is this!
1448 Glib::RWLock::ReaderLock lm (route_lock);
1449 AudioRegion::set_default_fade (steepness, fade_frames);
1454 /* XXX have to do this at some point */
1455 /* foreach region using default fade, reset, then
1456 refill_all_diskstream_buffers ();
1461 struct RouteSorter {
1462 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1463 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1465 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1468 if (r1->fed_by.empty()) {
1469 if (r2->fed_by.empty()) {
1470 /* no ardour-based connections inbound to either route. just use signal order */
1471 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1473 /* r2 has connections, r1 does not; run r1 early */
1477 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1484 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1486 shared_ptr<Route> r2;
1488 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1489 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1493 /* make a copy of the existing list of routes that feed r1 */
1495 set<shared_ptr<Route> > existing = r1->fed_by;
1497 /* for each route that feeds r1, recurse, marking it as feeding
1501 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1504 /* r2 is a route that feeds r1 which somehow feeds base. mark
1505 base as being fed by r2
1508 rbase->fed_by.insert (r2);
1512 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1516 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1520 /* now recurse, so that we can mark base as being fed by
1521 all routes that feed r2
1524 trace_terminal (r2, rbase);
1531 Session::resort_routes ()
1533 /* don't do anything here with signals emitted
1534 by Routes while we are being destroyed.
1537 if (_state_of_the_state & Deletion) {
1544 RCUWriter<RouteList> writer (routes);
1545 shared_ptr<RouteList> r = writer.get_copy ();
1546 resort_routes_using (r);
1547 /* writer goes out of scope and forces update */
1552 Session::resort_routes_using (shared_ptr<RouteList> r)
1554 RouteList::iterator i, j;
1556 for (i = r->begin(); i != r->end(); ++i) {
1558 (*i)->fed_by.clear ();
1560 for (j = r->begin(); j != r->end(); ++j) {
1562 /* although routes can feed themselves, it will
1563 cause an endless recursive descent if we
1564 detect it. so don't bother checking for
1572 if ((*j)->feeds (*i)) {
1573 (*i)->fed_by.insert (*j);
1578 for (i = r->begin(); i != r->end(); ++i) {
1579 trace_terminal (*i, *i);
1586 cerr << "finished route resort\n";
1588 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1589 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1596 list<boost::shared_ptr<MidiTrack> >
1597 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1599 char track_name[32];
1600 uint32_t track_id = 0;
1602 uint32_t channels_used = 0;
1604 RouteList new_routes;
1605 list<boost::shared_ptr<MidiTrack> > ret;
1607 /* count existing midi tracks */
1610 shared_ptr<RouteList> r = routes.reader ();
1612 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1613 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1614 if (!(*i)->hidden()) {
1616 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1624 /* check for duplicate route names, since we might have pre-existing
1625 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1626 save, close,restart,add new route - first named route is now
1634 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1636 if (route_by_name (track_name) == 0) {
1640 } while (track_id < (UINT_MAX-1));
1643 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1645 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1646 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1649 channels_used += track->n_inputs ().get(DataType::MIDI);
1651 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1652 track->set_remote_control_id (ntracks());
1654 new_routes.push_back (track);
1655 ret.push_back (track);
1658 catch (failed_constructor &err) {
1659 error << _("Session: could not create new midi track.") << endmsg;
1660 // XXX should we delete the tracks already created?
1668 if (!new_routes.empty()) {
1669 add_routes (new_routes, false);
1670 save_state (_current_snapshot_name);
1676 list<boost::shared_ptr<AudioTrack> >
1677 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1679 char track_name[32];
1680 uint32_t track_id = 0;
1682 uint32_t channels_used = 0;
1684 RouteList new_routes;
1685 list<boost::shared_ptr<AudioTrack> > ret;
1686 uint32_t control_id;
1688 /* count existing audio tracks */
1691 shared_ptr<RouteList> r = routes.reader ();
1693 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1694 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1695 if (!(*i)->hidden()) {
1697 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1703 vector<string> physinputs;
1704 vector<string> physoutputs;
1705 uint32_t nphysical_in;
1706 uint32_t nphysical_out;
1708 _engine.get_physical_outputs (physoutputs);
1709 _engine.get_physical_inputs (physinputs);
1710 control_id = ntracks() + nbusses() + 1;
1714 /* check for duplicate route names, since we might have pre-existing
1715 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1716 save, close,restart,add new route - first named route is now
1724 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1726 if (route_by_name (track_name) == 0) {
1730 } while (track_id < (UINT_MAX-1));
1732 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1733 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1738 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1739 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1745 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1747 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1748 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1749 input_channels, output_channels)
1754 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1758 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1759 port = physinputs[(channels_used+x)%nphysical_in];
1762 if (port.length() && track->connect_input (track->input (x), port, this)) {
1768 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1772 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1773 port = physoutputs[(channels_used+x)%nphysical_out];
1774 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1776 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1780 if (port.length() && track->connect_output (track->output (x), port, this)) {
1785 channels_used += track->n_inputs ().get(DataType::AUDIO);
1788 vector<string> cports;
1789 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1791 for (n = 0; n < ni; ++n) {
1792 cports.push_back (_control_out->input(n)->name());
1795 track->set_control_outs (cports);
1798 // assert (current_thread != RT_thread)
1800 track->audio_diskstream()->non_realtime_input_change();
1802 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1803 track->set_remote_control_id (control_id);
1806 new_routes.push_back (track);
1807 ret.push_back (track);
1810 catch (failed_constructor &err) {
1811 error << _("Session: could not create new audio track.") << endmsg;
1812 // XXX should we delete the tracks already created?
1820 if (!new_routes.empty()) {
1821 add_routes (new_routes, false);
1822 save_state (_current_snapshot_name);
1829 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1832 uint32_t bus_id = 1;
1836 uint32_t control_id;
1838 /* count existing audio busses */
1841 shared_ptr<RouteList> r = routes.reader ();
1843 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1844 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1845 if (!(*i)->hidden()) {
1852 vector<string> physinputs;
1853 vector<string> physoutputs;
1855 _engine.get_physical_outputs (physoutputs);
1856 _engine.get_physical_inputs (physinputs);
1857 control_id = ntracks() + nbusses() + 1;
1864 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1866 if (route_by_name (bus_name) == 0) {
1870 } while (bus_id < (UINT_MAX-1));
1873 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1875 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1876 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1877 input_channels, output_channels)
1881 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1885 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1886 port = physinputs[((n+x)%n_physical_inputs)];
1889 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1894 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1898 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1899 port = physoutputs[((n+x)%n_physical_outputs)];
1900 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1902 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1906 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1912 vector<string> cports;
1913 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1915 for (uint32_t n = 0; n < ni; ++n) {
1916 cports.push_back (_control_out->input(n)->name());
1918 bus->set_control_outs (cports);
1921 bus->set_remote_control_id (control_id);
1924 ret.push_back (bus);
1928 catch (failed_constructor &err) {
1929 error << _("Session: could not create new audio route.") << endmsg;
1938 add_routes (ret, false);
1939 save_state (_current_snapshot_name);
1947 Session::add_routes (RouteList& new_routes, bool save)
1950 RCUWriter<RouteList> writer (routes);
1951 shared_ptr<RouteList> r = writer.get_copy ();
1952 r->insert (r->end(), new_routes.begin(), new_routes.end());
1953 resort_routes_using (r);
1956 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1958 boost::weak_ptr<Route> wpr (*x);
1960 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1961 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1962 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1963 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1965 if ((*x)->master()) {
1969 if ((*x)->control()) {
1970 _control_out = (*x);
1977 save_state (_current_snapshot_name);
1980 RouteAdded (new_routes); /* EMIT SIGNAL */
1984 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1986 /* need to do this in case we're rolling at the time, to prevent false underruns */
1987 dstream->do_refill_with_alloc();
1990 RCUWriter<DiskstreamList> writer (diskstreams);
1991 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1992 ds->push_back (dstream);
1995 dstream->set_block_size (current_block_size);
1997 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1998 /* this will connect to future changes, and check the current length */
1999 diskstream_playlist_changed (dstream);
2001 dstream->prepare ();
2005 Session::remove_route (shared_ptr<Route> route)
2008 RCUWriter<RouteList> writer (routes);
2009 shared_ptr<RouteList> rs = writer.get_copy ();
2013 /* deleting the master out seems like a dumb
2014 idea, but its more of a UI policy issue
2018 if (route == _master_out) {
2019 _master_out = shared_ptr<Route> ();
2022 if (route == _control_out) {
2023 _control_out = shared_ptr<Route> ();
2025 /* cancel control outs for all routes */
2027 vector<string> empty;
2029 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2030 (*r)->set_control_outs (empty);
2034 update_route_solo_state ();
2036 /* writer goes out of scope, forces route list update */
2040 boost::shared_ptr<Diskstream> ds;
2042 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2043 ds = t->diskstream();
2049 RCUWriter<DiskstreamList> dsl (diskstreams);
2050 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2055 find_current_end ();
2057 update_latency_compensation (false, false);
2060 // We need to disconnect the routes inputs and outputs
2061 route->disconnect_inputs(NULL);
2062 route->disconnect_outputs(NULL);
2064 /* get rid of it from the dead wood collection in the route list manager */
2066 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2070 /* try to cause everyone to drop their references */
2072 route->drop_references ();
2074 /* save the new state of the world */
2076 if (save_state (_current_snapshot_name)) {
2077 save_history (_current_snapshot_name);
2082 Session::route_mute_changed (void* src)
2088 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2090 if (solo_update_disabled) {
2096 boost::shared_ptr<Route> route = wpr.lock ();
2099 /* should not happen */
2100 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2104 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2106 shared_ptr<RouteList> r = routes.reader ();
2108 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2110 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2114 /* don't mess with busses */
2116 if (dynamic_cast<Track*>((*i).get()) == 0) {
2122 /* don't mess with tracks */
2124 if (dynamic_cast<Track*>((*i).get()) != 0) {
2129 if ((*i) != route &&
2130 ((*i)->mix_group () == 0 ||
2131 (*i)->mix_group () != route->mix_group () ||
2132 !route->mix_group ()->is_active())) {
2134 if ((*i)->soloed()) {
2136 /* if its already soloed, and solo latching is enabled,
2137 then leave it as it is.
2140 if (Config->get_solo_latched()) {
2147 solo_update_disabled = true;
2148 (*i)->set_solo (false, src);
2149 solo_update_disabled = false;
2153 bool something_soloed = false;
2154 bool same_thing_soloed = false;
2155 bool signal = false;
2157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2158 if ((*i)->soloed()) {
2159 something_soloed = true;
2160 if (dynamic_cast<Track*>((*i).get())) {
2162 same_thing_soloed = true;
2167 same_thing_soloed = true;
2175 if (something_soloed != currently_soloing) {
2177 currently_soloing = something_soloed;
2180 modify_solo_mute (is_track, same_thing_soloed);
2183 SoloActive (currently_soloing);
2190 Session::update_route_solo_state ()
2193 bool is_track = false;
2194 bool signal = false;
2196 /* caller must hold RouteLock */
2198 /* this is where we actually implement solo by changing
2199 the solo mute setting of each track.
2202 shared_ptr<RouteList> r = routes.reader ();
2204 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2205 if ((*i)->soloed()) {
2207 if (dynamic_cast<Track*>((*i).get())) {
2214 if (mute != currently_soloing) {
2216 currently_soloing = mute;
2219 if (!is_track && !mute) {
2221 /* nothing is soloed */
2223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2224 (*i)->set_solo_mute (false);
2234 modify_solo_mute (is_track, mute);
2237 SoloActive (currently_soloing);
2242 Session::modify_solo_mute (bool is_track, bool mute)
2244 shared_ptr<RouteList> r = routes.reader ();
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2250 /* only alter track solo mute */
2252 if (dynamic_cast<Track*>((*i).get())) {
2253 if ((*i)->soloed()) {
2254 (*i)->set_solo_mute (!mute);
2256 (*i)->set_solo_mute (mute);
2262 /* only alter bus solo mute */
2264 if (!dynamic_cast<Track*>((*i).get())) {
2266 if ((*i)->soloed()) {
2268 (*i)->set_solo_mute (false);
2272 /* don't mute master or control outs
2273 in response to another bus solo
2276 if ((*i) != _master_out &&
2277 (*i) != _control_out) {
2278 (*i)->set_solo_mute (mute);
2289 Session::catch_up_on_solo ()
2291 /* this is called after set_state() to catch the full solo
2292 state, which can't be correctly determined on a per-route
2293 basis, but needs the global overview that only the session
2296 update_route_solo_state();
2300 Session::route_by_name (string name)
2302 shared_ptr<RouteList> r = routes.reader ();
2304 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2305 if ((*i)->name() == name) {
2310 return shared_ptr<Route> ((Route*) 0);
2314 Session::route_by_id (PBD::ID id)
2316 shared_ptr<RouteList> r = routes.reader ();
2318 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2319 if ((*i)->id() == id) {
2324 return shared_ptr<Route> ((Route*) 0);
2328 Session::route_by_remote_id (uint32_t id)
2330 shared_ptr<RouteList> r = routes.reader ();
2332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2333 if ((*i)->remote_control_id() == id) {
2338 return shared_ptr<Route> ((Route*) 0);
2342 Session::find_current_end ()
2344 if (_state_of_the_state & Loading) {
2348 nframes_t max = get_maximum_extent ();
2350 if (max > end_location->end()) {
2351 end_location->set_end (max);
2353 DurationChanged(); /* EMIT SIGNAL */
2358 Session::get_maximum_extent () const
2363 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2365 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2366 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2367 if ((me = pl->get_maximum_extent()) > max) {
2375 boost::shared_ptr<Diskstream>
2376 Session::diskstream_by_name (string name)
2378 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2380 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2381 if ((*i)->name() == name) {
2386 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2389 boost::shared_ptr<Diskstream>
2390 Session::diskstream_by_id (const PBD::ID& id)
2392 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2394 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2395 if ((*i)->id() == id) {
2400 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2403 /* Region management */
2406 Session::new_region_name (string old)
2408 string::size_type last_period;
2410 string::size_type len = old.length() + 64;
2413 if ((last_period = old.find_last_of ('.')) == string::npos) {
2415 /* no period present - add one explicitly */
2418 last_period = old.length() - 1;
2423 number = atoi (old.substr (last_period+1).c_str());
2427 while (number < (UINT_MAX-1)) {
2429 RegionList::const_iterator i;
2434 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2437 for (i = regions.begin(); i != regions.end(); ++i) {
2438 if (i->second->name() == sbuf) {
2443 if (i == regions.end()) {
2448 if (number != (UINT_MAX-1)) {
2452 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2457 Session::region_name (string& result, string base, bool newlevel) const
2462 assert(base.find("/") == string::npos);
2466 Glib::Mutex::Lock lm (region_lock);
2468 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2476 /* XXX this is going to be slow. optimize me later */
2481 string::size_type pos;
2483 pos = base.find_last_of ('.');
2485 /* pos may be npos, but then we just use entire base */
2487 subbase = base.substr (0, pos);
2491 bool name_taken = true;
2494 Glib::Mutex::Lock lm (region_lock);
2496 for (int n = 1; n < 5000; ++n) {
2499 snprintf (buf, sizeof (buf), ".%d", n);
2504 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2505 if (i->second->name() == result) {
2518 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2526 Session::add_region (boost::shared_ptr<Region> region)
2528 boost::shared_ptr<Region> other;
2532 Glib::Mutex::Lock lm (region_lock);
2534 RegionList::iterator x;
2536 for (x = regions.begin(); x != regions.end(); ++x) {
2540 if (region->region_list_equivalent (other)) {
2545 if (x == regions.end()) {
2547 pair<RegionList::key_type,RegionList::mapped_type> entry;
2549 entry.first = region->id();
2550 entry.second = region;
2552 pair<RegionList::iterator,bool> x = regions.insert (entry);
2564 /* mark dirty because something has changed even if we didn't
2565 add the region to the region list.
2571 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2572 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2573 RegionAdded (region); /* EMIT SIGNAL */
2578 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2580 boost::shared_ptr<Region> region (weak_region.lock ());
2586 if (what_changed & Region::HiddenChanged) {
2587 /* relay hidden changes */
2588 RegionHiddenChange (region);
2593 Session::remove_region (boost::weak_ptr<Region> weak_region)
2595 RegionList::iterator i;
2596 boost::shared_ptr<Region> region (weak_region.lock ());
2602 bool removed = false;
2605 Glib::Mutex::Lock lm (region_lock);
2607 if ((i = regions.find (region->id())) != regions.end()) {
2613 /* mark dirty because something has changed even if we didn't
2614 remove the region from the region list.
2620 RegionRemoved(region); /* EMIT SIGNAL */
2624 boost::shared_ptr<Region>
2625 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2627 RegionList::iterator i;
2628 boost::shared_ptr<Region> region;
2630 Glib::Mutex::Lock lm (region_lock);
2632 for (i = regions.begin(); i != regions.end(); ++i) {
2636 if (region->whole_file()) {
2638 if (child->source_equivalent (region)) {
2644 return boost::shared_ptr<Region> ();
2648 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2650 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2651 (*i)->get_region_list_equivalent_regions (region, result);
2655 Session::destroy_region (boost::shared_ptr<Region> region)
2657 vector<boost::shared_ptr<Source> > srcs;
2660 boost::shared_ptr<AudioRegion> aregion;
2662 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2666 if (aregion->playlist()) {
2667 aregion->playlist()->destroy_region (region);
2670 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2671 srcs.push_back (aregion->source (n));
2675 region->drop_references ();
2677 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2679 if (!(*i)->used()) {
2680 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2683 (afs)->mark_for_remove ();
2686 (*i)->drop_references ();
2688 cerr << "source was not used by any playlist\n";
2696 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2698 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2699 destroy_region (*i);
2705 Session::remove_last_capture ()
2707 list<boost::shared_ptr<Region> > r;
2709 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2711 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2712 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2715 r.insert (r.end(), l.begin(), l.end());
2720 destroy_regions (r);
2725 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2731 /* Source Management */
2733 Session::add_source (boost::shared_ptr<Source> source)
2735 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2736 pair<SourceMap::iterator,bool> result;
2738 entry.first = source->id();
2739 entry.second = source;
2742 Glib::Mutex::Lock lm (source_lock);
2743 result = sources.insert (entry);
2746 if (result.second) {
2747 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2753 Session::remove_source (boost::weak_ptr<Source> src)
2755 SourceMap::iterator i;
2756 boost::shared_ptr<Source> source = src.lock();
2763 Glib::Mutex::Lock lm (source_lock);
2766 Glib::Mutex::Lock lm (source_lock);
2768 if ((i = sources.find (source->id())) != sources.end()) {
2774 if (!_state_of_the_state & InCleanup) {
2776 /* save state so we don't end up with a session file
2777 referring to non-existent sources.
2780 save_state (_current_snapshot_name);
2784 boost::shared_ptr<Source>
2785 Session::source_by_id (const PBD::ID& id)
2787 Glib::Mutex::Lock lm (source_lock);
2788 SourceMap::iterator i;
2789 boost::shared_ptr<Source> source;
2791 if ((i = sources.find (id)) != sources.end()) {
2795 /* XXX search MIDI or other searches here */
2801 Session::peak_path_from_audio_path (string audio_path) const
2806 res += PBD::basename_nosuffix (audio_path);
2813 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2816 string old_basename = PBD::basename_nosuffix (oldname);
2817 string new_legalized = legalize_for_path (newname);
2819 /* note: we know (or assume) the old path is already valid */
2823 /* destructive file sources have a name of the form:
2825 /path/to/Tnnnn-NAME(%[LR])?.wav
2827 the task here is to replace NAME with the new name.
2830 /* find last slash */
2834 string::size_type slash;
2835 string::size_type dash;
2837 if ((slash = path.find_last_of ('/')) == string::npos) {
2841 dir = path.substr (0, slash+1);
2843 /* '-' is not a legal character for the NAME part of the path */
2845 if ((dash = path.find_last_of ('-')) == string::npos) {
2849 prefix = path.substr (slash+1, dash-(slash+1));
2854 path += new_legalized;
2855 path += ".wav"; /* XXX gag me with a spoon */
2859 /* non-destructive file sources have a name of the form:
2861 /path/to/NAME-nnnnn(%[LR])?.wav
2863 the task here is to replace NAME with the new name.
2868 string::size_type slash;
2869 string::size_type dash;
2870 string::size_type postfix;
2872 /* find last slash */
2874 if ((slash = path.find_last_of ('/')) == string::npos) {
2878 dir = path.substr (0, slash+1);
2880 /* '-' is not a legal character for the NAME part of the path */
2882 if ((dash = path.find_last_of ('-')) == string::npos) {
2886 suffix = path.substr (dash+1);
2888 // Suffix is now everything after the dash. Now we need to eliminate
2889 // the nnnnn part, which is done by either finding a '%' or a '.'
2891 postfix = suffix.find_last_of ("%");
2892 if (postfix == string::npos) {
2893 postfix = suffix.find_last_of ('.');
2896 if (postfix != string::npos) {
2897 suffix = suffix.substr (postfix);
2899 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2903 const uint32_t limit = 10000;
2904 char buf[PATH_MAX+1];
2906 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2908 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2910 if (access (buf, F_OK) != 0) {
2918 error << "FATAL ERROR! Could not find a " << endl;
2927 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2931 char buf[PATH_MAX+1];
2932 const uint32_t limit = 10000;
2936 legalized = legalize_for_path (name);
2938 /* find a "version" of the file name that doesn't exist in
2939 any of the possible directories.
2942 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2944 vector<space_and_path>::iterator i;
2945 uint32_t existing = 0;
2947 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2951 spath += sound_dir (false);
2955 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2956 } else if (nchan == 2) {
2958 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2960 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2962 } else if (nchan < 26) {
2963 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2965 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2974 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2975 } else if (nchan == 2) {
2977 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2979 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2981 } else if (nchan < 26) {
2982 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2984 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2988 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2994 if (existing == 0) {
2999 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3001 throw failed_constructor();
3005 /* we now have a unique name for the file, but figure out where to
3011 spath = discover_best_sound_dir ();
3014 string::size_type pos = foo.find_last_of ('/');
3016 if (pos == string::npos) {
3019 spath += foo.substr (pos + 1);
3025 boost::shared_ptr<AudioFileSource>
3026 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3028 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3029 return boost::dynamic_pointer_cast<AudioFileSource> (
3030 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3033 // FIXME: _terrible_ code duplication
3035 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3038 string old_basename = PBD::basename_nosuffix (oldname);
3039 string new_legalized = legalize_for_path (newname);
3041 /* note: we know (or assume) the old path is already valid */
3045 /* destructive file sources have a name of the form:
3047 /path/to/Tnnnn-NAME(%[LR])?.wav
3049 the task here is to replace NAME with the new name.
3052 /* find last slash */
3056 string::size_type slash;
3057 string::size_type dash;
3059 if ((slash = path.find_last_of ('/')) == string::npos) {
3063 dir = path.substr (0, slash+1);
3065 /* '-' is not a legal character for the NAME part of the path */
3067 if ((dash = path.find_last_of ('-')) == string::npos) {
3071 prefix = path.substr (slash+1, dash-(slash+1));
3076 path += new_legalized;
3077 path += ".mid"; /* XXX gag me with a spoon */
3081 /* non-destructive file sources have a name of the form:
3083 /path/to/NAME-nnnnn(%[LR])?.wav
3085 the task here is to replace NAME with the new name.
3090 string::size_type slash;
3091 string::size_type dash;
3092 string::size_type postfix;
3094 /* find last slash */
3096 if ((slash = path.find_last_of ('/')) == string::npos) {
3100 dir = path.substr (0, slash+1);
3102 /* '-' is not a legal character for the NAME part of the path */
3104 if ((dash = path.find_last_of ('-')) == string::npos) {
3108 suffix = path.substr (dash+1);
3110 // Suffix is now everything after the dash. Now we need to eliminate
3111 // the nnnnn part, which is done by either finding a '%' or a '.'
3113 postfix = suffix.find_last_of ("%");
3114 if (postfix == string::npos) {
3115 postfix = suffix.find_last_of ('.');
3118 if (postfix != string::npos) {
3119 suffix = suffix.substr (postfix);
3121 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3125 const uint32_t limit = 10000;
3126 char buf[PATH_MAX+1];
3128 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3130 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3132 if (access (buf, F_OK) != 0) {
3140 error << "FATAL ERROR! Could not find a " << endl;
3149 Session::midi_path_from_name (string name)
3153 char buf[PATH_MAX+1];
3154 const uint32_t limit = 10000;
3158 legalized = legalize_for_path (name);
3160 /* find a "version" of the file name that doesn't exist in
3161 any of the possible directories.
3164 for (cnt = 1; cnt <= limit; ++cnt) {
3166 vector<space_and_path>::iterator i;
3167 uint32_t existing = 0;
3169 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3173 // FIXME: different directory from audio?
3174 spath += sound_dir(false) + "/" + legalized;
3176 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3178 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3183 if (existing == 0) {
3188 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3189 throw failed_constructor();
3193 /* we now have a unique name for the file, but figure out where to
3199 // FIXME: different directory than audio?
3200 spath = discover_best_sound_dir ();
3203 string::size_type pos = foo.find_last_of ('/');
3205 if (pos == string::npos) {
3208 spath += foo.substr (pos + 1);
3214 boost::shared_ptr<MidiSource>
3215 Session::create_midi_source_for_session (MidiDiskstream& ds)
3217 string spath = midi_path_from_name (ds.name());
3219 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3223 /* Playlist management */
3225 boost::shared_ptr<Playlist>
3226 Session::playlist_by_name (string name)
3228 Glib::Mutex::Lock lm (playlist_lock);
3229 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3230 if ((*i)->name() == name) {
3234 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3235 if ((*i)->name() == name) {
3240 return boost::shared_ptr<Playlist>();
3244 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3246 if (playlist->hidden()) {
3251 Glib::Mutex::Lock lm (playlist_lock);
3252 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3253 playlists.insert (playlists.begin(), playlist);
3254 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3255 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3261 PlaylistAdded (playlist); /* EMIT SIGNAL */
3265 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3268 Glib::Mutex::Lock lm (playlist_lock);
3269 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3272 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3279 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3281 boost::shared_ptr<Playlist> pl(wpl.lock());
3287 PlaylistList::iterator x;
3290 /* its not supposed to be visible */
3295 Glib::Mutex::Lock lm (playlist_lock);
3299 unused_playlists.insert (pl);
3301 if ((x = playlists.find (pl)) != playlists.end()) {
3302 playlists.erase (x);
3308 playlists.insert (pl);
3310 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3311 unused_playlists.erase (x);
3318 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3320 if (_state_of_the_state & Deletion) {
3324 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3331 Glib::Mutex::Lock lm (playlist_lock);
3333 PlaylistList::iterator i;
3335 i = find (playlists.begin(), playlists.end(), playlist);
3336 if (i != playlists.end()) {
3337 playlists.erase (i);
3340 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3341 if (i != unused_playlists.end()) {
3342 unused_playlists.erase (i);
3349 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3353 Session::set_audition (boost::shared_ptr<Region> r)
3355 pending_audition_region = r;
3356 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3357 schedule_butler_transport_work ();
3361 Session::audition_playlist ()
3363 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3364 ev->region.reset ();
3369 Session::non_realtime_set_audition ()
3371 if (!pending_audition_region) {
3372 auditioner->audition_current_playlist ();
3374 auditioner->audition_region (pending_audition_region);
3375 pending_audition_region.reset ();
3377 AuditionActive (true); /* EMIT SIGNAL */
3381 Session::audition_region (boost::shared_ptr<Region> r)
3383 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3389 Session::cancel_audition ()
3391 if (auditioner->active()) {
3392 auditioner->cancel_audition ();
3393 AuditionActive (false); /* EMIT SIGNAL */
3398 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3400 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3404 Session::remove_empty_sounds ()
3406 PathScanner scanner;
3408 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3410 Glib::Mutex::Lock lm (source_lock);
3412 regex_t compiled_tape_track_pattern;
3415 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3419 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3421 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3425 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3427 /* never remove files that appear to be a tape track */
3429 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3434 if (AudioFileSource::is_empty (*this, *(*i))) {
3436 unlink ((*i)->c_str());
3438 string peak_path = peak_path_from_audio_path (**i);
3439 unlink (peak_path.c_str());
3445 delete possible_audiofiles;
3449 Session::is_auditioning () const
3451 /* can be called before we have an auditioner object */
3453 return auditioner->active();
3460 Session::set_all_solo (bool yn)
3462 shared_ptr<RouteList> r = routes.reader ();
3464 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3465 if (!(*i)->hidden()) {
3466 (*i)->set_solo (yn, this);
3474 Session::set_all_mute (bool yn)
3476 shared_ptr<RouteList> r = routes.reader ();
3478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3479 if (!(*i)->hidden()) {
3480 (*i)->set_mute (yn, this);
3488 Session::n_diskstreams () const
3492 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3494 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3495 if (!(*i)->hidden()) {
3503 Session::graph_reordered ()
3505 /* don't do this stuff if we are setting up connections
3506 from a set_state() call.
3509 if (_state_of_the_state & InitialConnecting) {
3513 /* every track/bus asked for this to be handled but it was deferred because
3514 we were connecting. do it now.
3517 request_input_change_handling ();
3521 /* force all diskstreams to update their capture offset values to
3522 reflect any changes in latencies within the graph.
3525 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3527 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3528 (*i)->set_capture_offset ();
3533 Session::record_disenable_all ()
3535 record_enable_change_all (false);
3539 Session::record_enable_all ()
3541 record_enable_change_all (true);
3545 Session::record_enable_change_all (bool yn)
3547 shared_ptr<RouteList> r = routes.reader ();
3549 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3552 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3553 at->set_record_enable (yn, this);
3557 /* since we don't keep rec-enable state, don't mark session dirty */
3561 Session::add_redirect (Redirect* redirect)
3565 PortInsert* port_insert;
3566 PluginInsert* plugin_insert;
3568 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3569 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3570 _port_inserts.insert (_port_inserts.begin(), port_insert);
3571 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3572 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3574 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3577 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3578 _sends.insert (_sends.begin(), send);
3580 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3584 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3590 Session::remove_redirect (Redirect* redirect)
3594 PortInsert* port_insert;
3595 PluginInsert* plugin_insert;
3597 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3598 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3599 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3600 if (x != _port_inserts.end()) {
3601 insert_bitset[port_insert->bit_slot()] = false;
3602 _port_inserts.erase (x);
3604 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3605 _plugin_inserts.remove (plugin_insert);
3607 fatal << string_compose (_("programming error: %1"),
3608 X_("unknown type of Insert deleted!"))
3612 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3613 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3614 if (x != _sends.end()) {
3615 send_bitset[send->bit_slot()] = false;
3619 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3627 Session::available_capture_duration ()
3629 float sample_bytes_on_disk = 4.0; // keep gcc happy
3631 switch (Config->get_native_file_data_format()) {
3633 sample_bytes_on_disk = 4;
3637 sample_bytes_on_disk = 3;
3641 /* impossible, but keep some gcc versions happy */
3642 fatal << string_compose (_("programming error: %1"),
3643 X_("illegal native file data format"))
3648 double scale = 4096.0 / sample_bytes_on_disk;
3650 if (_total_free_4k_blocks * scale > (double) max_frames) {
3654 return (nframes_t) floor (_total_free_4k_blocks * scale);
3658 Session::add_connection (ARDOUR::Connection* connection)
3661 Glib::Mutex::Lock guard (connection_lock);
3662 _connections.push_back (connection);
3665 ConnectionAdded (connection); /* EMIT SIGNAL */
3671 Session::remove_connection (ARDOUR::Connection* connection)
3673 bool removed = false;
3676 Glib::Mutex::Lock guard (connection_lock);
3677 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3679 if (i != _connections.end()) {
3680 _connections.erase (i);
3686 ConnectionRemoved (connection); /* EMIT SIGNAL */
3692 ARDOUR::Connection *
3693 Session::connection_by_name (string name) const
3695 Glib::Mutex::Lock lm (connection_lock);
3697 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3698 if ((*i)->name() == name) {
3707 Session::tempo_map_changed (Change ignored)
3713 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3714 * the given count with the current block size.
3717 Session::ensure_buffers (ChanCount howmany)
3719 // FIXME: NASTY assumption (midi block size == audio block size)
3720 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3721 _send_buffers->ensure_buffers(howmany, current_block_size);
3722 _silent_buffers->ensure_buffers(howmany, current_block_size);
3724 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3728 Session::next_insert_id ()
3730 /* this doesn't really loop forever. just think about it */
3733 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3734 if (!insert_bitset[n]) {
3735 insert_bitset[n] = true;
3736 cerr << "Returning " << n << " as insert ID\n";
3742 /* none available, so resize and try again */
3744 insert_bitset.resize (insert_bitset.size() + 16, false);
3749 Session::next_send_id ()
3751 /* this doesn't really loop forever. just think about it */
3754 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3755 if (!send_bitset[n]) {
3756 send_bitset[n] = true;
3757 cerr << "Returning " << n << " as send ID\n";
3763 /* none available, so resize and try again */
3765 send_bitset.resize (send_bitset.size() + 16, false);
3770 Session::mark_send_id (uint32_t id)
3772 if (id >= send_bitset.size()) {
3773 send_bitset.resize (id+16, false);
3775 if (send_bitset[id]) {
3776 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3778 send_bitset[id] = true;
3782 Session::mark_insert_id (uint32_t id)
3784 if (id >= insert_bitset.size()) {
3785 insert_bitset.resize (id+16, false);
3787 if (insert_bitset[id]) {
3788 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3790 insert_bitset[id] = true;
3793 /* Named Selection management */
3796 Session::named_selection_by_name (string name)
3798 Glib::Mutex::Lock lm (named_selection_lock);
3799 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3800 if ((*i)->name == name) {
3808 Session::add_named_selection (NamedSelection* named_selection)
3811 Glib::Mutex::Lock lm (named_selection_lock);
3812 named_selections.insert (named_selections.begin(), named_selection);
3815 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3821 NamedSelectionAdded (); /* EMIT SIGNAL */
3825 Session::remove_named_selection (NamedSelection* named_selection)
3827 bool removed = false;
3830 Glib::Mutex::Lock lm (named_selection_lock);
3832 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3834 if (i != named_selections.end()) {
3836 named_selections.erase (i);
3843 NamedSelectionRemoved (); /* EMIT SIGNAL */
3848 Session::reset_native_file_format ()
3850 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3852 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3853 (*i)->reset_write_sources (false);
3858 Session::route_name_unique (string n) const
3860 shared_ptr<RouteList> r = routes.reader ();
3862 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3863 if ((*i)->name() == n) {
3872 Session::n_playlists () const
3874 Glib::Mutex::Lock lm (playlist_lock);
3875 return playlists.size();
3879 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3881 if (!force && howmany <= _npan_buffers) {
3885 if (_pan_automation_buffer) {
3887 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3888 delete [] _pan_automation_buffer[i];
3891 delete [] _pan_automation_buffer;
3894 _pan_automation_buffer = new pan_t*[howmany];
3896 for (uint32_t i = 0; i < howmany; ++i) {
3897 _pan_automation_buffer[i] = new pan_t[nframes];
3900 _npan_buffers = howmany;
3904 Session::freeze (InterThreadInfo& itt)
3906 shared_ptr<RouteList> r = routes.reader ();
3908 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3912 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3913 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3924 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3925 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3928 boost::shared_ptr<Playlist> playlist;
3929 boost::shared_ptr<AudioFileSource> fsource;
3931 char buf[PATH_MAX+1];
3933 ChanCount nchans(track.audio_diskstream()->n_channels());
3935 nframes_t this_chunk;
3939 // any bigger than this seems to cause stack overflows in called functions
3940 const nframes_t chunk_size = (128 * 1024)/4;
3942 g_atomic_int_set (&processing_prohibited, 1);
3944 /* call tree *MUST* hold route_lock */
3946 if ((playlist = track.diskstream()->playlist()) == 0) {
3950 /* external redirects will be a problem */
3952 if (track.has_external_redirects()) {
3956 dir = discover_best_sound_dir ();
3958 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
3960 for (x = 0; x < 99999; ++x) {
3961 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3962 if (access (buf, F_OK) != 0) {
3968 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3973 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3974 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3977 catch (failed_constructor& err) {
3978 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3982 srcs.push_back (fsource);
3985 /* XXX need to flush all redirects */
3990 /* create a set of reasonably-sized buffers */
3991 buffers.ensure_buffers(nchans, chunk_size);
3992 buffers.set_count(nchans);
3994 while (to_do && !itt.cancel) {
3996 this_chunk = min (to_do, chunk_size);
3998 if (track.export_stuff (buffers, start, this_chunk)) {
4003 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4004 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4007 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
4013 start += this_chunk;
4014 to_do -= this_chunk;
4016 itt.progress = (float) (1.0 - ((double) to_do / len));
4025 xnow = localtime (&now);
4027 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4028 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4031 afs->update_header (position, *xnow, now);
4035 /* build peakfile for new source */
4037 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4038 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4040 afs->build_peaks ();
4044 /* construct a region to represent the bounced material */
4046 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4047 region_name_from_path (srcs.front()->name(), true));
4054 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4055 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4058 afs->mark_for_remove ();
4061 (*src)->drop_references ();
4065 g_atomic_int_set (&processing_prohibited, 0);
4073 Session::get_silent_buffers (ChanCount count)
4075 assert(_silent_buffers->available() >= count);
4076 _silent_buffers->set_count(count);
4078 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4079 for (size_t i=0; i < count.get(*t); ++i) {
4080 _silent_buffers->get(*t, i).clear();
4084 return *_silent_buffers;
4088 Session::get_scratch_buffers (ChanCount count)
4090 assert(_scratch_buffers->available() >= count);
4091 _scratch_buffers->set_count(count);
4092 return *_scratch_buffers;
4096 Session::get_send_buffers (ChanCount count)
4098 assert(_send_buffers->available() >= count);
4099 _send_buffers->set_count(count);
4100 return *_send_buffers;
4104 Session::ntracks () const
4107 shared_ptr<RouteList> r = routes.reader ();
4109 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4110 if (dynamic_cast<Track*> ((*i).get())) {
4119 Session::nbusses () const
4122 shared_ptr<RouteList> r = routes.reader ();
4124 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4125 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4134 Session::add_automation_list(AutomationList *al)
4136 automation_lists[al->id()] = al;
4140 Session::compute_initial_length ()
4142 return _engine.frame_rate() * 60 * 5;