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 set_block_size (_engine.frames_per_cycle());
634 set_frame_rate (_engine.frame_rate());
636 Config->map_parameters (mem_fun (*this, &Session::config_changed));
638 /* every time we reconnect, recompute worst case output latencies */
640 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
642 if (synced_to_jack()) {
643 _engine.transport_stop ();
646 if (Config->get_jack_time_master()) {
647 _engine.transport_locate (_transport_frame);
655 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
657 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
659 /* existing state for Click */
661 if (_click_io->set_state (*child->children().front()) == 0) {
663 _clicking = Config->get_clicking ();
667 error << _("could not setup Click I/O") << endmsg;
673 /* default state for Click */
675 first_physical_output = _engine.get_nth_physical_output (0);
677 if (first_physical_output.length()) {
678 if (_click_io->add_output_port (first_physical_output, this)) {
679 // relax, even though its an error
681 _clicking = Config->get_clicking ();
687 catch (failed_constructor& err) {
688 error << _("cannot setup Click I/O") << endmsg;
691 set_worst_io_latencies ();
694 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
697 /* Create a set of Connection objects that map
698 to the physical outputs currently available
703 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
705 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
707 Connection* c = new OutputConnection (buf, true);
710 c->add_connection (0, _engine.get_nth_physical_output (np));
715 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
717 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
719 Connection* c = new InputConnection (buf, true);
722 c->add_connection (0, _engine.get_nth_physical_input (np));
729 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
731 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
733 Connection* c = new OutputConnection (buf, true);
737 c->add_connection (0, _engine.get_nth_physical_output (np));
738 c->add_connection (1, _engine.get_nth_physical_output (np+1));
743 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
745 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
747 Connection* c = new InputConnection (buf, true);
751 c->add_connection (0, _engine.get_nth_physical_input (np));
752 c->add_connection (1, _engine.get_nth_physical_input (np+1));
761 /* create master/control ports */
766 /* force the master to ignore any later call to this */
768 if (_master_out->pending_state_node) {
769 _master_out->ports_became_legal();
772 /* no panner resets till we are through */
774 _master_out->defer_pan_reset ();
776 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
777 if (_master_out->add_input_port ("", this)) {
778 error << _("cannot setup master inputs")
784 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
785 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
786 error << _("cannot setup master outputs")
793 _master_out->allow_pan_reset ();
797 Connection* c = new OutputConnection (_("Master Out"), true);
799 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
801 c->add_connection ((int) n, _master_out->input(n)->name());
808 /* catch up on send+insert cnts */
812 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
815 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
816 if (id > insert_cnt) {
824 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
827 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
835 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
837 /* hook us up to the engine */
839 _engine.set_session (this);
844 osc->set_session (*this);
847 _state_of_the_state = Clean;
849 DirtyChanged (); /* EMIT SIGNAL */
853 Session::hookup_io ()
855 /* stop graph reordering notifications from
856 causing resorts, etc.
859 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
861 if (auditioner == 0) {
863 /* we delay creating the auditioner till now because
864 it makes its own connections to ports.
865 the engine has to be running for this to work.
869 auditioner.reset (new Auditioner (*this));
872 catch (failed_constructor& err) {
873 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
877 /* Tell all IO objects to create their ports */
884 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
885 if (_control_out->add_input_port ("", this)) {
886 error << _("cannot setup control inputs")
892 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
893 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
894 error << _("cannot set up master outputs")
902 /* Tell all IO objects to connect themselves together */
904 IO::enable_connecting ();
906 /* Now reset all panners */
908 IO::reset_panners ();
910 /* Anyone who cares about input state, wake up and do something */
912 IOConnectionsComplete (); /* EMIT SIGNAL */
914 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
916 /* now handle the whole enchilada as if it was one
922 /* update mixer solo state */
928 Session::playlist_length_changed ()
930 /* we can't just increase end_location->end() if pl->get_maximum_extent()
931 if larger. if the playlist used to be the longest playlist,
932 and its now shorter, we have to decrease end_location->end(). hence,
933 we have to iterate over all diskstreams and check the
934 playlists currently in use.
940 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
942 boost::shared_ptr<Playlist> playlist;
944 if ((playlist = dstream->playlist()) != 0) {
945 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
948 /* see comment in playlist_length_changed () */
953 Session::record_enabling_legal () const
955 /* this used to be in here, but survey says.... we don't need to restrict it */
956 // if (record_status() == Recording) {
960 if (Config->get_all_safe()) {
967 Session::reset_input_monitor_state ()
969 if (transport_rolling()) {
971 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
973 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
974 if ((*i)->record_enabled ()) {
975 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
976 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
980 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
982 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
983 if ((*i)->record_enabled ()) {
984 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
985 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
992 Session::auto_punch_start_changed (Location* location)
994 replace_event (Event::PunchIn, location->start());
996 if (get_record_enabled() && Config->get_punch_in()) {
997 /* capture start has been changed, so save new pending state */
998 save_state ("", true);
1003 Session::auto_punch_end_changed (Location* location)
1005 nframes_t when_to_stop = location->end();
1006 // when_to_stop += _worst_output_latency + _worst_input_latency;
1007 replace_event (Event::PunchOut, when_to_stop);
1011 Session::auto_punch_changed (Location* location)
1013 nframes_t when_to_stop = location->end();
1015 replace_event (Event::PunchIn, location->start());
1016 //when_to_stop += _worst_output_latency + _worst_input_latency;
1017 replace_event (Event::PunchOut, when_to_stop);
1021 Session::auto_loop_changed (Location* location)
1023 replace_event (Event::AutoLoop, location->end(), location->start());
1025 if (transport_rolling() && play_loop) {
1027 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1029 if (_transport_frame > location->end()) {
1030 // relocate to beginning of loop
1031 clear_events (Event::LocateRoll);
1033 request_locate (location->start(), true);
1036 else if (Config->get_seamless_loop() && !loop_changing) {
1038 // schedule a locate-roll to refill the diskstreams at the
1039 // previous loop end
1040 loop_changing = true;
1042 if (location->end() > last_loopend) {
1043 clear_events (Event::LocateRoll);
1044 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1051 last_loopend = location->end();
1056 Session::set_auto_punch_location (Location* location)
1060 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1061 auto_punch_start_changed_connection.disconnect();
1062 auto_punch_end_changed_connection.disconnect();
1063 auto_punch_changed_connection.disconnect();
1064 existing->set_auto_punch (false, this);
1065 remove_event (existing->start(), Event::PunchIn);
1066 clear_events (Event::PunchOut);
1067 auto_punch_location_changed (0);
1072 if (location == 0) {
1076 if (location->end() <= location->start()) {
1077 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1081 auto_punch_start_changed_connection.disconnect();
1082 auto_punch_end_changed_connection.disconnect();
1083 auto_punch_changed_connection.disconnect();
1085 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1086 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1087 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1089 location->set_auto_punch (true, this);
1090 auto_punch_location_changed (location);
1094 Session::set_auto_loop_location (Location* location)
1098 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1099 auto_loop_start_changed_connection.disconnect();
1100 auto_loop_end_changed_connection.disconnect();
1101 auto_loop_changed_connection.disconnect();
1102 existing->set_auto_loop (false, this);
1103 remove_event (existing->end(), Event::AutoLoop);
1104 auto_loop_location_changed (0);
1109 if (location == 0) {
1113 if (location->end() <= location->start()) {
1114 error << _("Session: you can't use a mark for auto loop") << endmsg;
1118 last_loopend = location->end();
1120 auto_loop_start_changed_connection.disconnect();
1121 auto_loop_end_changed_connection.disconnect();
1122 auto_loop_changed_connection.disconnect();
1124 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1125 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1126 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1128 location->set_auto_loop (true, this);
1129 auto_loop_location_changed (location);
1133 Session::locations_added (Location* ignored)
1139 Session::locations_changed ()
1141 _locations.apply (*this, &Session::handle_locations_changed);
1145 Session::handle_locations_changed (Locations::LocationList& locations)
1147 Locations::LocationList::iterator i;
1149 bool set_loop = false;
1150 bool set_punch = false;
1152 for (i = locations.begin(); i != locations.end(); ++i) {
1156 if (location->is_auto_punch()) {
1157 set_auto_punch_location (location);
1160 if (location->is_auto_loop()) {
1161 set_auto_loop_location (location);
1168 set_auto_loop_location (0);
1171 set_auto_punch_location (0);
1178 Session::enable_record ()
1180 /* XXX really atomic compare+swap here */
1181 if (g_atomic_int_get (&_record_status) != Recording) {
1182 g_atomic_int_set (&_record_status, Recording);
1183 _last_record_location = _transport_frame;
1184 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1186 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1187 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1188 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1189 if ((*i)->record_enabled ()) {
1190 (*i)->monitor_input (true);
1195 RecordStateChanged ();
1200 Session::disable_record (bool rt_context, bool force)
1204 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1206 if (!Config->get_latched_record_enable () || force) {
1207 g_atomic_int_set (&_record_status, Disabled);
1209 if (rs == Recording) {
1210 g_atomic_int_set (&_record_status, Enabled);
1214 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1216 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1217 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1219 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1220 if ((*i)->record_enabled ()) {
1221 (*i)->monitor_input (false);
1226 RecordStateChanged (); /* emit signal */
1229 remove_pending_capture_state ();
1235 Session::step_back_from_record ()
1237 g_atomic_int_set (&_record_status, Enabled);
1239 if (Config->get_monitoring_model() == HardwareMonitoring) {
1240 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1242 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1243 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1244 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1245 (*i)->monitor_input (false);
1252 Session::maybe_enable_record ()
1254 g_atomic_int_set (&_record_status, Enabled);
1256 /* this function is currently called from somewhere other than an RT thread.
1257 this save_state() call therefore doesn't impact anything.
1260 save_state ("", true);
1262 if (_transport_speed) {
1263 if (!Config->get_punch_in()) {
1267 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1268 RecordStateChanged (); /* EMIT SIGNAL */
1275 Session::audible_frame () const
1281 /* the first of these two possible settings for "offset"
1282 mean that the audible frame is stationary until
1283 audio emerges from the latency compensation
1286 the second means that the audible frame is stationary
1287 until audio would emerge from a physical port
1288 in the absence of any plugin latency compensation
1291 offset = _worst_output_latency;
1293 if (offset > current_block_size) {
1294 offset -= current_block_size;
1296 /* XXX is this correct? if we have no external
1297 physical connections and everything is internal
1298 then surely this is zero? still, how
1299 likely is that anyway?
1301 offset = current_block_size;
1304 if (synced_to_jack()) {
1305 tf = _engine.transport_frame();
1307 tf = _transport_frame;
1310 if (_transport_speed == 0) {
1320 if (!non_realtime_work_pending()) {
1324 /* take latency into account */
1333 Session::set_frame_rate (nframes_t frames_per_second)
1335 /** \fn void Session::set_frame_size(nframes_t)
1336 the AudioEngine object that calls this guarantees
1337 that it will not be called while we are also in
1338 ::process(). Its fine to do things that block
1342 _base_frame_rate = frames_per_second;
1346 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1348 // XXX we need some equivalent to this, somehow
1349 // SndFileSource::setup_standard_crossfades (frames_per_second);
1353 /* XXX need to reset/reinstantiate all LADSPA plugins */
1357 Session::set_block_size (nframes_t nframes)
1359 /* the AudioEngine guarantees
1360 that it will not be called while we are also in
1361 ::process(). It is therefore fine to do things that block
1366 vector<Sample*>::iterator i;
1369 current_block_size = nframes;
1371 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1375 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1379 _passthru_buffers.clear ();
1380 _silent_buffers.clear ();
1382 ensure_passthru_buffers (np);
1384 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1388 #ifdef NO_POSIX_MEMALIGN
1389 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1391 posix_memalign((void **)&buf,16,current_block_size * 4);
1395 memset (*i, 0, sizeof (Sample) * current_block_size);
1399 if (_gain_automation_buffer) {
1400 delete [] _gain_automation_buffer;
1402 _gain_automation_buffer = new gain_t[nframes];
1404 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1406 boost::shared_ptr<RouteList> r = routes.reader ();
1408 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1409 (*i)->set_block_size (nframes);
1412 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1413 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1414 (*i)->set_block_size (nframes);
1417 set_worst_io_latencies ();
1422 Session::set_default_fade (float steepness, float fade_msecs)
1425 nframes_t fade_frames;
1427 /* Don't allow fade of less 1 frame */
1429 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1436 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1440 default_fade_msecs = fade_msecs;
1441 default_fade_steepness = steepness;
1444 // jlc, WTF is this!
1445 Glib::RWLock::ReaderLock lm (route_lock);
1446 AudioRegion::set_default_fade (steepness, fade_frames);
1451 /* XXX have to do this at some point */
1452 /* foreach region using default fade, reset, then
1453 refill_all_diskstream_buffers ();
1458 struct RouteSorter {
1459 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1460 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1462 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1465 if (r1->fed_by.empty()) {
1466 if (r2->fed_by.empty()) {
1467 /* no ardour-based connections inbound to either route. just use signal order */
1468 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1470 /* r2 has connections, r1 does not; run r1 early */
1474 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1481 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1483 shared_ptr<Route> r2;
1485 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1486 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1490 /* make a copy of the existing list of routes that feed r1 */
1492 set<shared_ptr<Route> > existing = r1->fed_by;
1494 /* for each route that feeds r1, recurse, marking it as feeding
1498 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1501 /* r2 is a route that feeds r1 which somehow feeds base. mark
1502 base as being fed by r2
1505 rbase->fed_by.insert (r2);
1509 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1513 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1517 /* now recurse, so that we can mark base as being fed by
1518 all routes that feed r2
1521 trace_terminal (r2, rbase);
1528 Session::resort_routes ()
1530 /* don't do anything here with signals emitted
1531 by Routes while we are being destroyed.
1534 if (_state_of_the_state & Deletion) {
1541 RCUWriter<RouteList> writer (routes);
1542 shared_ptr<RouteList> r = writer.get_copy ();
1543 resort_routes_using (r);
1544 /* writer goes out of scope and forces update */
1549 Session::resort_routes_using (shared_ptr<RouteList> r)
1551 RouteList::iterator i, j;
1553 for (i = r->begin(); i != r->end(); ++i) {
1555 (*i)->fed_by.clear ();
1557 for (j = r->begin(); j != r->end(); ++j) {
1559 /* although routes can feed themselves, it will
1560 cause an endless recursive descent if we
1561 detect it. so don't bother checking for
1569 if ((*j)->feeds (*i)) {
1570 (*i)->fed_by.insert (*j);
1575 for (i = r->begin(); i != r->end(); ++i) {
1576 trace_terminal (*i, *i);
1582 /* don't leave dangling references to routes in Route::fed_by */
1584 for (i = r->begin(); i != r->end(); ++i) {
1585 (*i)->fed_by.clear ();
1589 cerr << "finished route resort\n";
1591 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1592 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1599 list<boost::shared_ptr<AudioTrack> >
1600 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1602 char track_name[32];
1603 uint32_t track_id = 0;
1605 uint32_t channels_used = 0;
1607 RouteList new_routes;
1608 list<boost::shared_ptr<AudioTrack> > ret;
1610 /* count existing audio tracks */
1613 shared_ptr<RouteList> r = routes.reader ();
1615 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1616 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1617 if (!(*i)->hidden()) {
1619 channels_used += (*i)->n_inputs();
1625 vector<string> physinputs;
1626 vector<string> physoutputs;
1627 uint32_t nphysical_in;
1628 uint32_t nphysical_out;
1630 _engine.get_physical_outputs (physoutputs);
1631 _engine.get_physical_inputs (physinputs);
1635 /* check for duplicate route names, since we might have pre-existing
1636 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1637 save, close,restart,add new route - first named route is now
1645 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1647 if (route_by_name (track_name) == 0) {
1651 } while (track_id < (UINT_MAX-1));
1653 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1654 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1659 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1660 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1666 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1668 if (track->ensure_io (input_channels, output_channels, false, this)) {
1669 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1670 input_channels, output_channels)
1675 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1679 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1680 port = physinputs[(channels_used+x)%nphysical_in];
1683 if (port.length() && track->connect_input (track->input (x), port, this)) {
1689 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1693 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1694 port = physoutputs[(channels_used+x)%nphysical_out];
1695 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1697 port = _master_out->input (x%_master_out->n_inputs())->name();
1701 if (port.length() && track->connect_output (track->output (x), port, this)) {
1706 channels_used += track->n_inputs ();
1709 vector<string> cports;
1710 uint32_t ni = _control_out->n_inputs();
1712 for (n = 0; n < ni; ++n) {
1713 cports.push_back (_control_out->input(n)->name());
1716 track->set_control_outs (cports);
1719 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1720 track->set_remote_control_id (ntracks());
1722 new_routes.push_back (track);
1723 ret.push_back (track);
1726 catch (failed_constructor &err) {
1727 error << _("Session: could not create new audio track.") << endmsg;
1728 // XXX should we delete the tracks already created?
1736 if (!new_routes.empty()) {
1737 add_routes (new_routes, false);
1738 save_state (_current_snapshot_name);
1745 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1748 uint32_t bus_id = 1;
1753 /* count existing audio busses */
1756 shared_ptr<RouteList> r = routes.reader ();
1758 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1759 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1760 if (!(*i)->hidden()) {
1767 vector<string> physinputs;
1768 vector<string> physoutputs;
1770 _engine.get_physical_outputs (physoutputs);
1771 _engine.get_physical_inputs (physinputs);
1778 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1780 if (route_by_name (bus_name) == 0) {
1784 } while (bus_id < (UINT_MAX-1));
1787 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1789 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1790 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1791 input_channels, output_channels)
1795 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1799 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1800 port = physinputs[((n+x)%n_physical_inputs)];
1803 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1808 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1812 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1813 port = physoutputs[((n+x)%n_physical_outputs)];
1814 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1816 port = _master_out->input (x%_master_out->n_inputs())->name();
1820 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1826 vector<string> cports;
1827 uint32_t ni = _control_out->n_inputs();
1829 for (uint32_t n = 0; n < ni; ++n) {
1830 cports.push_back (_control_out->input(n)->name());
1832 bus->set_control_outs (cports);
1835 ret.push_back (bus);
1839 catch (failed_constructor &err) {
1840 error << _("Session: could not create new audio route.") << endmsg;
1849 add_routes (ret, false);
1850 save_state (_current_snapshot_name);
1858 Session::add_routes (RouteList& new_routes, bool save)
1861 RCUWriter<RouteList> writer (routes);
1862 shared_ptr<RouteList> r = writer.get_copy ();
1863 r->insert (r->end(), new_routes.begin(), new_routes.end());
1864 resort_routes_using (r);
1867 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1869 boost::weak_ptr<Route> wpr (*x);
1871 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1872 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1873 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1874 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1876 if ((*x)->master()) {
1880 if ((*x)->control()) {
1881 _control_out = (*x);
1888 save_state (_current_snapshot_name);
1891 RouteAdded (new_routes); /* EMIT SIGNAL */
1895 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1897 /* need to do this in case we're rolling at the time, to prevent false underruns */
1898 dstream->do_refill_with_alloc();
1901 RCUWriter<DiskstreamList> writer (diskstreams);
1902 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1903 ds->push_back (dstream);
1906 dstream->set_block_size (current_block_size);
1908 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1909 /* this will connect to future changes, and check the current length */
1910 diskstream_playlist_changed (dstream);
1912 dstream->prepare ();
1916 Session::remove_route (shared_ptr<Route> route)
1919 RCUWriter<RouteList> writer (routes);
1920 shared_ptr<RouteList> rs = writer.get_copy ();
1924 /* deleting the master out seems like a dumb
1925 idea, but its more of a UI policy issue
1929 if (route == _master_out) {
1930 _master_out = shared_ptr<Route> ();
1933 if (route == _control_out) {
1934 _control_out = shared_ptr<Route> ();
1936 /* cancel control outs for all routes */
1938 vector<string> empty;
1940 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1941 (*r)->set_control_outs (empty);
1945 update_route_solo_state ();
1947 /* writer goes out of scope, forces route list update */
1950 // FIXME: audio specific
1952 boost::shared_ptr<AudioDiskstream> ds;
1954 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1955 ds = at->audio_diskstream();
1961 RCUWriter<DiskstreamList> dsl (diskstreams);
1962 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1967 find_current_end ();
1969 update_latency_compensation (false, false);
1972 // We need to disconnect the routes inputs and outputs
1973 route->disconnect_inputs(NULL);
1974 route->disconnect_outputs(NULL);
1976 /* get rid of it from the dead wood collection in the route list manager */
1978 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1982 /* try to cause everyone to drop their references */
1984 route->drop_references ();
1986 /* save the new state of the world */
1988 if (save_state (_current_snapshot_name)) {
1989 save_history (_current_snapshot_name);
1994 Session::route_mute_changed (void* src)
2000 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2002 if (solo_update_disabled) {
2008 boost::shared_ptr<Route> route = wpr.lock ();
2011 /* should not happen */
2012 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2016 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2018 shared_ptr<RouteList> r = routes.reader ();
2020 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2022 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2026 /* don't mess with busses */
2028 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2034 /* don't mess with tracks */
2036 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2041 if ((*i) != route &&
2042 ((*i)->mix_group () == 0 ||
2043 (*i)->mix_group () != route->mix_group () ||
2044 !route->mix_group ()->is_active())) {
2046 if ((*i)->soloed()) {
2048 /* if its already soloed, and solo latching is enabled,
2049 then leave it as it is.
2052 if (Config->get_solo_latched()) {
2059 solo_update_disabled = true;
2060 (*i)->set_solo (false, src);
2061 solo_update_disabled = false;
2065 bool something_soloed = false;
2066 bool same_thing_soloed = false;
2067 bool signal = false;
2069 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2070 if ((*i)->soloed()) {
2071 something_soloed = true;
2072 if (dynamic_cast<AudioTrack*>((*i).get())) {
2074 same_thing_soloed = true;
2079 same_thing_soloed = true;
2087 if (something_soloed != currently_soloing) {
2089 currently_soloing = something_soloed;
2092 modify_solo_mute (is_track, same_thing_soloed);
2095 SoloActive (currently_soloing);
2102 Session::update_route_solo_state ()
2105 bool is_track = false;
2106 bool signal = false;
2108 /* caller must hold RouteLock */
2110 /* this is where we actually implement solo by changing
2111 the solo mute setting of each track.
2114 shared_ptr<RouteList> r = routes.reader ();
2116 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2117 if ((*i)->soloed()) {
2119 if (dynamic_cast<AudioTrack*>((*i).get())) {
2126 if (mute != currently_soloing) {
2128 currently_soloing = mute;
2131 if (!is_track && !mute) {
2133 /* nothing is soloed */
2135 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2136 (*i)->set_solo_mute (false);
2146 modify_solo_mute (is_track, mute);
2149 SoloActive (currently_soloing);
2154 Session::modify_solo_mute (bool is_track, bool mute)
2156 shared_ptr<RouteList> r = routes.reader ();
2158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2162 /* only alter track solo mute */
2164 if (dynamic_cast<AudioTrack*>((*i).get())) {
2165 if ((*i)->soloed()) {
2166 (*i)->set_solo_mute (!mute);
2168 (*i)->set_solo_mute (mute);
2174 /* only alter bus solo mute */
2176 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2178 if ((*i)->soloed()) {
2180 (*i)->set_solo_mute (false);
2184 /* don't mute master or control outs
2185 in response to another bus solo
2188 if ((*i) != _master_out &&
2189 (*i) != _control_out) {
2190 (*i)->set_solo_mute (mute);
2201 Session::catch_up_on_solo ()
2203 /* this is called after set_state() to catch the full solo
2204 state, which can't be correctly determined on a per-route
2205 basis, but needs the global overview that only the session
2208 update_route_solo_state();
2212 Session::route_by_name (string name)
2214 shared_ptr<RouteList> r = routes.reader ();
2216 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2217 if ((*i)->name() == name) {
2222 return shared_ptr<Route> ((Route*) 0);
2226 Session::route_by_id (PBD::ID id)
2228 shared_ptr<RouteList> r = routes.reader ();
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if ((*i)->id() == id) {
2236 return shared_ptr<Route> ((Route*) 0);
2240 Session::route_by_remote_id (uint32_t id)
2242 shared_ptr<RouteList> r = routes.reader ();
2244 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2245 if ((*i)->remote_control_id() == id) {
2250 return shared_ptr<Route> ((Route*) 0);
2254 Session::find_current_end ()
2256 if (_state_of_the_state & Loading) {
2260 nframes_t max = get_maximum_extent ();
2262 if (max > end_location->end()) {
2263 end_location->set_end (max);
2265 DurationChanged(); /* EMIT SIGNAL */
2270 Session::get_maximum_extent () const
2275 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2277 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2278 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2279 if ((me = pl->get_maximum_extent()) > max) {
2287 boost::shared_ptr<Diskstream>
2288 Session::diskstream_by_name (string name)
2290 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2292 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2293 if ((*i)->name() == name) {
2298 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2301 boost::shared_ptr<Diskstream>
2302 Session::diskstream_by_id (const PBD::ID& id)
2304 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2306 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2307 if ((*i)->id() == id) {
2312 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2315 /* AudioRegion management */
2318 Session::new_region_name (string old)
2320 string::size_type last_period;
2322 string::size_type len = old.length() + 64;
2325 if ((last_period = old.find_last_of ('.')) == string::npos) {
2327 /* no period present - add one explicitly */
2330 last_period = old.length() - 1;
2335 number = atoi (old.substr (last_period+1).c_str());
2339 while (number < (UINT_MAX-1)) {
2341 AudioRegionList::const_iterator i;
2346 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2349 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2350 if (i->second->name() == sbuf) {
2355 if (i == audio_regions.end()) {
2360 if (number != (UINT_MAX-1)) {
2364 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2369 Session::region_name (string& result, string base, bool newlevel) const
2376 Glib::Mutex::Lock lm (region_lock);
2378 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2386 /* XXX this is going to be slow. optimize me later */
2391 string::size_type pos;
2393 pos = base.find_last_of ('.');
2395 /* pos may be npos, but then we just use entire base */
2397 subbase = base.substr (0, pos);
2401 bool name_taken = true;
2404 Glib::Mutex::Lock lm (region_lock);
2406 for (int n = 1; n < 5000; ++n) {
2409 snprintf (buf, sizeof (buf), ".%d", n);
2414 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2415 if (i->second->name() == result) {
2428 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2436 Session::add_region (boost::shared_ptr<Region> region)
2438 boost::shared_ptr<AudioRegion> ar;
2439 boost::shared_ptr<AudioRegion> oar;
2443 Glib::Mutex::Lock lm (region_lock);
2445 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2447 AudioRegionList::iterator x;
2449 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2451 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2453 if (ar->region_list_equivalent (oar)) {
2458 if (x == audio_regions.end()) {
2460 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2462 entry.first = region->id();
2465 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2477 fatal << _("programming error: ")
2478 << X_("unknown region type passed to Session::add_region()")
2485 /* mark dirty because something has changed even if we didn't
2486 add the region to the region list.
2492 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2493 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2494 AudioRegionAdded (ar); /* EMIT SIGNAL */
2499 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2501 boost::shared_ptr<Region> region (weak_region.lock ());
2507 if (what_changed & Region::HiddenChanged) {
2508 /* relay hidden changes */
2509 RegionHiddenChange (region);
2514 Session::remove_region (boost::weak_ptr<Region> weak_region)
2516 AudioRegionList::iterator i;
2517 boost::shared_ptr<Region> region (weak_region.lock ());
2523 boost::shared_ptr<AudioRegion> ar;
2524 bool removed = false;
2527 Glib::Mutex::Lock lm (region_lock);
2529 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2530 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2531 audio_regions.erase (i);
2537 fatal << _("programming error: ")
2538 << X_("unknown region type passed to Session::remove_region()")
2544 /* mark dirty because something has changed even if we didn't
2545 remove the region from the region list.
2551 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2555 boost::shared_ptr<AudioRegion>
2556 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2558 AudioRegionList::iterator i;
2559 boost::shared_ptr<AudioRegion> region;
2560 Glib::Mutex::Lock lm (region_lock);
2562 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2566 if (region->whole_file()) {
2568 if (child->source_equivalent (region)) {
2574 return boost::shared_ptr<AudioRegion> ();
2578 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2580 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2581 (*i)->get_region_list_equivalent_regions (region, result);
2585 Session::destroy_region (boost::shared_ptr<Region> region)
2587 vector<boost::shared_ptr<Source> > srcs;
2590 boost::shared_ptr<AudioRegion> aregion;
2592 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2596 if (aregion->playlist()) {
2597 aregion->playlist()->destroy_region (region);
2600 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2601 srcs.push_back (aregion->source (n));
2605 region->drop_references ();
2607 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2609 if (!(*i)->used()) {
2610 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2613 (afs)->mark_for_remove ();
2616 (*i)->drop_references ();
2618 cerr << "source was not used by any playlist\n";
2626 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2628 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2629 destroy_region (*i);
2635 Session::remove_last_capture ()
2637 list<boost::shared_ptr<Region> > r;
2639 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2641 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2642 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2645 r.insert (r.end(), l.begin(), l.end());
2650 destroy_regions (r);
2655 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2661 /* Source Management */
2664 Session::add_source (boost::shared_ptr<Source> source)
2666 boost::shared_ptr<AudioFileSource> afs;
2668 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2670 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2671 pair<AudioSourceList::iterator,bool> result;
2673 entry.first = source->id();
2677 Glib::Mutex::Lock lm (audio_source_lock);
2678 result = audio_sources.insert (entry);
2681 if (result.second) {
2682 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2690 Session::remove_source (boost::weak_ptr<Source> src)
2692 AudioSourceList::iterator i;
2693 boost::shared_ptr<Source> source = src.lock();
2700 Glib::Mutex::Lock lm (audio_source_lock);
2702 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2703 audio_sources.erase (i);
2707 if (!_state_of_the_state & InCleanup) {
2709 /* save state so we don't end up with a session file
2710 referring to non-existent sources.
2713 save_state (_current_snapshot_name);
2717 boost::shared_ptr<Source>
2718 Session::source_by_id (const PBD::ID& id)
2720 Glib::Mutex::Lock lm (audio_source_lock);
2721 AudioSourceList::iterator i;
2722 boost::shared_ptr<Source> source;
2724 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2728 /* XXX search MIDI or other searches here */
2734 Session::peak_path_from_audio_path (string audio_path) const
2739 res += PBD::basename_nosuffix (audio_path);
2746 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2749 string old_basename = PBD::basename_nosuffix (oldname);
2750 string new_legalized = legalize_for_path (newname);
2752 /* note: we know (or assume) the old path is already valid */
2756 /* destructive file sources have a name of the form:
2758 /path/to/Tnnnn-NAME(%[LR])?.wav
2760 the task here is to replace NAME with the new name.
2763 /* find last slash */
2767 string::size_type slash;
2768 string::size_type dash;
2770 if ((slash = path.find_last_of ('/')) == string::npos) {
2774 dir = path.substr (0, slash+1);
2776 /* '-' is not a legal character for the NAME part of the path */
2778 if ((dash = path.find_last_of ('-')) == string::npos) {
2782 prefix = path.substr (slash+1, dash-(slash+1));
2787 path += new_legalized;
2788 path += ".wav"; /* XXX gag me with a spoon */
2792 /* non-destructive file sources have a name of the form:
2794 /path/to/NAME-nnnnn(%[LR])?.wav
2796 the task here is to replace NAME with the new name.
2801 string::size_type slash;
2802 string::size_type dash;
2803 string::size_type postfix;
2805 /* find last slash */
2807 if ((slash = path.find_last_of ('/')) == string::npos) {
2811 dir = path.substr (0, slash+1);
2813 /* '-' is not a legal character for the NAME part of the path */
2815 if ((dash = path.find_last_of ('-')) == string::npos) {
2819 suffix = path.substr (dash+1);
2821 // Suffix is now everything after the dash. Now we need to eliminate
2822 // the nnnnn part, which is done by either finding a '%' or a '.'
2824 postfix = suffix.find_last_of ("%");
2825 if (postfix == string::npos) {
2826 postfix = suffix.find_last_of ('.');
2829 if (postfix != string::npos) {
2830 suffix = suffix.substr (postfix);
2832 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2836 const uint32_t limit = 10000;
2837 char buf[PATH_MAX+1];
2839 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2841 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2843 if (access (buf, F_OK) != 0) {
2851 error << "FATAL ERROR! Could not find a " << endl;
2860 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2864 char buf[PATH_MAX+1];
2865 const uint32_t limit = 10000;
2869 legalized = legalize_for_path (name);
2871 /* find a "version" of the file name that doesn't exist in
2872 any of the possible directories.
2875 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2877 vector<space_and_path>::iterator i;
2878 uint32_t existing = 0;
2880 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2884 spath += sound_dir (false);
2888 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2889 } else if (nchan == 2) {
2891 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2893 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2895 } else if (nchan < 26) {
2896 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2898 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2907 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2908 } else if (nchan == 2) {
2910 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2912 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2914 } else if (nchan < 26) {
2915 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2917 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2921 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2927 if (existing == 0) {
2932 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2933 throw failed_constructor();
2937 /* we now have a unique name for the file, but figure out where to
2943 spath = discover_best_sound_dir ();
2946 string::size_type pos = foo.find_last_of ('/');
2948 if (pos == string::npos) {
2951 spath += foo.substr (pos + 1);
2957 boost::shared_ptr<AudioFileSource>
2958 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2960 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2961 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2964 /* Playlist management */
2966 boost::shared_ptr<Playlist>
2967 Session::playlist_by_name (string name)
2969 Glib::Mutex::Lock lm (playlist_lock);
2970 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2971 if ((*i)->name() == name) {
2975 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2976 if ((*i)->name() == name) {
2981 return boost::shared_ptr<Playlist>();
2985 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
2987 if (playlist->hidden()) {
2992 Glib::Mutex::Lock lm (playlist_lock);
2993 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2994 playlists.insert (playlists.begin(), playlist);
2995 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
2996 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3002 PlaylistAdded (playlist); /* EMIT SIGNAL */
3006 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3009 Glib::Mutex::Lock lm (playlist_lock);
3010 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3013 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3020 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3022 boost::shared_ptr<Playlist> pl(wpl.lock());
3028 PlaylistList::iterator x;
3031 /* its not supposed to be visible */
3036 Glib::Mutex::Lock lm (playlist_lock);
3040 unused_playlists.insert (pl);
3042 if ((x = playlists.find (pl)) != playlists.end()) {
3043 playlists.erase (x);
3049 playlists.insert (pl);
3051 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3052 unused_playlists.erase (x);
3059 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3061 if (_state_of_the_state & Deletion) {
3065 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3072 Glib::Mutex::Lock lm (playlist_lock);
3073 cerr << "removing playlist: " << playlist->name() << endl;
3075 PlaylistList::iterator i;
3077 i = find (playlists.begin(), playlists.end(), playlist);
3078 if (i != playlists.end()) {
3079 cerr << "\tfound it in used playlist\n";
3080 playlists.erase (i);
3083 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3084 if (i != unused_playlists.end()) {
3085 cerr << "\tfound it in unused playlist\n";
3086 unused_playlists.erase (i);
3093 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3097 Session::set_audition (boost::shared_ptr<Region> r)
3099 pending_audition_region = r;
3100 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3101 schedule_butler_transport_work ();
3105 Session::audition_playlist ()
3107 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3108 ev->region.reset ();
3113 Session::non_realtime_set_audition ()
3115 if (!pending_audition_region) {
3116 auditioner->audition_current_playlist ();
3118 auditioner->audition_region (pending_audition_region);
3119 pending_audition_region.reset ();
3121 AuditionActive (true); /* EMIT SIGNAL */
3125 Session::audition_region (boost::shared_ptr<Region> r)
3127 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3133 Session::cancel_audition ()
3135 if (auditioner->active()) {
3136 auditioner->cancel_audition ();
3137 AuditionActive (false); /* EMIT SIGNAL */
3142 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3144 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3148 Session::remove_empty_sounds ()
3150 PathScanner scanner;
3152 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3154 Glib::Mutex::Lock lm (audio_source_lock);
3156 regex_t compiled_tape_track_pattern;
3159 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3163 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3165 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3169 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3171 /* never remove files that appear to be a tape track */
3173 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3178 if (AudioFileSource::is_empty (*this, *(*i))) {
3180 unlink ((*i)->c_str());
3182 string peak_path = peak_path_from_audio_path (**i);
3183 unlink (peak_path.c_str());
3189 delete possible_audiofiles;
3193 Session::is_auditioning () const
3195 /* can be called before we have an auditioner object */
3197 return auditioner->active();
3204 Session::set_all_solo (bool yn)
3206 shared_ptr<RouteList> r = routes.reader ();
3208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3209 if (!(*i)->hidden()) {
3210 (*i)->set_solo (yn, this);
3218 Session::set_all_mute (bool yn)
3220 shared_ptr<RouteList> r = routes.reader ();
3222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3223 if (!(*i)->hidden()) {
3224 (*i)->set_mute (yn, this);
3232 Session::n_diskstreams () const
3236 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3238 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3239 if (!(*i)->hidden()) {
3247 Session::graph_reordered ()
3249 /* don't do this stuff if we are setting up connections
3250 from a set_state() call.
3253 if (_state_of_the_state & InitialConnecting) {
3257 /* every track/bus asked for this to be handled but it was deferred because
3258 we were connecting. do it now.
3261 request_input_change_handling ();
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(), true));
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;