2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
43 #include <pbd/stacktrace.h>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/utils.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/destructive_filesource.h>
54 #include <ardour/auditioner.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/redirect.h>
57 #include <ardour/send.h>
58 #include <ardour/insert.h>
59 #include <ardour/connection.h>
60 #include <ardour/slave.h>
61 #include <ardour/tempo.h>
62 #include <ardour/audio_track.h>
63 #include <ardour/cycle_timer.h>
64 #include <ardour/named_selection.h>
65 #include <ardour/crossfade.h>
66 #include <ardour/playlist.h>
67 #include <ardour/click.h>
68 #include <ardour/data_type.h>
69 #include <ardour/source_factory.h>
70 #include <ardour/region_factory.h>
73 #include <ardour/osc.h>
79 using namespace ARDOUR;
81 using boost::shared_ptr;
83 const char* Session::_template_suffix = X_(".template");
84 const char* Session::_statefile_suffix = X_(".ardour");
85 const char* Session::_pending_suffix = X_(".pending");
86 const char* Session::old_sound_dir_name = X_("sounds");
87 const char* Session::sound_dir_name = X_("audiofiles");
88 const char* Session::peak_dir_name = X_("peaks");
89 const char* Session::dead_sound_dir_name = X_("dead_sounds");
90 const char* Session::interchange_dir_name = X_("interchange");
92 Session::compute_peak_t Session::compute_peak = 0;
93 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
94 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
95 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
97 sigc::signal<int> Session::AskAboutPendingState;
98 sigc::signal<void> Session::SendFeedback;
100 sigc::signal<void> Session::SMPTEOffsetChanged;
101 sigc::signal<void> Session::StartTimeChanged;
102 sigc::signal<void> Session::EndTimeChanged;
105 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
108 char buf[PATH_MAX+1];
112 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
113 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
119 /* check to see if it exists, and what it is */
121 if (stat (str.c_str(), &statbuf)) {
122 if (errno == ENOENT) {
125 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
133 /* it exists, so it must either be the name
134 of the directory, or the name of the statefile
138 if (S_ISDIR (statbuf.st_mode)) {
140 string::size_type slash = str.find_last_of ('/');
142 if (slash == string::npos) {
144 /* a subdirectory of cwd, so statefile should be ... */
150 tmp += _statefile_suffix;
154 if (stat (tmp.c_str(), &statbuf)) {
155 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
165 /* some directory someplace in the filesystem.
166 the snapshot name is the directory name
171 snapshot = str.substr (slash+1);
175 } else if (S_ISREG (statbuf.st_mode)) {
177 string::size_type slash = str.find_last_of ('/');
178 string::size_type suffix;
180 /* remove the suffix */
182 if (slash != string::npos) {
183 snapshot = str.substr (slash+1);
188 suffix = snapshot.find (_statefile_suffix);
190 if (suffix == string::npos) {
191 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
197 snapshot = snapshot.substr (0, suffix);
199 if (slash == string::npos) {
201 /* we must be in the directory where the
202 statefile lives. get it using cwd().
205 char cwd[PATH_MAX+1];
207 if (getcwd (cwd, sizeof (cwd)) == 0) {
208 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
217 /* full path to the statefile */
219 path = str.substr (0, slash);
224 /* what type of file is it? */
225 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
231 /* its the name of a new directory. get the name
235 string::size_type slash = str.find_last_of ('/');
237 if (slash == string::npos) {
239 /* no slash, just use the name, but clean it up */
241 path = legalize_for_path (str);
247 snapshot = str.substr (slash+1);
254 Session::Session (AudioEngine &eng,
256 string snapshot_name,
257 string* mix_template)
260 _mmc_port (default_mmc_port),
261 _mtc_port (default_mtc_port),
262 _midi_port (default_midi_port),
263 pending_events (2048),
264 midi_requests (128), // the size of this should match the midi request pool size
265 diskstreams (new DiskstreamList),
266 routes (new RouteList),
267 auditioner ((Auditioner*) 0),
273 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
275 n_physical_outputs = _engine.n_physical_outputs();
276 n_physical_inputs = _engine.n_physical_inputs();
278 first_stage_init (fullpath, snapshot_name);
280 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
282 if (create (new_session, mix_template, compute_initial_length())) {
283 cerr << "create failed\n";
284 throw failed_constructor ();
288 if (second_stage_init (new_session)) {
289 cerr << "2nd state failed\n";
290 throw failed_constructor ();
293 store_recent_sessions(_name, _path);
295 bool was_dirty = dirty();
297 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
299 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
302 DirtyChanged (); /* EMIT SIGNAL */
306 Session::Session (AudioEngine &eng,
308 string snapshot_name,
309 AutoConnectOption input_ac,
310 AutoConnectOption output_ac,
311 uint32_t control_out_channels,
312 uint32_t master_out_channels,
313 uint32_t requested_physical_in,
314 uint32_t requested_physical_out,
315 nframes_t initial_length)
318 _mmc_port (default_mmc_port),
319 _mtc_port (default_mtc_port),
320 _midi_port (default_midi_port),
321 pending_events (2048),
323 diskstreams (new DiskstreamList),
324 routes (new RouteList),
330 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
332 n_physical_outputs = _engine.n_physical_outputs();
333 n_physical_inputs = _engine.n_physical_inputs();
335 if (n_physical_inputs) {
336 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
339 if (n_physical_outputs) {
340 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
343 first_stage_init (fullpath, snapshot_name);
345 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
348 if (create (new_session, 0, initial_length)) {
349 throw failed_constructor ();
353 if (control_out_channels) {
354 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
361 if (master_out_channels) {
362 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
368 /* prohibit auto-connect to master, because there isn't one */
369 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
372 Config->set_input_auto_connect (input_ac);
373 Config->set_output_auto_connect (output_ac);
375 if (second_stage_init (new_session)) {
376 throw failed_constructor ();
379 store_recent_sessions(_name, _path);
381 bool was_dirty = dirty ();
383 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
386 DirtyChanged (); /* EMIT SIGNAL */
392 /* if we got to here, leaving pending capture state around
396 remove_pending_capture_state ();
398 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
399 _engine.remove_session ();
401 GoingAway (); /* EMIT SIGNAL */
407 /* clear history so that no references to objects are held any more */
411 /* clear state tree so that no references to objects are held any more */
417 terminate_butler_thread ();
418 terminate_midi_thread ();
420 if (click_data && click_data != default_click) {
421 delete [] click_data;
424 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
425 delete [] click_emphasis_data;
430 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
434 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
438 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
442 AudioDiskstream::free_working_buffers();
444 /* this should cause deletion of the auditioner */
446 // auditioner.reset ();
448 #undef TRACK_DESTRUCTION
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete named selections\n";
451 #endif /* TRACK_DESTRUCTION */
452 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
453 NamedSelectionList::iterator tmp;
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete playlists\n";
464 #endif /* TRACK_DESTRUCTION */
465 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
466 PlaylistList::iterator tmp;
471 (*i)->drop_references ();
476 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
477 PlaylistList::iterator tmp;
482 (*i)->drop_references ();
488 unused_playlists.clear ();
490 #ifdef TRACK_DESTRUCTION
491 cerr << "delete audio regions\n";
492 #endif /* TRACK_DESTRUCTION */
494 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
495 AudioRegionList::iterator tmp;
500 i->second->drop_references ();
505 audio_regions.clear ();
507 #ifdef TRACK_DESTRUCTION
508 cerr << "delete routes\n";
509 #endif /* TRACK_DESTRUCTION */
511 RCUWriter<RouteList> writer (routes);
512 boost::shared_ptr<RouteList> r = writer.get_copy ();
513 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
514 (*i)->drop_references ();
517 /* writer goes out of scope and updates master */
522 #ifdef TRACK_DESTRUCTION
523 cerr << "delete diskstreams\n";
524 #endif /* TRACK_DESTRUCTION */
526 RCUWriter<DiskstreamList> dwriter (diskstreams);
527 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
528 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
529 (*i)->drop_references ();
533 diskstreams.flush ();
535 #ifdef TRACK_DESTRUCTION
536 cerr << "delete audio sources\n";
537 #endif /* TRACK_DESTRUCTION */
538 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
539 AudioSourceList::iterator tmp;
544 i->second->drop_references ();
549 audio_sources.clear ();
551 #ifdef TRACK_DESTRUCTION
552 cerr << "delete mix groups\n";
553 #endif /* TRACK_DESTRUCTION */
554 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
555 list<RouteGroup*>::iterator tmp;
565 #ifdef TRACK_DESTRUCTION
566 cerr << "delete edit groups\n";
567 #endif /* TRACK_DESTRUCTION */
568 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
569 list<RouteGroup*>::iterator tmp;
579 #ifdef TRACK_DESTRUCTION
580 cerr << "delete connections\n";
581 #endif /* TRACK_DESTRUCTION */
582 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
583 ConnectionList::iterator tmp;
593 if (butler_mixdown_buffer) {
594 delete [] butler_mixdown_buffer;
597 if (butler_gain_buffer) {
598 delete [] butler_gain_buffer;
601 Crossfade::set_buffer_size (0);
609 Session::set_worst_io_latencies ()
611 _worst_output_latency = 0;
612 _worst_input_latency = 0;
614 if (!_engine.connected()) {
618 boost::shared_ptr<RouteList> r = routes.reader ();
620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
621 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
622 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
627 Session::when_engine_running ()
629 string first_physical_output;
631 /* we don't want to run execute this again */
633 first_time_running.disconnect ();
635 set_block_size (_engine.frames_per_cycle());
636 set_frame_rate (_engine.frame_rate());
638 Config->map_parameters (mem_fun (*this, &Session::config_changed));
640 /* every time we reconnect, recompute worst case output latencies */
642 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
644 if (synced_to_jack()) {
645 _engine.transport_stop ();
648 if (Config->get_jack_time_master()) {
649 _engine.transport_locate (_transport_frame);
657 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
659 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
661 /* existing state for Click */
663 if (_click_io->set_state (*child->children().front()) == 0) {
665 _clicking = Config->get_clicking ();
669 error << _("could not setup Click I/O") << endmsg;
675 /* default state for Click */
677 first_physical_output = _engine.get_nth_physical_output (0);
679 if (first_physical_output.length()) {
680 if (_click_io->add_output_port (first_physical_output, this)) {
681 // relax, even though its an error
683 _clicking = Config->get_clicking ();
689 catch (failed_constructor& err) {
690 error << _("cannot setup Click I/O") << endmsg;
693 set_worst_io_latencies ();
696 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
699 if (auditioner == 0) {
701 /* we delay creating the auditioner till now because
702 it makes its own connections to ports named
703 in the ARDOUR_RC config file. the engine has
704 to be running for this to work.
708 auditioner.reset (new Auditioner (*this));
711 catch (failed_constructor& err) {
712 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
716 /* Create a set of Connection objects that map
717 to the physical outputs currently available
722 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
724 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
726 Connection* c = new OutputConnection (buf, true);
729 c->add_connection (0, _engine.get_nth_physical_output (np));
734 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
736 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
738 Connection* c = new InputConnection (buf, true);
741 c->add_connection (0, _engine.get_nth_physical_input (np));
748 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
750 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
752 Connection* c = new OutputConnection (buf, true);
756 c->add_connection (0, _engine.get_nth_physical_output (np));
757 c->add_connection (1, _engine.get_nth_physical_output (np+1));
762 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
764 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
766 Connection* c = new InputConnection (buf, true);
770 c->add_connection (0, _engine.get_nth_physical_input (np));
771 c->add_connection (1, _engine.get_nth_physical_input (np+1));
780 /* create master/control ports */
785 /* force the master to ignore any later call to this */
787 if (_master_out->pending_state_node) {
788 _master_out->ports_became_legal();
791 /* no panner resets till we are through */
793 _master_out->defer_pan_reset ();
795 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
796 if (_master_out->add_input_port ("", this)) {
797 error << _("cannot setup master inputs")
803 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
804 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
805 error << _("cannot setup master outputs")
812 _master_out->allow_pan_reset ();
816 Connection* c = new OutputConnection (_("Master Out"), true);
818 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
820 c->add_connection ((int) n, _master_out->input(n)->name());
827 /* catch up on send+insert cnts */
831 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
834 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
835 if (id > insert_cnt) {
843 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
846 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
854 /* its safe to do this now */
856 restore_history (snap_name());
858 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
860 /* hook us up to the engine */
862 _engine.set_session (this);
867 osc->set_session (*this);
870 _state_of_the_state = Clean;
872 DirtyChanged (); /* EMIT SIGNAL */
876 Session::hookup_io ()
878 /* stop graph reordering notifications from
879 causing resorts, etc.
882 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
884 /* Tell all IO objects to create their ports */
891 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
892 if (_control_out->add_input_port ("", this)) {
893 error << _("cannot setup control inputs")
899 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
900 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
901 error << _("cannot set up master outputs")
909 /* Tell all IO objects to connect themselves together */
911 IO::enable_connecting ();
913 /* Now reset all panners */
915 IO::reset_panners ();
917 /* Anyone who cares about input state, wake up and do something */
919 IOConnectionsComplete (); /* EMIT SIGNAL */
921 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
923 /* now handle the whole enchilada as if it was one
929 /* update mixer solo state */
935 Session::playlist_length_changed ()
937 /* we can't just increase end_location->end() if pl->get_maximum_extent()
938 if larger. if the playlist used to be the longest playlist,
939 and its now shorter, we have to decrease end_location->end(). hence,
940 we have to iterate over all diskstreams and check the
941 playlists currently in use.
947 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
949 boost::shared_ptr<Playlist> playlist;
951 if ((playlist = dstream->playlist()) != 0) {
952 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
955 /* see comment in playlist_length_changed () */
960 Session::record_enabling_legal () const
962 /* this used to be in here, but survey says.... we don't need to restrict it */
963 // if (record_status() == Recording) {
967 if (Config->get_all_safe()) {
974 Session::reset_input_monitor_state ()
976 if (transport_rolling()) {
978 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
980 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
981 if ((*i)->record_enabled ()) {
982 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
983 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
987 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
989 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
990 if ((*i)->record_enabled ()) {
991 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
992 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
999 Session::auto_punch_start_changed (Location* location)
1001 replace_event (Event::PunchIn, location->start());
1003 if (get_record_enabled() && Config->get_punch_in()) {
1004 /* capture start has been changed, so save new pending state */
1005 save_state ("", true);
1010 Session::auto_punch_end_changed (Location* location)
1012 nframes_t when_to_stop = location->end();
1013 // when_to_stop += _worst_output_latency + _worst_input_latency;
1014 replace_event (Event::PunchOut, when_to_stop);
1018 Session::auto_punch_changed (Location* location)
1020 nframes_t when_to_stop = location->end();
1022 replace_event (Event::PunchIn, location->start());
1023 //when_to_stop += _worst_output_latency + _worst_input_latency;
1024 replace_event (Event::PunchOut, when_to_stop);
1028 Session::auto_loop_changed (Location* location)
1030 replace_event (Event::AutoLoop, location->end(), location->start());
1032 if (transport_rolling() && play_loop) {
1034 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1036 if (_transport_frame > location->end()) {
1037 // relocate to beginning of loop
1038 clear_events (Event::LocateRoll);
1040 request_locate (location->start(), true);
1043 else if (Config->get_seamless_loop() && !loop_changing) {
1045 // schedule a locate-roll to refill the diskstreams at the
1046 // previous loop end
1047 loop_changing = true;
1049 if (location->end() > last_loopend) {
1050 clear_events (Event::LocateRoll);
1051 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1058 last_loopend = location->end();
1063 Session::set_auto_punch_location (Location* location)
1067 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1068 auto_punch_start_changed_connection.disconnect();
1069 auto_punch_end_changed_connection.disconnect();
1070 auto_punch_changed_connection.disconnect();
1071 existing->set_auto_punch (false, this);
1072 remove_event (existing->start(), Event::PunchIn);
1073 clear_events (Event::PunchOut);
1074 auto_punch_location_changed (0);
1079 if (location == 0) {
1083 if (location->end() <= location->start()) {
1084 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1088 auto_punch_start_changed_connection.disconnect();
1089 auto_punch_end_changed_connection.disconnect();
1090 auto_punch_changed_connection.disconnect();
1092 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1093 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1094 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1096 location->set_auto_punch (true, this);
1097 auto_punch_location_changed (location);
1101 Session::set_auto_loop_location (Location* location)
1105 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1106 auto_loop_start_changed_connection.disconnect();
1107 auto_loop_end_changed_connection.disconnect();
1108 auto_loop_changed_connection.disconnect();
1109 existing->set_auto_loop (false, this);
1110 remove_event (existing->end(), Event::AutoLoop);
1111 auto_loop_location_changed (0);
1116 if (location == 0) {
1120 if (location->end() <= location->start()) {
1121 error << _("Session: you can't use a mark for auto loop") << endmsg;
1125 last_loopend = location->end();
1127 auto_loop_start_changed_connection.disconnect();
1128 auto_loop_end_changed_connection.disconnect();
1129 auto_loop_changed_connection.disconnect();
1131 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1132 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1133 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1135 location->set_auto_loop (true, this);
1136 auto_loop_location_changed (location);
1140 Session::locations_added (Location* ignored)
1146 Session::locations_changed ()
1148 _locations.apply (*this, &Session::handle_locations_changed);
1152 Session::handle_locations_changed (Locations::LocationList& locations)
1154 Locations::LocationList::iterator i;
1156 bool set_loop = false;
1157 bool set_punch = false;
1159 for (i = locations.begin(); i != locations.end(); ++i) {
1163 if (location->is_auto_punch()) {
1164 set_auto_punch_location (location);
1167 if (location->is_auto_loop()) {
1168 set_auto_loop_location (location);
1175 set_auto_loop_location (0);
1178 set_auto_punch_location (0);
1185 Session::enable_record ()
1187 /* XXX really atomic compare+swap here */
1188 if (g_atomic_int_get (&_record_status) != Recording) {
1189 g_atomic_int_set (&_record_status, Recording);
1190 _last_record_location = _transport_frame;
1191 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1193 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1194 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1195 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1196 if ((*i)->record_enabled ()) {
1197 (*i)->monitor_input (true);
1202 RecordStateChanged ();
1207 Session::disable_record (bool rt_context, bool force)
1211 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1213 if (!Config->get_latched_record_enable () || force) {
1214 g_atomic_int_set (&_record_status, Disabled);
1216 if (rs == Recording) {
1217 g_atomic_int_set (&_record_status, Enabled);
1221 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1223 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1224 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1226 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1227 if ((*i)->record_enabled ()) {
1228 (*i)->monitor_input (false);
1233 RecordStateChanged (); /* emit signal */
1236 remove_pending_capture_state ();
1242 Session::step_back_from_record ()
1244 g_atomic_int_set (&_record_status, Enabled);
1246 if (Config->get_monitoring_model() == HardwareMonitoring) {
1247 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1249 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1250 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1251 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1252 (*i)->monitor_input (false);
1259 Session::maybe_enable_record ()
1261 g_atomic_int_set (&_record_status, Enabled);
1263 /* this function is currently called from somewhere other than an RT thread.
1264 this save_state() call therefore doesn't impact anything.
1267 save_state ("", true);
1269 if (_transport_speed) {
1270 if (!Config->get_punch_in()) {
1274 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1275 RecordStateChanged (); /* EMIT SIGNAL */
1282 Session::audible_frame () const
1288 /* the first of these two possible settings for "offset"
1289 mean that the audible frame is stationary until
1290 audio emerges from the latency compensation
1293 the second means that the audible frame is stationary
1294 until audio would emerge from a physical port
1295 in the absence of any plugin latency compensation
1298 offset = _worst_output_latency;
1300 if (offset > current_block_size) {
1301 offset -= current_block_size;
1303 /* XXX is this correct? if we have no external
1304 physical connections and everything is internal
1305 then surely this is zero? still, how
1306 likely is that anyway?
1308 offset = current_block_size;
1311 if (synced_to_jack()) {
1312 tf = _engine.transport_frame();
1314 tf = _transport_frame;
1317 if (_transport_speed == 0) {
1327 if (!non_realtime_work_pending()) {
1331 /* take latency into account */
1340 Session::set_frame_rate (nframes_t frames_per_second)
1342 /** \fn void Session::set_frame_size(nframes_t)
1343 the AudioEngine object that calls this guarantees
1344 that it will not be called while we are also in
1345 ::process(). Its fine to do things that block
1349 _base_frame_rate = frames_per_second;
1353 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1355 // XXX we need some equivalent to this, somehow
1356 // SndFileSource::setup_standard_crossfades (frames_per_second);
1360 /* XXX need to reset/reinstantiate all LADSPA plugins */
1364 Session::set_block_size (nframes_t nframes)
1366 /* the AudioEngine guarantees
1367 that it will not be called while we are also in
1368 ::process(). It is therefore fine to do things that block
1373 vector<Sample*>::iterator i;
1376 current_block_size = nframes;
1378 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1382 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1386 _passthru_buffers.clear ();
1387 _silent_buffers.clear ();
1389 ensure_passthru_buffers (np);
1391 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1395 #ifdef NO_POSIX_MEMALIGN
1396 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1398 posix_memalign((void **)&buf,16,current_block_size * 4);
1402 memset (*i, 0, sizeof (Sample) * current_block_size);
1406 if (_gain_automation_buffer) {
1407 delete [] _gain_automation_buffer;
1409 _gain_automation_buffer = new gain_t[nframes];
1411 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1413 boost::shared_ptr<RouteList> r = routes.reader ();
1415 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1416 (*i)->set_block_size (nframes);
1419 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1420 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1421 (*i)->set_block_size (nframes);
1424 set_worst_io_latencies ();
1429 Session::set_default_fade (float steepness, float fade_msecs)
1432 nframes_t fade_frames;
1434 /* Don't allow fade of less 1 frame */
1436 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1443 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1447 default_fade_msecs = fade_msecs;
1448 default_fade_steepness = steepness;
1451 // jlc, WTF is this!
1452 Glib::RWLock::ReaderLock lm (route_lock);
1453 AudioRegion::set_default_fade (steepness, fade_frames);
1458 /* XXX have to do this at some point */
1459 /* foreach region using default fade, reset, then
1460 refill_all_diskstream_buffers ();
1465 struct RouteSorter {
1466 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1467 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1469 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1472 if (r1->fed_by.empty()) {
1473 if (r2->fed_by.empty()) {
1474 /* no ardour-based connections inbound to either route. just use signal order */
1475 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1477 /* r2 has connections, r1 does not; run r1 early */
1481 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1488 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1490 shared_ptr<Route> r2;
1492 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1493 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1497 /* make a copy of the existing list of routes that feed r1 */
1499 set<shared_ptr<Route> > existing = r1->fed_by;
1501 /* for each route that feeds r1, recurse, marking it as feeding
1505 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1508 /* r2 is a route that feeds r1 which somehow feeds base. mark
1509 base as being fed by r2
1512 rbase->fed_by.insert (r2);
1516 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1520 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1524 /* now recurse, so that we can mark base as being fed by
1525 all routes that feed r2
1528 trace_terminal (r2, rbase);
1535 Session::resort_routes ()
1537 /* don't do anything here with signals emitted
1538 by Routes while we are being destroyed.
1541 if (_state_of_the_state & Deletion) {
1548 RCUWriter<RouteList> writer (routes);
1549 shared_ptr<RouteList> r = writer.get_copy ();
1550 resort_routes_using (r);
1551 /* writer goes out of scope and forces update */
1556 Session::resort_routes_using (shared_ptr<RouteList> r)
1558 RouteList::iterator i, j;
1560 for (i = r->begin(); i != r->end(); ++i) {
1562 (*i)->fed_by.clear ();
1564 for (j = r->begin(); j != r->end(); ++j) {
1566 /* although routes can feed themselves, it will
1567 cause an endless recursive descent if we
1568 detect it. so don't bother checking for
1576 if ((*j)->feeds (*i)) {
1577 (*i)->fed_by.insert (*j);
1582 for (i = r->begin(); i != r->end(); ++i) {
1583 trace_terminal (*i, *i);
1589 /* don't leave dangling references to routes in Route::fed_by */
1591 for (i = r->begin(); i != r->end(); ++i) {
1592 (*i)->fed_by.clear ();
1596 cerr << "finished route resort\n";
1598 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1599 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1606 list<boost::shared_ptr<AudioTrack> >
1607 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1609 char track_name[32];
1610 uint32_t track_id = 0;
1612 uint32_t channels_used = 0;
1614 RouteList new_routes;
1615 list<boost::shared_ptr<AudioTrack> > ret;
1617 /* count existing audio tracks */
1620 shared_ptr<RouteList> r = routes.reader ();
1622 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1623 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1624 if (!(*i)->hidden()) {
1626 channels_used += (*i)->n_inputs();
1632 vector<string> physinputs;
1633 vector<string> physoutputs;
1634 uint32_t nphysical_in;
1635 uint32_t nphysical_out;
1637 _engine.get_physical_outputs (physoutputs);
1638 _engine.get_physical_inputs (physinputs);
1642 /* check for duplicate route names, since we might have pre-existing
1643 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1644 save, close,restart,add new route - first named route is now
1652 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1654 if (route_by_name (track_name) == 0) {
1658 } while (track_id < (UINT_MAX-1));
1660 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1661 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1666 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1667 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1673 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1675 if (track->ensure_io (input_channels, output_channels, false, this)) {
1676 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1677 input_channels, output_channels)
1682 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1686 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1687 port = physinputs[(channels_used+x)%nphysical_in];
1690 if (port.length() && track->connect_input (track->input (x), port, this)) {
1696 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1700 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1701 port = physoutputs[(channels_used+x)%nphysical_out];
1702 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1704 port = _master_out->input (x%_master_out->n_inputs())->name();
1708 if (port.length() && track->connect_output (track->output (x), port, this)) {
1713 channels_used += track->n_inputs ();
1716 vector<string> cports;
1717 uint32_t ni = _control_out->n_inputs();
1719 for (n = 0; n < ni; ++n) {
1720 cports.push_back (_control_out->input(n)->name());
1723 track->set_control_outs (cports);
1726 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1727 track->set_remote_control_id (ntracks());
1729 new_routes.push_back (track);
1730 ret.push_back (track);
1733 catch (failed_constructor &err) {
1734 error << _("Session: could not create new audio track.") << endmsg;
1735 // XXX should we delete the tracks already created?
1743 if (!new_routes.empty()) {
1744 add_routes (new_routes, false);
1745 save_state (_current_snapshot_name);
1752 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1755 uint32_t bus_id = 1;
1760 /* count existing audio busses */
1763 shared_ptr<RouteList> r = routes.reader ();
1765 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1766 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1767 if (!(*i)->hidden()) {
1774 vector<string> physinputs;
1775 vector<string> physoutputs;
1777 _engine.get_physical_outputs (physoutputs);
1778 _engine.get_physical_inputs (physinputs);
1785 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1787 if (route_by_name (bus_name) == 0) {
1791 } while (bus_id < (UINT_MAX-1));
1794 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1796 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1797 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1798 input_channels, output_channels)
1802 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1806 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1807 port = physinputs[((n+x)%n_physical_inputs)];
1810 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1815 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1819 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1820 port = physoutputs[((n+x)%n_physical_outputs)];
1821 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1823 port = _master_out->input (x%_master_out->n_inputs())->name();
1827 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1833 vector<string> cports;
1834 uint32_t ni = _control_out->n_inputs();
1836 for (uint32_t n = 0; n < ni; ++n) {
1837 cports.push_back (_control_out->input(n)->name());
1839 bus->set_control_outs (cports);
1842 ret.push_back (bus);
1846 catch (failed_constructor &err) {
1847 error << _("Session: could not create new audio route.") << endmsg;
1856 add_routes (ret, false);
1857 save_state (_current_snapshot_name);
1865 Session::add_routes (RouteList& new_routes, bool save)
1868 RCUWriter<RouteList> writer (routes);
1869 shared_ptr<RouteList> r = writer.get_copy ();
1870 r->insert (r->end(), new_routes.begin(), new_routes.end());
1871 resort_routes_using (r);
1874 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1876 boost::weak_ptr<Route> wpr (*x);
1878 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1879 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1880 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1881 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1883 if ((*x)->master()) {
1887 if ((*x)->control()) {
1888 _control_out = (*x);
1895 save_state (_current_snapshot_name);
1898 RouteAdded (new_routes); /* EMIT SIGNAL */
1902 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1904 /* need to do this in case we're rolling at the time, to prevent false underruns */
1905 dstream->do_refill_with_alloc();
1908 RCUWriter<DiskstreamList> writer (diskstreams);
1909 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1910 ds->push_back (dstream);
1913 dstream->set_block_size (current_block_size);
1915 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1916 /* this will connect to future changes, and check the current length */
1917 diskstream_playlist_changed (dstream);
1919 dstream->prepare ();
1923 Session::remove_route (shared_ptr<Route> route)
1926 RCUWriter<RouteList> writer (routes);
1927 shared_ptr<RouteList> rs = writer.get_copy ();
1931 /* deleting the master out seems like a dumb
1932 idea, but its more of a UI policy issue
1936 if (route == _master_out) {
1937 _master_out = shared_ptr<Route> ();
1940 if (route == _control_out) {
1941 _control_out = shared_ptr<Route> ();
1943 /* cancel control outs for all routes */
1945 vector<string> empty;
1947 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1948 (*r)->set_control_outs (empty);
1952 update_route_solo_state ();
1954 /* writer goes out of scope, forces route list update */
1957 // FIXME: audio specific
1959 boost::shared_ptr<AudioDiskstream> ds;
1961 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1962 ds = at->audio_diskstream();
1968 RCUWriter<DiskstreamList> dsl (diskstreams);
1969 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1974 find_current_end ();
1976 update_latency_compensation (false, false);
1979 // We need to disconnect the routes inputs and outputs
1980 route->disconnect_inputs(NULL);
1981 route->disconnect_outputs(NULL);
1983 /* get rid of it from the dead wood collection in the route list manager */
1985 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1989 /* try to cause everyone to drop their references */
1991 route->drop_references ();
1993 /* save the new state of the world */
1995 if (save_state (_current_snapshot_name)) {
1996 save_history (_current_snapshot_name);
2001 Session::route_mute_changed (void* src)
2007 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2009 if (solo_update_disabled) {
2015 boost::shared_ptr<Route> route = wpr.lock ();
2018 /* should not happen */
2019 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2023 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2025 shared_ptr<RouteList> r = routes.reader ();
2027 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2029 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2033 /* don't mess with busses */
2035 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2041 /* don't mess with tracks */
2043 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2048 if ((*i) != route &&
2049 ((*i)->mix_group () == 0 ||
2050 (*i)->mix_group () != route->mix_group () ||
2051 !route->mix_group ()->is_active())) {
2053 if ((*i)->soloed()) {
2055 /* if its already soloed, and solo latching is enabled,
2056 then leave it as it is.
2059 if (Config->get_solo_latched()) {
2066 solo_update_disabled = true;
2067 (*i)->set_solo (false, src);
2068 solo_update_disabled = false;
2072 bool something_soloed = false;
2073 bool same_thing_soloed = false;
2074 bool signal = false;
2076 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2077 if ((*i)->soloed()) {
2078 something_soloed = true;
2079 if (dynamic_cast<AudioTrack*>((*i).get())) {
2081 same_thing_soloed = true;
2086 same_thing_soloed = true;
2094 if (something_soloed != currently_soloing) {
2096 currently_soloing = something_soloed;
2099 modify_solo_mute (is_track, same_thing_soloed);
2102 SoloActive (currently_soloing);
2109 Session::update_route_solo_state ()
2112 bool is_track = false;
2113 bool signal = false;
2115 /* caller must hold RouteLock */
2117 /* this is where we actually implement solo by changing
2118 the solo mute setting of each track.
2121 shared_ptr<RouteList> r = routes.reader ();
2123 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2124 if ((*i)->soloed()) {
2126 if (dynamic_cast<AudioTrack*>((*i).get())) {
2133 if (mute != currently_soloing) {
2135 currently_soloing = mute;
2138 if (!is_track && !mute) {
2140 /* nothing is soloed */
2142 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2143 (*i)->set_solo_mute (false);
2153 modify_solo_mute (is_track, mute);
2156 SoloActive (currently_soloing);
2161 Session::modify_solo_mute (bool is_track, bool mute)
2163 shared_ptr<RouteList> r = routes.reader ();
2165 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2169 /* only alter track solo mute */
2171 if (dynamic_cast<AudioTrack*>((*i).get())) {
2172 if ((*i)->soloed()) {
2173 (*i)->set_solo_mute (!mute);
2175 (*i)->set_solo_mute (mute);
2181 /* only alter bus solo mute */
2183 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2185 if ((*i)->soloed()) {
2187 (*i)->set_solo_mute (false);
2191 /* don't mute master or control outs
2192 in response to another bus solo
2195 if ((*i) != _master_out &&
2196 (*i) != _control_out) {
2197 (*i)->set_solo_mute (mute);
2208 Session::catch_up_on_solo ()
2210 /* this is called after set_state() to catch the full solo
2211 state, which can't be correctly determined on a per-route
2212 basis, but needs the global overview that only the session
2215 update_route_solo_state();
2219 Session::route_by_name (string name)
2221 shared_ptr<RouteList> r = routes.reader ();
2223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2224 if ((*i)->name() == name) {
2229 return shared_ptr<Route> ((Route*) 0);
2233 Session::route_by_id (PBD::ID id)
2235 shared_ptr<RouteList> r = routes.reader ();
2237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238 if ((*i)->id() == id) {
2243 return shared_ptr<Route> ((Route*) 0);
2247 Session::route_by_remote_id (uint32_t id)
2249 shared_ptr<RouteList> r = routes.reader ();
2251 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2252 if ((*i)->remote_control_id() == id) {
2257 return shared_ptr<Route> ((Route*) 0);
2261 Session::find_current_end ()
2263 if (_state_of_the_state & Loading) {
2267 nframes_t max = get_maximum_extent ();
2269 if (max > end_location->end()) {
2270 end_location->set_end (max);
2272 DurationChanged(); /* EMIT SIGNAL */
2277 Session::get_maximum_extent () const
2282 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2284 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2285 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2286 if ((me = pl->get_maximum_extent()) > max) {
2294 boost::shared_ptr<Diskstream>
2295 Session::diskstream_by_name (string name)
2297 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2299 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2300 if ((*i)->name() == name) {
2305 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2308 boost::shared_ptr<Diskstream>
2309 Session::diskstream_by_id (const PBD::ID& id)
2311 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2313 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2314 if ((*i)->id() == id) {
2319 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2322 /* AudioRegion management */
2325 Session::new_region_name (string old)
2327 string::size_type last_period;
2329 string::size_type len = old.length() + 64;
2332 if ((last_period = old.find_last_of ('.')) == string::npos) {
2334 /* no period present - add one explicitly */
2337 last_period = old.length() - 1;
2342 number = atoi (old.substr (last_period+1).c_str());
2346 while (number < (UINT_MAX-1)) {
2348 AudioRegionList::const_iterator i;
2353 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2356 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2357 if (i->second->name() == sbuf) {
2362 if (i == audio_regions.end()) {
2367 if (number != (UINT_MAX-1)) {
2371 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2376 Session::region_name (string& result, string base, bool newlevel) const
2383 Glib::Mutex::Lock lm (region_lock);
2385 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2393 /* XXX this is going to be slow. optimize me later */
2398 string::size_type pos;
2400 pos = base.find_last_of ('.');
2402 /* pos may be npos, but then we just use entire base */
2404 subbase = base.substr (0, pos);
2408 bool name_taken = true;
2411 Glib::Mutex::Lock lm (region_lock);
2413 for (int n = 1; n < 5000; ++n) {
2416 snprintf (buf, sizeof (buf), ".%d", n);
2421 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2422 if (i->second->name() == result) {
2435 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2443 Session::add_region (boost::shared_ptr<Region> region)
2445 boost::shared_ptr<AudioRegion> ar;
2446 boost::shared_ptr<AudioRegion> oar;
2450 Glib::Mutex::Lock lm (region_lock);
2452 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2454 AudioRegionList::iterator x;
2456 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2458 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2460 if (ar->region_list_equivalent (oar)) {
2465 if (x == audio_regions.end()) {
2467 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2469 entry.first = region->id();
2472 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2484 fatal << _("programming error: ")
2485 << X_("unknown region type passed to Session::add_region()")
2492 /* mark dirty because something has changed even if we didn't
2493 add the region to the region list.
2499 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2500 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2501 AudioRegionAdded (ar); /* EMIT SIGNAL */
2506 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2508 boost::shared_ptr<Region> region (weak_region.lock ());
2514 if (what_changed & Region::HiddenChanged) {
2515 /* relay hidden changes */
2516 RegionHiddenChange (region);
2521 Session::remove_region (boost::weak_ptr<Region> weak_region)
2523 AudioRegionList::iterator i;
2524 boost::shared_ptr<Region> region (weak_region.lock ());
2530 boost::shared_ptr<AudioRegion> ar;
2531 bool removed = false;
2534 Glib::Mutex::Lock lm (region_lock);
2536 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2537 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2538 audio_regions.erase (i);
2544 fatal << _("programming error: ")
2545 << X_("unknown region type passed to Session::remove_region()")
2551 /* mark dirty because something has changed even if we didn't
2552 remove the region from the region list.
2558 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2562 boost::shared_ptr<AudioRegion>
2563 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2565 AudioRegionList::iterator i;
2566 boost::shared_ptr<AudioRegion> region;
2567 Glib::Mutex::Lock lm (region_lock);
2569 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2573 if (region->whole_file()) {
2575 if (child->source_equivalent (region)) {
2581 return boost::shared_ptr<AudioRegion> ();
2585 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2587 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2588 (*i)->get_region_list_equivalent_regions (region, result);
2592 Session::destroy_region (boost::shared_ptr<Region> region)
2594 vector<boost::shared_ptr<Source> > srcs;
2597 boost::shared_ptr<AudioRegion> aregion;
2599 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2603 if (aregion->playlist()) {
2604 aregion->playlist()->destroy_region (region);
2607 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2608 srcs.push_back (aregion->source (n));
2612 region->drop_references ();
2614 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2616 if (!(*i)->used()) {
2617 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2620 (afs)->mark_for_remove ();
2623 (*i)->drop_references ();
2625 cerr << "source was not used by any playlist\n";
2633 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2635 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2636 destroy_region (*i);
2642 Session::remove_last_capture ()
2644 list<boost::shared_ptr<Region> > r;
2646 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2648 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2649 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2652 r.insert (r.end(), l.begin(), l.end());
2657 destroy_regions (r);
2662 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2668 /* Source Management */
2671 Session::add_source (boost::shared_ptr<Source> source)
2673 boost::shared_ptr<AudioFileSource> afs;
2675 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2677 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2678 pair<AudioSourceList::iterator,bool> result;
2680 entry.first = source->id();
2684 Glib::Mutex::Lock lm (audio_source_lock);
2685 result = audio_sources.insert (entry);
2688 if (result.second) {
2689 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2696 Session::remove_source (boost::weak_ptr<Source> src)
2698 AudioSourceList::iterator i;
2699 boost::shared_ptr<Source> source = src.lock();
2706 Glib::Mutex::Lock lm (audio_source_lock);
2708 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2709 audio_sources.erase (i);
2713 if (!_state_of_the_state & InCleanup) {
2715 /* save state so we don't end up with a session file
2716 referring to non-existent sources.
2719 save_state (_current_snapshot_name);
2723 boost::shared_ptr<Source>
2724 Session::source_by_id (const PBD::ID& id)
2726 Glib::Mutex::Lock lm (audio_source_lock);
2727 AudioSourceList::iterator i;
2728 boost::shared_ptr<Source> source;
2730 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2734 /* XXX search MIDI or other searches here */
2740 Session::peak_path_from_audio_path (string audio_path) const
2745 res += PBD::basename_nosuffix (audio_path);
2752 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2755 string old_basename = PBD::basename_nosuffix (oldname);
2756 string new_legalized = legalize_for_path (newname);
2758 /* note: we know (or assume) the old path is already valid */
2762 /* destructive file sources have a name of the form:
2764 /path/to/Tnnnn-NAME(%[LR])?.wav
2766 the task here is to replace NAME with the new name.
2769 /* find last slash */
2773 string::size_type slash;
2774 string::size_type dash;
2776 if ((slash = path.find_last_of ('/')) == string::npos) {
2780 dir = path.substr (0, slash+1);
2782 /* '-' is not a legal character for the NAME part of the path */
2784 if ((dash = path.find_last_of ('-')) == string::npos) {
2788 prefix = path.substr (slash+1, dash-(slash+1));
2793 path += new_legalized;
2794 path += ".wav"; /* XXX gag me with a spoon */
2798 /* non-destructive file sources have a name of the form:
2800 /path/to/NAME-nnnnn(%[LR])?.wav
2802 the task here is to replace NAME with the new name.
2807 string::size_type slash;
2808 string::size_type dash;
2809 string::size_type postfix;
2811 /* find last slash */
2813 if ((slash = path.find_last_of ('/')) == string::npos) {
2817 dir = path.substr (0, slash+1);
2819 /* '-' is not a legal character for the NAME part of the path */
2821 if ((dash = path.find_last_of ('-')) == string::npos) {
2825 suffix = path.substr (dash+1);
2827 // Suffix is now everything after the dash. Now we need to eliminate
2828 // the nnnnn part, which is done by either finding a '%' or a '.'
2830 postfix = suffix.find_last_of ("%");
2831 if (postfix == string::npos) {
2832 postfix = suffix.find_last_of ('.');
2835 if (postfix != string::npos) {
2836 suffix = suffix.substr (postfix);
2838 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2842 const uint32_t limit = 10000;
2843 char buf[PATH_MAX+1];
2845 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2847 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2849 if (access (buf, F_OK) != 0) {
2857 error << "FATAL ERROR! Could not find a " << endl;
2866 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2870 char buf[PATH_MAX+1];
2871 const uint32_t limit = 10000;
2875 legalized = legalize_for_path (name);
2877 /* find a "version" of the file name that doesn't exist in
2878 any of the possible directories.
2881 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2883 vector<space_and_path>::iterator i;
2884 uint32_t existing = 0;
2886 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2890 spath += sound_dir (false);
2894 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2895 } else if (nchan == 2) {
2897 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2899 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2901 } else if (nchan < 26) {
2902 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2904 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2913 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2914 } else if (nchan == 2) {
2916 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2918 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2920 } else if (nchan < 26) {
2921 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2923 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2927 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2933 if (existing == 0) {
2938 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2939 throw failed_constructor();
2943 /* we now have a unique name for the file, but figure out where to
2949 spath = discover_best_sound_dir ();
2952 string::size_type pos = foo.find_last_of ('/');
2954 if (pos == string::npos) {
2957 spath += foo.substr (pos + 1);
2963 boost::shared_ptr<AudioFileSource>
2964 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2966 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2967 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2970 /* Playlist management */
2972 boost::shared_ptr<Playlist>
2973 Session::playlist_by_name (string name)
2975 Glib::Mutex::Lock lm (playlist_lock);
2976 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2977 if ((*i)->name() == name) {
2981 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2982 if ((*i)->name() == name) {
2987 return boost::shared_ptr<Playlist>();
2991 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
2993 if (playlist->hidden()) {
2998 Glib::Mutex::Lock lm (playlist_lock);
2999 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3000 playlists.insert (playlists.begin(), playlist);
3001 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3002 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3008 PlaylistAdded (playlist); /* EMIT SIGNAL */
3012 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3015 Glib::Mutex::Lock lm (playlist_lock);
3016 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3019 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3026 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3028 boost::shared_ptr<Playlist> pl(wpl.lock());
3034 PlaylistList::iterator x;
3037 /* its not supposed to be visible */
3042 Glib::Mutex::Lock lm (playlist_lock);
3046 unused_playlists.insert (pl);
3048 if ((x = playlists.find (pl)) != playlists.end()) {
3049 playlists.erase (x);
3055 playlists.insert (pl);
3057 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3058 unused_playlists.erase (x);
3065 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3067 if (_state_of_the_state & Deletion) {
3071 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3078 Glib::Mutex::Lock lm (playlist_lock);
3079 cerr << "removing playlist: " << playlist->name() << endl;
3081 PlaylistList::iterator i;
3083 i = find (playlists.begin(), playlists.end(), playlist);
3084 if (i != playlists.end()) {
3085 cerr << "\tfound it in used playlist\n";
3086 playlists.erase (i);
3089 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3090 if (i != unused_playlists.end()) {
3091 cerr << "\tfound it in unused playlist\n";
3092 unused_playlists.erase (i);
3099 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3103 Session::set_audition (boost::shared_ptr<Region> r)
3105 pending_audition_region = r;
3106 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3107 schedule_butler_transport_work ();
3111 Session::audition_playlist ()
3113 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3114 ev->region.reset ();
3119 Session::non_realtime_set_audition ()
3121 if (!pending_audition_region) {
3122 auditioner->audition_current_playlist ();
3124 auditioner->audition_region (pending_audition_region);
3125 pending_audition_region.reset ();
3127 AuditionActive (true); /* EMIT SIGNAL */
3131 Session::audition_region (boost::shared_ptr<Region> r)
3133 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3139 Session::cancel_audition ()
3141 if (auditioner->active()) {
3142 auditioner->cancel_audition ();
3143 AuditionActive (false); /* EMIT SIGNAL */
3148 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3150 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3154 Session::remove_empty_sounds ()
3156 PathScanner scanner;
3158 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3160 Glib::Mutex::Lock lm (audio_source_lock);
3162 regex_t compiled_tape_track_pattern;
3165 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3169 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3171 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3175 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3177 /* never remove files that appear to be a tape track */
3179 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3184 if (AudioFileSource::is_empty (*this, *(*i))) {
3186 unlink ((*i)->c_str());
3188 string peak_path = peak_path_from_audio_path (**i);
3189 unlink (peak_path.c_str());
3195 delete possible_audiofiles;
3199 Session::is_auditioning () const
3201 /* can be called before we have an auditioner object */
3203 return auditioner->active();
3210 Session::set_all_solo (bool yn)
3212 shared_ptr<RouteList> r = routes.reader ();
3214 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3215 if (!(*i)->hidden()) {
3216 (*i)->set_solo (yn, this);
3224 Session::set_all_mute (bool yn)
3226 shared_ptr<RouteList> r = routes.reader ();
3228 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3229 if (!(*i)->hidden()) {
3230 (*i)->set_mute (yn, this);
3238 Session::n_diskstreams () const
3242 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3244 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3245 if (!(*i)->hidden()) {
3253 Session::graph_reordered ()
3255 /* don't do this stuff if we are setting up connections
3256 from a set_state() call.
3259 if (_state_of_the_state & InitialConnecting) {
3265 /* force all diskstreams to update their capture offset values to
3266 reflect any changes in latencies within the graph.
3269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3272 (*i)->set_capture_offset ();
3277 Session::record_disenable_all ()
3279 record_enable_change_all (false);
3283 Session::record_enable_all ()
3285 record_enable_change_all (true);
3289 Session::record_enable_change_all (bool yn)
3291 shared_ptr<RouteList> r = routes.reader ();
3293 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3296 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3297 at->set_record_enable (yn, this);
3301 /* since we don't keep rec-enable state, don't mark session dirty */
3305 Session::add_redirect (Redirect* redirect)
3309 PortInsert* port_insert;
3310 PluginInsert* plugin_insert;
3312 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3313 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3314 _port_inserts.insert (_port_inserts.begin(), port_insert);
3315 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3316 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3318 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3321 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3322 _sends.insert (_sends.begin(), send);
3324 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3328 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3334 Session::remove_redirect (Redirect* redirect)
3338 PortInsert* port_insert;
3339 PluginInsert* plugin_insert;
3341 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3342 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3343 _port_inserts.remove (port_insert);
3344 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3345 _plugin_inserts.remove (plugin_insert);
3347 fatal << string_compose (_("programming error: %1"),
3348 X_("unknown type of Insert deleted!"))
3352 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3353 _sends.remove (send);
3355 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3363 Session::available_capture_duration ()
3365 float sample_bytes_on_disk;
3367 switch (Config->get_native_file_data_format()) {
3369 sample_bytes_on_disk = 4;
3373 sample_bytes_on_disk = 3;
3377 /* impossible, but keep some gcc versions happy */
3378 fatal << string_compose (_("programming error: %1"),
3379 X_("illegal native file data format"))
3384 double scale = 4096.0 / sample_bytes_on_disk;
3386 if (_total_free_4k_blocks * scale > (double) max_frames) {
3390 return (nframes_t) floor (_total_free_4k_blocks * scale);
3394 Session::add_connection (ARDOUR::Connection* connection)
3397 Glib::Mutex::Lock guard (connection_lock);
3398 _connections.push_back (connection);
3401 ConnectionAdded (connection); /* EMIT SIGNAL */
3407 Session::remove_connection (ARDOUR::Connection* connection)
3409 bool removed = false;
3412 Glib::Mutex::Lock guard (connection_lock);
3413 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3415 if (i != _connections.end()) {
3416 _connections.erase (i);
3422 ConnectionRemoved (connection); /* EMIT SIGNAL */
3428 ARDOUR::Connection *
3429 Session::connection_by_name (string name) const
3431 Glib::Mutex::Lock lm (connection_lock);
3433 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3434 if ((*i)->name() == name) {
3443 Session::tempo_map_changed (Change ignored)
3450 Session::ensure_passthru_buffers (uint32_t howmany)
3452 while (howmany > _passthru_buffers.size()) {
3454 #ifdef NO_POSIX_MEMALIGN
3455 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3457 posix_memalign((void **)&p,16,current_block_size * 4);
3459 _passthru_buffers.push_back (p);
3463 #ifdef NO_POSIX_MEMALIGN
3464 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3466 posix_memalign((void **)&p,16,current_block_size * 4);
3468 memset (p, 0, sizeof (Sample) * current_block_size);
3469 _silent_buffers.push_back (p);
3473 #ifdef NO_POSIX_MEMALIGN
3474 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3476 posix_memalign((void **)&p,16,current_block_size * 4);
3478 memset (p, 0, sizeof (Sample) * current_block_size);
3479 _send_buffers.push_back (p);
3482 allocate_pan_automation_buffers (current_block_size, howmany, false);
3486 Session::next_send_name ()
3490 shared_ptr<RouteList> r = routes.reader ();
3492 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3493 cnt += (*i)->count_sends ();
3496 return string_compose (_("send %1"), ++cnt);
3500 Session::next_insert_name ()
3503 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3507 /* Named Selection management */
3510 Session::named_selection_by_name (string name)
3512 Glib::Mutex::Lock lm (named_selection_lock);
3513 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3514 if ((*i)->name == name) {
3522 Session::add_named_selection (NamedSelection* named_selection)
3525 Glib::Mutex::Lock lm (named_selection_lock);
3526 named_selections.insert (named_selections.begin(), named_selection);
3531 NamedSelectionAdded (); /* EMIT SIGNAL */
3535 Session::remove_named_selection (NamedSelection* named_selection)
3537 bool removed = false;
3540 Glib::Mutex::Lock lm (named_selection_lock);
3542 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3544 if (i != named_selections.end()) {
3546 named_selections.erase (i);
3553 NamedSelectionRemoved (); /* EMIT SIGNAL */
3558 Session::reset_native_file_format ()
3560 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3562 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3563 (*i)->reset_write_sources (false);
3568 Session::route_name_unique (string n) const
3570 shared_ptr<RouteList> r = routes.reader ();
3572 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3573 if ((*i)->name() == n) {
3582 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3584 return fs->move_to_trash (dead_sound_dir_name);
3588 Session::n_playlists () const
3590 Glib::Mutex::Lock lm (playlist_lock);
3591 return playlists.size();
3595 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3597 if (!force && howmany <= _npan_buffers) {
3601 if (_pan_automation_buffer) {
3603 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3604 delete [] _pan_automation_buffer[i];
3607 delete [] _pan_automation_buffer;
3610 _pan_automation_buffer = new pan_t*[howmany];
3612 for (uint32_t i = 0; i < howmany; ++i) {
3613 _pan_automation_buffer[i] = new pan_t[nframes];
3616 _npan_buffers = howmany;
3620 Session::freeze (InterThreadInfo& itt)
3622 shared_ptr<RouteList> r = routes.reader ();
3624 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3628 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3629 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3640 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3641 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3644 boost::shared_ptr<Playlist> playlist;
3645 boost::shared_ptr<AudioFileSource> fsource;
3647 char buf[PATH_MAX+1];
3651 nframes_t this_chunk;
3653 vector<Sample*> buffers;
3655 // any bigger than this seems to cause stack overflows in called functions
3656 const nframes_t chunk_size = (128 * 1024)/4;
3658 g_atomic_int_set (&processing_prohibited, 1);
3660 /* call tree *MUST* hold route_lock */
3662 if ((playlist = track.diskstream()->playlist()) == 0) {
3666 /* external redirects will be a problem */
3668 if (track.has_external_redirects()) {
3672 nchans = track.audio_diskstream()->n_channels();
3674 dir = discover_best_sound_dir ();
3676 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3678 for (x = 0; x < 99999; ++x) {
3679 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3680 if (access (buf, F_OK) != 0) {
3686 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3691 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3694 catch (failed_constructor& err) {
3695 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3699 srcs.push_back (fsource);
3702 /* XXX need to flush all redirects */
3707 /* create a set of reasonably-sized buffers */
3709 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3711 #ifdef NO_POSIX_MEMALIGN
3712 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3714 posix_memalign((void **)&b,16,chunk_size * 4);
3716 buffers.push_back (b);
3719 while (to_do && !itt.cancel) {
3721 this_chunk = min (to_do, chunk_size);
3723 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3728 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3729 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3732 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3738 start += this_chunk;
3739 to_do -= this_chunk;
3741 itt.progress = (float) (1.0 - ((double) to_do / len));
3750 xnow = localtime (&now);
3752 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3753 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3756 afs->update_header (position, *xnow, now);
3760 /* build peakfile for new source */
3762 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3763 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3765 afs->build_peaks ();
3769 /* construct a region to represent the bounced material */
3771 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3772 region_name_from_path (srcs.front()->name()));
3779 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3780 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3783 afs->mark_for_remove ();
3786 (*src)->drop_references ();
3790 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3794 g_atomic_int_set (&processing_prohibited, 0);
3802 Session::get_silent_buffers (uint32_t howmany)
3804 for (uint32_t i = 0; i < howmany; ++i) {
3805 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3807 return _silent_buffers;
3811 Session::ntracks () const
3814 shared_ptr<RouteList> r = routes.reader ();
3816 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3817 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3826 Session::nbusses () const
3829 shared_ptr<RouteList> r = routes.reader ();
3831 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3832 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3841 Session::add_automation_list(AutomationList *al)
3843 automation_lists[al->id()] = al;
3847 Session::compute_initial_length ()
3849 return _engine.frame_rate() * 60 * 5;