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");
91 const char* Session::export_dir_name = X_("export");
93 Session::compute_peak_t Session::compute_peak = 0;
94 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
95 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
96 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
98 sigc::signal<int> Session::AskAboutPendingState;
99 sigc::signal<void> Session::SendFeedback;
101 sigc::signal<void> Session::SMPTEOffsetChanged;
102 sigc::signal<void> Session::StartTimeChanged;
103 sigc::signal<void> Session::EndTimeChanged;
106 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
109 char buf[PATH_MAX+1];
113 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
114 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
120 /* check to see if it exists, and what it is */
122 if (stat (str.c_str(), &statbuf)) {
123 if (errno == ENOENT) {
126 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
134 /* it exists, so it must either be the name
135 of the directory, or the name of the statefile
139 if (S_ISDIR (statbuf.st_mode)) {
141 string::size_type slash = str.find_last_of ('/');
143 if (slash == string::npos) {
145 /* a subdirectory of cwd, so statefile should be ... */
151 tmp += _statefile_suffix;
155 if (stat (tmp.c_str(), &statbuf)) {
156 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
166 /* some directory someplace in the filesystem.
167 the snapshot name is the directory name
172 snapshot = str.substr (slash+1);
176 } else if (S_ISREG (statbuf.st_mode)) {
178 string::size_type slash = str.find_last_of ('/');
179 string::size_type suffix;
181 /* remove the suffix */
183 if (slash != string::npos) {
184 snapshot = str.substr (slash+1);
189 suffix = snapshot.find (_statefile_suffix);
191 if (suffix == string::npos) {
192 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
198 snapshot = snapshot.substr (0, suffix);
200 if (slash == string::npos) {
202 /* we must be in the directory where the
203 statefile lives. get it using cwd().
206 char cwd[PATH_MAX+1];
208 if (getcwd (cwd, sizeof (cwd)) == 0) {
209 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
218 /* full path to the statefile */
220 path = str.substr (0, slash);
225 /* what type of file is it? */
226 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
232 /* its the name of a new directory. get the name
236 string::size_type slash = str.find_last_of ('/');
238 if (slash == string::npos) {
240 /* no slash, just use the name, but clean it up */
242 path = legalize_for_path (str);
248 snapshot = str.substr (slash+1);
255 Session::Session (AudioEngine &eng,
257 string snapshot_name,
258 string* mix_template)
261 _mmc_port (default_mmc_port),
262 _mtc_port (default_mtc_port),
263 _midi_port (default_midi_port),
264 pending_events (2048),
265 midi_requests (128), // the size of this should match the midi request pool size
266 diskstreams (new DiskstreamList),
267 routes (new RouteList),
268 auditioner ((Auditioner*) 0),
274 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
276 n_physical_outputs = _engine.n_physical_outputs();
277 n_physical_inputs = _engine.n_physical_inputs();
279 first_stage_init (fullpath, snapshot_name);
281 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
283 if (create (new_session, mix_template, compute_initial_length())) {
284 cerr << "create failed\n";
286 throw failed_constructor ();
290 if (second_stage_init (new_session)) {
292 throw failed_constructor ();
295 store_recent_sessions(_name, _path);
297 bool was_dirty = dirty();
299 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
301 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
304 DirtyChanged (); /* EMIT SIGNAL */
308 Session::Session (AudioEngine &eng,
310 string snapshot_name,
311 AutoConnectOption input_ac,
312 AutoConnectOption output_ac,
313 uint32_t control_out_channels,
314 uint32_t master_out_channels,
315 uint32_t requested_physical_in,
316 uint32_t requested_physical_out,
317 nframes_t initial_length)
320 _mmc_port (default_mmc_port),
321 _mtc_port (default_mtc_port),
322 _midi_port (default_midi_port),
323 pending_events (2048),
325 diskstreams (new DiskstreamList),
326 routes (new RouteList),
332 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
334 n_physical_outputs = _engine.n_physical_outputs();
335 n_physical_inputs = _engine.n_physical_inputs();
337 if (n_physical_inputs) {
338 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
341 if (n_physical_outputs) {
342 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
345 first_stage_init (fullpath, snapshot_name);
347 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
350 if (create (new_session, 0, initial_length)) {
352 throw failed_constructor ();
357 /* set up Master Out and Control Out if necessary */
362 if (control_out_channels) {
363 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
364 r->set_remote_control_id (control_id++);
369 if (master_out_channels) {
370 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
371 r->set_remote_control_id (control_id);
375 /* prohibit auto-connect to master, because there isn't one */
376 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
385 Config->set_input_auto_connect (input_ac);
386 Config->set_output_auto_connect (output_ac);
388 if (second_stage_init (new_session)) {
390 throw failed_constructor ();
393 store_recent_sessions(_name, _path);
395 bool was_dirty = dirty ();
397 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
399 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
402 DirtyChanged (); /* EMIT SIGNAL */
414 /* if we got to here, leaving pending capture state around
418 remove_pending_capture_state ();
420 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
421 _engine.remove_session ();
423 GoingAway (); /* EMIT SIGNAL */
429 /* clear history so that no references to objects are held any more */
433 /* clear state tree so that no references to objects are held any more */
439 terminate_butler_thread ();
440 terminate_midi_thread ();
442 if (click_data && click_data != default_click) {
443 delete [] click_data;
446 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
447 delete [] click_emphasis_data;
452 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
456 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
460 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
464 AudioDiskstream::free_working_buffers();
466 /* this should cause deletion of the auditioner */
468 // auditioner.reset ();
470 #undef TRACK_DESTRUCTION
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete named selections\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
475 NamedSelectionList::iterator tmp;
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete playlists\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
488 PlaylistList::iterator tmp;
493 (*i)->drop_references ();
498 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
499 PlaylistList::iterator tmp;
504 (*i)->drop_references ();
510 unused_playlists.clear ();
512 #ifdef TRACK_DESTRUCTION
513 cerr << "delete audio regions\n";
514 #endif /* TRACK_DESTRUCTION */
516 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
517 AudioRegionList::iterator tmp;
522 i->second->drop_references ();
527 audio_regions.clear ();
529 #ifdef TRACK_DESTRUCTION
530 cerr << "delete routes\n";
531 #endif /* TRACK_DESTRUCTION */
533 RCUWriter<RouteList> writer (routes);
534 boost::shared_ptr<RouteList> r = writer.get_copy ();
535 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
536 (*i)->drop_references ();
539 /* writer goes out of scope and updates master */
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete diskstreams\n";
546 #endif /* TRACK_DESTRUCTION */
548 RCUWriter<DiskstreamList> dwriter (diskstreams);
549 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
550 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
551 (*i)->drop_references ();
555 diskstreams.flush ();
557 #ifdef TRACK_DESTRUCTION
558 cerr << "delete audio sources\n";
559 #endif /* TRACK_DESTRUCTION */
560 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
561 AudioSourceList::iterator tmp;
566 i->second->drop_references ();
571 audio_sources.clear ();
573 #ifdef TRACK_DESTRUCTION
574 cerr << "delete mix groups\n";
575 #endif /* TRACK_DESTRUCTION */
576 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
577 list<RouteGroup*>::iterator tmp;
587 #ifdef TRACK_DESTRUCTION
588 cerr << "delete edit groups\n";
589 #endif /* TRACK_DESTRUCTION */
590 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
591 list<RouteGroup*>::iterator tmp;
601 #ifdef TRACK_DESTRUCTION
602 cerr << "delete connections\n";
603 #endif /* TRACK_DESTRUCTION */
604 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
605 ConnectionList::iterator tmp;
615 if (butler_mixdown_buffer) {
616 delete [] butler_mixdown_buffer;
619 if (butler_gain_buffer) {
620 delete [] butler_gain_buffer;
623 Crossfade::set_buffer_size (0);
631 Session::set_worst_io_latencies ()
633 _worst_output_latency = 0;
634 _worst_input_latency = 0;
636 if (!_engine.connected()) {
640 boost::shared_ptr<RouteList> r = routes.reader ();
642 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
643 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
644 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
649 Session::when_engine_running ()
651 string first_physical_output;
653 /* we don't want to run execute this again */
655 set_block_size (_engine.frames_per_cycle());
656 set_frame_rate (_engine.frame_rate());
658 Config->map_parameters (mem_fun (*this, &Session::config_changed));
660 /* every time we reconnect, recompute worst case output latencies */
662 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
664 if (synced_to_jack()) {
665 _engine.transport_stop ();
668 if (Config->get_jack_time_master()) {
669 _engine.transport_locate (_transport_frame);
677 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
679 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
681 /* existing state for Click */
683 if (_click_io->set_state (*child->children().front()) == 0) {
685 _clicking = Config->get_clicking ();
689 error << _("could not setup Click I/O") << endmsg;
695 /* default state for Click */
697 first_physical_output = _engine.get_nth_physical_output (0);
699 if (first_physical_output.length()) {
700 if (_click_io->add_output_port (first_physical_output, this)) {
701 // relax, even though its an error
703 _clicking = Config->get_clicking ();
709 catch (failed_constructor& err) {
710 error << _("cannot setup Click I/O") << endmsg;
713 set_worst_io_latencies ();
716 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
719 /* Create a set of Connection objects that map
720 to the physical outputs currently available
725 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
727 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
729 Connection* c = new OutputConnection (buf, true);
732 c->add_connection (0, _engine.get_nth_physical_output (np));
737 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
739 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
741 Connection* c = new InputConnection (buf, true);
744 c->add_connection (0, _engine.get_nth_physical_input (np));
751 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
753 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
755 Connection* c = new OutputConnection (buf, true);
759 c->add_connection (0, _engine.get_nth_physical_output (np));
760 c->add_connection (1, _engine.get_nth_physical_output (np+1));
765 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
767 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
769 Connection* c = new InputConnection (buf, true);
773 c->add_connection (0, _engine.get_nth_physical_input (np));
774 c->add_connection (1, _engine.get_nth_physical_input (np+1));
783 /* create master/control ports */
788 /* force the master to ignore any later call to this */
790 if (_master_out->pending_state_node) {
791 _master_out->ports_became_legal();
794 /* no panner resets till we are through */
796 _master_out->defer_pan_reset ();
798 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
799 if (_master_out->add_input_port ("", this)) {
800 error << _("cannot setup master inputs")
806 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
807 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
808 error << _("cannot setup master outputs")
815 _master_out->allow_pan_reset ();
819 Connection* c = new OutputConnection (_("Master Out"), true);
821 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
823 c->add_connection ((int) n, _master_out->input(n)->name());
830 /* catch up on send+insert cnts */
834 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
837 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
838 if (id > insert_cnt) {
846 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
849 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
857 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
859 /* hook us up to the engine */
861 _engine.set_session (this);
866 osc->set_session (*this);
869 _state_of_the_state = Clean;
871 DirtyChanged (); /* EMIT SIGNAL */
875 Session::hookup_io ()
877 /* stop graph reordering notifications from
878 causing resorts, etc.
881 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
883 if (auditioner == 0) {
885 /* we delay creating the auditioner till now because
886 it makes its own connections to ports.
887 the engine has to be running for this to work.
891 auditioner.reset (new Auditioner (*this));
894 catch (failed_constructor& err) {
895 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
899 /* Tell all IO objects to create their ports */
906 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
907 if (_control_out->add_input_port ("", this)) {
908 error << _("cannot setup control inputs")
914 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
915 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
916 error << _("cannot set up master outputs")
924 /* Tell all IO objects to connect themselves together */
926 IO::enable_connecting ();
928 /* Now reset all panners */
930 IO::reset_panners ();
932 /* Anyone who cares about input state, wake up and do something */
934 IOConnectionsComplete (); /* EMIT SIGNAL */
936 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
938 /* now handle the whole enchilada as if it was one
944 /* update mixer solo state */
950 Session::playlist_length_changed ()
952 /* we can't just increase end_location->end() if pl->get_maximum_extent()
953 if larger. if the playlist used to be the longest playlist,
954 and its now shorter, we have to decrease end_location->end(). hence,
955 we have to iterate over all diskstreams and check the
956 playlists currently in use.
962 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
964 boost::shared_ptr<Playlist> playlist;
966 if ((playlist = dstream->playlist()) != 0) {
967 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
970 /* see comment in playlist_length_changed () */
975 Session::record_enabling_legal () const
977 /* this used to be in here, but survey says.... we don't need to restrict it */
978 // if (record_status() == Recording) {
982 if (Config->get_all_safe()) {
989 Session::reset_input_monitor_state ()
991 if (transport_rolling()) {
993 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
995 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
996 if ((*i)->record_enabled ()) {
997 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
998 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1002 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1004 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1005 if ((*i)->record_enabled ()) {
1006 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1007 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1014 Session::auto_punch_start_changed (Location* location)
1016 replace_event (Event::PunchIn, location->start());
1018 if (get_record_enabled() && Config->get_punch_in()) {
1019 /* capture start has been changed, so save new pending state */
1020 save_state ("", true);
1025 Session::auto_punch_end_changed (Location* location)
1027 nframes_t when_to_stop = location->end();
1028 // when_to_stop += _worst_output_latency + _worst_input_latency;
1029 replace_event (Event::PunchOut, when_to_stop);
1033 Session::auto_punch_changed (Location* location)
1035 nframes_t when_to_stop = location->end();
1037 replace_event (Event::PunchIn, location->start());
1038 //when_to_stop += _worst_output_latency + _worst_input_latency;
1039 replace_event (Event::PunchOut, when_to_stop);
1043 Session::auto_loop_changed (Location* location)
1045 replace_event (Event::AutoLoop, location->end(), location->start());
1047 if (transport_rolling() && play_loop) {
1049 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1051 if (_transport_frame > location->end()) {
1052 // relocate to beginning of loop
1053 clear_events (Event::LocateRoll);
1055 request_locate (location->start(), true);
1058 else if (Config->get_seamless_loop() && !loop_changing) {
1060 // schedule a locate-roll to refill the diskstreams at the
1061 // previous loop end
1062 loop_changing = true;
1064 if (location->end() > last_loopend) {
1065 clear_events (Event::LocateRoll);
1066 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1073 last_loopend = location->end();
1078 Session::set_auto_punch_location (Location* location)
1082 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1083 auto_punch_start_changed_connection.disconnect();
1084 auto_punch_end_changed_connection.disconnect();
1085 auto_punch_changed_connection.disconnect();
1086 existing->set_auto_punch (false, this);
1087 remove_event (existing->start(), Event::PunchIn);
1088 clear_events (Event::PunchOut);
1089 auto_punch_location_changed (0);
1094 if (location == 0) {
1098 if (location->end() <= location->start()) {
1099 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1103 auto_punch_start_changed_connection.disconnect();
1104 auto_punch_end_changed_connection.disconnect();
1105 auto_punch_changed_connection.disconnect();
1107 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1108 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1109 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1111 location->set_auto_punch (true, this);
1112 auto_punch_location_changed (location);
1116 Session::set_auto_loop_location (Location* location)
1120 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1121 auto_loop_start_changed_connection.disconnect();
1122 auto_loop_end_changed_connection.disconnect();
1123 auto_loop_changed_connection.disconnect();
1124 existing->set_auto_loop (false, this);
1125 remove_event (existing->end(), Event::AutoLoop);
1126 auto_loop_location_changed (0);
1131 if (location == 0) {
1135 if (location->end() <= location->start()) {
1136 error << _("Session: you can't use a mark for auto loop") << endmsg;
1140 last_loopend = location->end();
1142 auto_loop_start_changed_connection.disconnect();
1143 auto_loop_end_changed_connection.disconnect();
1144 auto_loop_changed_connection.disconnect();
1146 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1147 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1148 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1150 location->set_auto_loop (true, this);
1151 auto_loop_location_changed (location);
1155 Session::locations_added (Location* ignored)
1161 Session::locations_changed ()
1163 _locations.apply (*this, &Session::handle_locations_changed);
1167 Session::handle_locations_changed (Locations::LocationList& locations)
1169 Locations::LocationList::iterator i;
1171 bool set_loop = false;
1172 bool set_punch = false;
1174 for (i = locations.begin(); i != locations.end(); ++i) {
1178 if (location->is_auto_punch()) {
1179 set_auto_punch_location (location);
1182 if (location->is_auto_loop()) {
1183 set_auto_loop_location (location);
1190 set_auto_loop_location (0);
1193 set_auto_punch_location (0);
1200 Session::enable_record ()
1202 /* XXX really atomic compare+swap here */
1203 if (g_atomic_int_get (&_record_status) != Recording) {
1204 g_atomic_int_set (&_record_status, Recording);
1205 _last_record_location = _transport_frame;
1206 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1208 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1209 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1210 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1211 if ((*i)->record_enabled ()) {
1212 (*i)->monitor_input (true);
1217 RecordStateChanged ();
1222 Session::disable_record (bool rt_context, bool force)
1226 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1228 if (!Config->get_latched_record_enable () || force) {
1229 g_atomic_int_set (&_record_status, Disabled);
1231 if (rs == Recording) {
1232 g_atomic_int_set (&_record_status, Enabled);
1236 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1238 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1239 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1241 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1242 if ((*i)->record_enabled ()) {
1243 (*i)->monitor_input (false);
1248 RecordStateChanged (); /* emit signal */
1251 remove_pending_capture_state ();
1257 Session::step_back_from_record ()
1259 g_atomic_int_set (&_record_status, Enabled);
1261 if (Config->get_monitoring_model() == HardwareMonitoring) {
1262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1264 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1265 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1266 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1267 (*i)->monitor_input (false);
1274 Session::maybe_enable_record ()
1276 g_atomic_int_set (&_record_status, Enabled);
1278 /* this function is currently called from somewhere other than an RT thread.
1279 this save_state() call therefore doesn't impact anything.
1282 save_state ("", true);
1284 if (_transport_speed) {
1285 if (!Config->get_punch_in()) {
1289 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1290 RecordStateChanged (); /* EMIT SIGNAL */
1297 Session::audible_frame () const
1303 /* the first of these two possible settings for "offset"
1304 mean that the audible frame is stationary until
1305 audio emerges from the latency compensation
1308 the second means that the audible frame is stationary
1309 until audio would emerge from a physical port
1310 in the absence of any plugin latency compensation
1313 offset = _worst_output_latency;
1315 if (offset > current_block_size) {
1316 offset -= current_block_size;
1318 /* XXX is this correct? if we have no external
1319 physical connections and everything is internal
1320 then surely this is zero? still, how
1321 likely is that anyway?
1323 offset = current_block_size;
1326 if (synced_to_jack()) {
1327 tf = _engine.transport_frame();
1329 tf = _transport_frame;
1332 if (_transport_speed == 0) {
1342 if (!non_realtime_work_pending()) {
1346 /* take latency into account */
1355 Session::set_frame_rate (nframes_t frames_per_second)
1357 /** \fn void Session::set_frame_size(nframes_t)
1358 the AudioEngine object that calls this guarantees
1359 that it will not be called while we are also in
1360 ::process(). Its fine to do things that block
1364 _base_frame_rate = frames_per_second;
1368 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1370 // XXX we need some equivalent to this, somehow
1371 // SndFileSource::setup_standard_crossfades (frames_per_second);
1375 /* XXX need to reset/reinstantiate all LADSPA plugins */
1379 Session::set_block_size (nframes_t nframes)
1381 /* the AudioEngine guarantees
1382 that it will not be called while we are also in
1383 ::process(). It is therefore fine to do things that block
1388 vector<Sample*>::iterator i;
1391 current_block_size = nframes;
1393 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1397 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1401 _passthru_buffers.clear ();
1402 _silent_buffers.clear ();
1404 ensure_passthru_buffers (np);
1406 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1410 #ifdef NO_POSIX_MEMALIGN
1411 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1413 posix_memalign((void **)&buf,16,current_block_size * 4);
1417 memset (*i, 0, sizeof (Sample) * current_block_size);
1421 if (_gain_automation_buffer) {
1422 delete [] _gain_automation_buffer;
1424 _gain_automation_buffer = new gain_t[nframes];
1426 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1428 boost::shared_ptr<RouteList> r = routes.reader ();
1430 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1431 (*i)->set_block_size (nframes);
1434 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1435 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1436 (*i)->set_block_size (nframes);
1439 set_worst_io_latencies ();
1444 Session::set_default_fade (float steepness, float fade_msecs)
1447 nframes_t fade_frames;
1449 /* Don't allow fade of less 1 frame */
1451 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1458 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1462 default_fade_msecs = fade_msecs;
1463 default_fade_steepness = steepness;
1466 // jlc, WTF is this!
1467 Glib::RWLock::ReaderLock lm (route_lock);
1468 AudioRegion::set_default_fade (steepness, fade_frames);
1473 /* XXX have to do this at some point */
1474 /* foreach region using default fade, reset, then
1475 refill_all_diskstream_buffers ();
1480 struct RouteSorter {
1481 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1482 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1484 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1487 if (r1->fed_by.empty()) {
1488 if (r2->fed_by.empty()) {
1489 /* no ardour-based connections inbound to either route. just use signal order */
1490 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1492 /* r2 has connections, r1 does not; run r1 early */
1496 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1503 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1505 shared_ptr<Route> r2;
1507 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1508 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1512 /* make a copy of the existing list of routes that feed r1 */
1514 set<shared_ptr<Route> > existing = r1->fed_by;
1516 /* for each route that feeds r1, recurse, marking it as feeding
1520 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1523 /* r2 is a route that feeds r1 which somehow feeds base. mark
1524 base as being fed by r2
1527 rbase->fed_by.insert (r2);
1531 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1535 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1539 /* now recurse, so that we can mark base as being fed by
1540 all routes that feed r2
1543 trace_terminal (r2, rbase);
1550 Session::resort_routes ()
1552 /* don't do anything here with signals emitted
1553 by Routes while we are being destroyed.
1556 if (_state_of_the_state & Deletion) {
1563 RCUWriter<RouteList> writer (routes);
1564 shared_ptr<RouteList> r = writer.get_copy ();
1565 resort_routes_using (r);
1566 /* writer goes out of scope and forces update */
1571 Session::resort_routes_using (shared_ptr<RouteList> r)
1573 RouteList::iterator i, j;
1575 for (i = r->begin(); i != r->end(); ++i) {
1577 (*i)->fed_by.clear ();
1579 for (j = r->begin(); j != r->end(); ++j) {
1581 /* although routes can feed themselves, it will
1582 cause an endless recursive descent if we
1583 detect it. so don't bother checking for
1591 if ((*j)->feeds (*i)) {
1592 (*i)->fed_by.insert (*j);
1597 for (i = r->begin(); i != r->end(); ++i) {
1598 trace_terminal (*i, *i);
1604 /* don't leave dangling references to routes in Route::fed_by */
1606 for (i = r->begin(); i != r->end(); ++i) {
1607 (*i)->fed_by.clear ();
1611 cerr << "finished route resort\n";
1613 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1614 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1621 list<boost::shared_ptr<AudioTrack> >
1622 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1624 char track_name[32];
1625 uint32_t track_id = 0;
1627 uint32_t channels_used = 0;
1629 RouteList new_routes;
1630 list<boost::shared_ptr<AudioTrack> > ret;
1631 uint32_t control_id;
1633 /* count existing audio tracks */
1636 shared_ptr<RouteList> r = routes.reader ();
1638 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1639 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1640 if (!(*i)->hidden()) {
1642 channels_used += (*i)->n_inputs();
1648 vector<string> physinputs;
1649 vector<string> physoutputs;
1650 uint32_t nphysical_in;
1651 uint32_t nphysical_out;
1653 _engine.get_physical_outputs (physoutputs);
1654 _engine.get_physical_inputs (physinputs);
1655 control_id = ntracks() + nbusses() + 1;
1659 /* check for duplicate route names, since we might have pre-existing
1660 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1661 save, close,restart,add new route - first named route is now
1669 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1671 if (route_by_name (track_name) == 0) {
1675 } while (track_id < (UINT_MAX-1));
1677 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1678 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1683 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1684 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1690 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1692 if (track->ensure_io (input_channels, output_channels, false, this)) {
1693 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1694 input_channels, output_channels)
1699 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1703 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1704 port = physinputs[(channels_used+x)%nphysical_in];
1707 if (port.length() && track->connect_input (track->input (x), port, this)) {
1713 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1717 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1718 port = physoutputs[(channels_used+x)%nphysical_out];
1719 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1721 port = _master_out->input (x%_master_out->n_inputs())->name();
1725 if (port.length() && track->connect_output (track->output (x), port, this)) {
1730 channels_used += track->n_inputs ();
1733 vector<string> cports;
1734 uint32_t ni = _control_out->n_inputs();
1736 for (n = 0; n < ni; ++n) {
1737 cports.push_back (_control_out->input(n)->name());
1740 track->set_control_outs (cports);
1743 // assert (current_thread != RT_thread)
1745 track->audio_diskstream()->non_realtime_input_change();
1747 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1748 track->set_remote_control_id (control_id);
1751 new_routes.push_back (track);
1752 ret.push_back (track);
1755 catch (failed_constructor &err) {
1756 error << _("Session: could not create new audio track.") << endmsg;
1757 // XXX should we delete the tracks already created?
1765 if (!new_routes.empty()) {
1766 add_routes (new_routes, false);
1767 save_state (_current_snapshot_name);
1774 Session::set_remote_control_ids ()
1776 RemoteModel m = Config->get_remote_model();
1778 shared_ptr<RouteList> r = routes.reader ();
1780 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1781 if ( MixerOrdered == m) {
1782 long order = (*i)->order_key(N_("signal"));
1783 (*i)->set_remote_control_id( order+1 );
1784 } else if ( EditorOrdered == m) {
1785 long order = (*i)->order_key(N_("editor"));
1786 (*i)->set_remote_control_id( order+1 );
1787 } else if ( UserOrdered == m) {
1788 //do nothing ... only changes to remote id's are initiated by user
1795 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1798 uint32_t bus_id = 1;
1802 uint32_t control_id;
1804 /* count existing audio busses */
1807 shared_ptr<RouteList> r = routes.reader ();
1809 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1810 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1811 if (!(*i)->hidden()) {
1818 vector<string> physinputs;
1819 vector<string> physoutputs;
1821 _engine.get_physical_outputs (physoutputs);
1822 _engine.get_physical_inputs (physinputs);
1823 control_id = ntracks() + nbusses() + 1;
1830 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1832 if (route_by_name (bus_name) == 0) {
1836 } while (bus_id < (UINT_MAX-1));
1839 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1841 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1842 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1843 input_channels, output_channels)
1847 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1851 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1852 port = physinputs[((n+x)%n_physical_inputs)];
1855 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1860 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1864 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1865 port = physoutputs[((n+x)%n_physical_outputs)];
1866 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1868 port = _master_out->input (x%_master_out->n_inputs())->name();
1872 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1878 vector<string> cports;
1879 uint32_t ni = _control_out->n_inputs();
1881 for (uint32_t n = 0; n < ni; ++n) {
1882 cports.push_back (_control_out->input(n)->name());
1884 bus->set_control_outs (cports);
1887 bus->set_remote_control_id (control_id);
1890 ret.push_back (bus);
1894 catch (failed_constructor &err) {
1895 error << _("Session: could not create new audio route.") << endmsg;
1904 add_routes (ret, false);
1905 save_state (_current_snapshot_name);
1913 Session::add_routes (RouteList& new_routes, bool save)
1916 RCUWriter<RouteList> writer (routes);
1917 shared_ptr<RouteList> r = writer.get_copy ();
1918 r->insert (r->end(), new_routes.begin(), new_routes.end());
1919 resort_routes_using (r);
1922 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1924 boost::weak_ptr<Route> wpr (*x);
1926 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1927 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1928 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1929 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1931 if ((*x)->master()) {
1935 if ((*x)->control()) {
1936 _control_out = (*x);
1943 save_state (_current_snapshot_name);
1946 RouteAdded (new_routes); /* EMIT SIGNAL */
1950 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1952 /* need to do this in case we're rolling at the time, to prevent false underruns */
1953 dstream->do_refill_with_alloc();
1956 RCUWriter<DiskstreamList> writer (diskstreams);
1957 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1958 ds->push_back (dstream);
1961 dstream->set_block_size (current_block_size);
1963 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1964 /* this will connect to future changes, and check the current length */
1965 diskstream_playlist_changed (dstream);
1967 dstream->prepare ();
1971 Session::remove_route (shared_ptr<Route> route)
1974 RCUWriter<RouteList> writer (routes);
1975 shared_ptr<RouteList> rs = writer.get_copy ();
1979 /* deleting the master out seems like a dumb
1980 idea, but its more of a UI policy issue
1984 if (route == _master_out) {
1985 _master_out = shared_ptr<Route> ();
1988 if (route == _control_out) {
1989 _control_out = shared_ptr<Route> ();
1991 /* cancel control outs for all routes */
1993 vector<string> empty;
1995 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1996 (*r)->set_control_outs (empty);
2000 update_route_solo_state ();
2002 /* writer goes out of scope, forces route list update */
2005 // FIXME: audio specific
2007 boost::shared_ptr<AudioDiskstream> ds;
2009 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2010 ds = at->audio_diskstream();
2016 RCUWriter<DiskstreamList> dsl (diskstreams);
2017 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2022 find_current_end ();
2024 update_latency_compensation (false, false);
2027 // We need to disconnect the routes inputs and outputs
2028 route->disconnect_inputs(NULL);
2029 route->disconnect_outputs(NULL);
2031 /* get rid of it from the dead wood collection in the route list manager */
2033 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2037 /* try to cause everyone to drop their references */
2039 route->drop_references ();
2041 /* save the new state of the world */
2043 if (save_state (_current_snapshot_name)) {
2044 save_history (_current_snapshot_name);
2049 Session::route_mute_changed (void* src)
2055 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2057 if (solo_update_disabled) {
2063 boost::shared_ptr<Route> route = wpr.lock ();
2066 /* should not happen */
2067 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2071 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2073 shared_ptr<RouteList> r = routes.reader ();
2075 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2077 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2081 /* don't mess with busses */
2083 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2089 /* don't mess with tracks */
2091 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2096 if ((*i) != route &&
2097 ((*i)->mix_group () == 0 ||
2098 (*i)->mix_group () != route->mix_group () ||
2099 !route->mix_group ()->is_active())) {
2101 if ((*i)->soloed()) {
2103 /* if its already soloed, and solo latching is enabled,
2104 then leave it as it is.
2107 if (Config->get_solo_latched()) {
2114 solo_update_disabled = true;
2115 (*i)->set_solo (false, src);
2116 solo_update_disabled = false;
2120 bool something_soloed = false;
2121 bool same_thing_soloed = false;
2122 bool signal = false;
2124 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2125 if ((*i)->soloed()) {
2126 something_soloed = true;
2127 if (dynamic_cast<AudioTrack*>((*i).get())) {
2129 same_thing_soloed = true;
2134 same_thing_soloed = true;
2142 if (something_soloed != currently_soloing) {
2144 currently_soloing = something_soloed;
2147 modify_solo_mute (is_track, same_thing_soloed);
2150 SoloActive (currently_soloing); /* EMIT SIGNAL */
2153 SoloChanged (); /* EMIT SIGNAL */
2159 Session::update_route_solo_state ()
2162 bool is_track = false;
2163 bool signal = false;
2165 /* caller must hold RouteLock */
2167 /* this is where we actually implement solo by changing
2168 the solo mute setting of each track.
2171 shared_ptr<RouteList> r = routes.reader ();
2173 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2174 if ((*i)->soloed()) {
2176 if (dynamic_cast<AudioTrack*>((*i).get())) {
2183 if (mute != currently_soloing) {
2185 currently_soloing = mute;
2188 if (!is_track && !mute) {
2190 /* nothing is soloed */
2192 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2193 (*i)->set_solo_mute (false);
2203 modify_solo_mute (is_track, mute);
2206 SoloActive (currently_soloing);
2211 Session::modify_solo_mute (bool is_track, bool mute)
2213 shared_ptr<RouteList> r = routes.reader ();
2215 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2219 /* only alter track solo mute */
2221 if (dynamic_cast<AudioTrack*>((*i).get())) {
2222 if ((*i)->soloed()) {
2223 (*i)->set_solo_mute (!mute);
2225 (*i)->set_solo_mute (mute);
2231 /* only alter bus solo mute */
2233 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2235 if ((*i)->soloed()) {
2237 (*i)->set_solo_mute (false);
2241 /* don't mute master or control outs
2242 in response to another bus solo
2245 if ((*i) != _master_out &&
2246 (*i) != _control_out) {
2247 (*i)->set_solo_mute (mute);
2258 Session::catch_up_on_solo ()
2260 /* this is called after set_state() to catch the full solo
2261 state, which can't be correctly determined on a per-route
2262 basis, but needs the global overview that only the session
2265 update_route_solo_state();
2269 Session::route_by_name (string name)
2271 shared_ptr<RouteList> r = routes.reader ();
2273 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2274 if ((*i)->name() == name) {
2279 return shared_ptr<Route> ((Route*) 0);
2283 Session::route_by_id (PBD::ID id)
2285 shared_ptr<RouteList> r = routes.reader ();
2287 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2288 if ((*i)->id() == id) {
2293 return shared_ptr<Route> ((Route*) 0);
2297 Session::route_by_remote_id (uint32_t id)
2299 shared_ptr<RouteList> r = routes.reader ();
2301 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2302 if ((*i)->remote_control_id() == id) {
2307 return shared_ptr<Route> ((Route*) 0);
2311 Session::find_current_end ()
2313 if (_state_of_the_state & Loading) {
2317 nframes_t max = get_maximum_extent ();
2319 if (max > end_location->end()) {
2320 end_location->set_end (max);
2322 DurationChanged(); /* EMIT SIGNAL */
2327 Session::get_maximum_extent () const
2332 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2334 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2335 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2336 if ((me = pl->get_maximum_extent()) > max) {
2344 boost::shared_ptr<Diskstream>
2345 Session::diskstream_by_name (string name)
2347 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2349 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2350 if ((*i)->name() == name) {
2355 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2358 boost::shared_ptr<Diskstream>
2359 Session::diskstream_by_id (const PBD::ID& id)
2361 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2363 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2364 if ((*i)->id() == id) {
2369 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2372 /* AudioRegion management */
2375 Session::new_region_name (string old)
2377 string::size_type last_period;
2379 string::size_type len = old.length() + 64;
2382 if ((last_period = old.find_last_of ('.')) == string::npos) {
2384 /* no period present - add one explicitly */
2387 last_period = old.length() - 1;
2392 number = atoi (old.substr (last_period+1).c_str());
2396 while (number < (UINT_MAX-1)) {
2398 AudioRegionList::const_iterator i;
2403 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2406 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2407 if (i->second->name() == sbuf) {
2412 if (i == audio_regions.end()) {
2417 if (number != (UINT_MAX-1)) {
2421 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2426 Session::region_name (string& result, string base, bool newlevel) const
2433 Glib::Mutex::Lock lm (region_lock);
2435 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2443 /* XXX this is going to be slow. optimize me later */
2448 string::size_type pos;
2450 pos = base.find_last_of ('.');
2452 /* pos may be npos, but then we just use entire base */
2454 subbase = base.substr (0, pos);
2458 bool name_taken = true;
2461 Glib::Mutex::Lock lm (region_lock);
2463 for (int n = 1; n < 5000; ++n) {
2466 snprintf (buf, sizeof (buf), ".%d", n);
2471 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2472 if (i->second->name() == result) {
2485 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2493 Session::add_region (boost::shared_ptr<Region> region)
2495 boost::shared_ptr<AudioRegion> ar;
2496 boost::shared_ptr<AudioRegion> oar;
2500 Glib::Mutex::Lock lm (region_lock);
2502 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2504 AudioRegionList::iterator x;
2506 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2508 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2510 if (ar->region_list_equivalent (oar)) {
2515 if (x == audio_regions.end()) {
2517 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2519 entry.first = region->id();
2522 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2534 fatal << _("programming error: ")
2535 << X_("unknown region type passed to Session::add_region()")
2542 /* mark dirty because something has changed even if we didn't
2543 add the region to the region list.
2549 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2550 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2551 AudioRegionAdded (ar); /* EMIT SIGNAL */
2556 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2558 boost::shared_ptr<Region> region (weak_region.lock ());
2564 if (what_changed & Region::HiddenChanged) {
2565 /* relay hidden changes */
2566 RegionHiddenChange (region);
2571 Session::remove_region (boost::weak_ptr<Region> weak_region)
2573 AudioRegionList::iterator i;
2574 boost::shared_ptr<Region> region (weak_region.lock ());
2580 boost::shared_ptr<AudioRegion> ar;
2581 bool removed = false;
2584 Glib::Mutex::Lock lm (region_lock);
2586 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2587 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2588 audio_regions.erase (i);
2594 fatal << _("programming error: ")
2595 << X_("unknown region type passed to Session::remove_region()")
2601 /* mark dirty because something has changed even if we didn't
2602 remove the region from the region list.
2608 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2612 boost::shared_ptr<AudioRegion>
2613 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2615 AudioRegionList::iterator i;
2616 boost::shared_ptr<AudioRegion> region;
2617 Glib::Mutex::Lock lm (region_lock);
2619 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2623 if (region->whole_file()) {
2625 if (child->source_equivalent (region)) {
2631 return boost::shared_ptr<AudioRegion> ();
2635 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2637 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2638 (*i)->get_region_list_equivalent_regions (region, result);
2642 Session::destroy_region (boost::shared_ptr<Region> region)
2644 vector<boost::shared_ptr<Source> > srcs;
2647 boost::shared_ptr<AudioRegion> aregion;
2649 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2653 if (aregion->playlist()) {
2654 aregion->playlist()->destroy_region (region);
2657 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2658 srcs.push_back (aregion->source (n));
2662 region->drop_references ();
2664 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2666 if (!(*i)->used()) {
2667 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2670 (afs)->mark_for_remove ();
2673 (*i)->drop_references ();
2675 cerr << "source was not used by any playlist\n";
2683 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2685 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2686 destroy_region (*i);
2692 Session::remove_last_capture ()
2694 list<boost::shared_ptr<Region> > r;
2696 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2698 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2699 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2702 r.insert (r.end(), l.begin(), l.end());
2707 destroy_regions (r);
2712 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2718 /* Source Management */
2721 Session::add_source (boost::shared_ptr<Source> source)
2723 boost::shared_ptr<AudioFileSource> afs;
2725 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2727 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2728 pair<AudioSourceList::iterator,bool> result;
2730 entry.first = source->id();
2734 Glib::Mutex::Lock lm (audio_source_lock);
2735 result = audio_sources.insert (entry);
2738 if (result.second) {
2739 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2747 Session::remove_source (boost::weak_ptr<Source> src)
2749 AudioSourceList::iterator i;
2750 boost::shared_ptr<Source> source = src.lock();
2757 Glib::Mutex::Lock lm (audio_source_lock);
2759 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2760 audio_sources.erase (i);
2764 if (!_state_of_the_state & InCleanup) {
2766 /* save state so we don't end up with a session file
2767 referring to non-existent sources.
2770 save_state (_current_snapshot_name);
2774 boost::shared_ptr<Source>
2775 Session::source_by_id (const PBD::ID& id)
2777 Glib::Mutex::Lock lm (audio_source_lock);
2778 AudioSourceList::iterator i;
2779 boost::shared_ptr<Source> source;
2781 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2785 /* XXX search MIDI or other searches here */
2791 Session::peak_path_from_audio_path (string audio_path) const
2796 res += PBD::basename_nosuffix (audio_path);
2803 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2806 string old_basename = PBD::basename_nosuffix (oldname);
2807 string new_legalized = legalize_for_path (newname);
2809 /* note: we know (or assume) the old path is already valid */
2813 /* destructive file sources have a name of the form:
2815 /path/to/Tnnnn-NAME(%[LR])?.wav
2817 the task here is to replace NAME with the new name.
2820 /* find last slash */
2824 string::size_type slash;
2825 string::size_type dash;
2827 if ((slash = path.find_last_of ('/')) == string::npos) {
2831 dir = path.substr (0, slash+1);
2833 /* '-' is not a legal character for the NAME part of the path */
2835 if ((dash = path.find_last_of ('-')) == string::npos) {
2839 prefix = path.substr (slash+1, dash-(slash+1));
2844 path += new_legalized;
2845 path += ".wav"; /* XXX gag me with a spoon */
2849 /* non-destructive file sources have a name of the form:
2851 /path/to/NAME-nnnnn(%[LR])?.wav
2853 the task here is to replace NAME with the new name.
2858 string::size_type slash;
2859 string::size_type dash;
2860 string::size_type postfix;
2862 /* find last slash */
2864 if ((slash = path.find_last_of ('/')) == string::npos) {
2868 dir = path.substr (0, slash+1);
2870 /* '-' is not a legal character for the NAME part of the path */
2872 if ((dash = path.find_last_of ('-')) == string::npos) {
2876 suffix = path.substr (dash+1);
2878 // Suffix is now everything after the dash. Now we need to eliminate
2879 // the nnnnn part, which is done by either finding a '%' or a '.'
2881 postfix = suffix.find_last_of ("%");
2882 if (postfix == string::npos) {
2883 postfix = suffix.find_last_of ('.');
2886 if (postfix != string::npos) {
2887 suffix = suffix.substr (postfix);
2889 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2893 const uint32_t limit = 10000;
2894 char buf[PATH_MAX+1];
2896 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2898 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2900 if (access (buf, F_OK) != 0) {
2908 error << "FATAL ERROR! Could not find a " << endl;
2917 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2921 char buf[PATH_MAX+1];
2922 const uint32_t limit = 10000;
2926 legalized = legalize_for_path (name);
2928 /* find a "version" of the file name that doesn't exist in
2929 any of the possible directories.
2932 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2934 vector<space_and_path>::iterator i;
2935 uint32_t existing = 0;
2937 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2941 spath += sound_dir (false);
2945 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2946 } else if (nchan == 2) {
2948 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2950 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2952 } else if (nchan < 26) {
2953 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2955 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2964 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2965 } else if (nchan == 2) {
2967 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2969 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2971 } else if (nchan < 26) {
2972 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2974 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2978 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2984 if (existing == 0) {
2989 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2991 throw failed_constructor();
2995 /* we now have a unique name for the file, but figure out where to
3001 spath = discover_best_sound_dir ();
3004 string::size_type pos = foo.find_last_of ('/');
3006 if (pos == string::npos) {
3009 spath += foo.substr (pos + 1);
3015 boost::shared_ptr<AudioFileSource>
3016 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3018 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3019 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3022 /* Playlist management */
3024 boost::shared_ptr<Playlist>
3025 Session::playlist_by_name (string name)
3027 Glib::Mutex::Lock lm (playlist_lock);
3028 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3029 if ((*i)->name() == name) {
3033 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3034 if ((*i)->name() == name) {
3039 return boost::shared_ptr<Playlist>();
3043 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3045 if (playlist->hidden()) {
3050 Glib::Mutex::Lock lm (playlist_lock);
3051 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3052 playlists.insert (playlists.begin(), playlist);
3053 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3054 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3060 PlaylistAdded (playlist); /* EMIT SIGNAL */
3064 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3067 Glib::Mutex::Lock lm (playlist_lock);
3068 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3071 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3078 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3080 boost::shared_ptr<Playlist> pl(wpl.lock());
3086 PlaylistList::iterator x;
3089 /* its not supposed to be visible */
3094 Glib::Mutex::Lock lm (playlist_lock);
3098 unused_playlists.insert (pl);
3100 if ((x = playlists.find (pl)) != playlists.end()) {
3101 playlists.erase (x);
3107 playlists.insert (pl);
3109 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3110 unused_playlists.erase (x);
3117 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3119 if (_state_of_the_state & Deletion) {
3123 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3130 Glib::Mutex::Lock lm (playlist_lock);
3132 PlaylistList::iterator i;
3134 i = find (playlists.begin(), playlists.end(), playlist);
3135 if (i != playlists.end()) {
3136 playlists.erase (i);
3139 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3140 if (i != unused_playlists.end()) {
3141 unused_playlists.erase (i);
3148 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3152 Session::set_audition (boost::shared_ptr<Region> r)
3154 pending_audition_region = r;
3155 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3156 schedule_butler_transport_work ();
3160 Session::audition_playlist ()
3162 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3163 ev->region.reset ();
3168 Session::non_realtime_set_audition ()
3170 if (!pending_audition_region) {
3171 auditioner->audition_current_playlist ();
3173 auditioner->audition_region (pending_audition_region);
3174 pending_audition_region.reset ();
3176 AuditionActive (true); /* EMIT SIGNAL */
3180 Session::audition_region (boost::shared_ptr<Region> r)
3182 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3188 Session::cancel_audition ()
3190 if (auditioner->active()) {
3191 auditioner->cancel_audition ();
3192 AuditionActive (false); /* EMIT SIGNAL */
3197 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3199 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3203 Session::remove_empty_sounds ()
3205 PathScanner scanner;
3207 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3209 Glib::Mutex::Lock lm (audio_source_lock);
3211 regex_t compiled_tape_track_pattern;
3214 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3218 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3220 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3224 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3226 /* never remove files that appear to be a tape track */
3228 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3233 if (AudioFileSource::is_empty (*this, *(*i))) {
3235 unlink ((*i)->c_str());
3237 string peak_path = peak_path_from_audio_path (**i);
3238 unlink (peak_path.c_str());
3244 delete possible_audiofiles;
3248 Session::is_auditioning () const
3250 /* can be called before we have an auditioner object */
3252 return auditioner->active();
3259 Session::set_all_solo (bool yn)
3261 shared_ptr<RouteList> r = routes.reader ();
3263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3264 if (!(*i)->hidden()) {
3265 (*i)->set_solo (yn, this);
3273 Session::set_all_mute (bool yn)
3275 shared_ptr<RouteList> r = routes.reader ();
3277 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3278 if (!(*i)->hidden()) {
3279 (*i)->set_mute (yn, this);
3287 Session::n_diskstreams () const
3291 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3293 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3294 if (!(*i)->hidden()) {
3302 Session::graph_reordered ()
3304 /* don't do this stuff if we are setting up connections
3305 from a set_state() call.
3308 if (_state_of_the_state & InitialConnecting) {
3312 /* every track/bus asked for this to be handled but it was deferred because
3313 we were connecting. do it now.
3316 request_input_change_handling ();
3320 /* force all diskstreams to update their capture offset values to
3321 reflect any changes in latencies within the graph.
3324 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3327 (*i)->set_capture_offset ();
3332 Session::record_disenable_all ()
3334 record_enable_change_all (false);
3338 Session::record_enable_all ()
3340 record_enable_change_all (true);
3344 Session::record_enable_change_all (bool yn)
3346 shared_ptr<RouteList> r = routes.reader ();
3348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3351 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3352 at->set_record_enable (yn, this);
3356 /* since we don't keep rec-enable state, don't mark session dirty */
3360 Session::add_redirect (Redirect* redirect)
3364 PortInsert* port_insert;
3365 PluginInsert* plugin_insert;
3367 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3368 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3369 _port_inserts.insert (_port_inserts.begin(), port_insert);
3370 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3371 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3373 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3376 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3377 _sends.insert (_sends.begin(), send);
3379 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3383 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3389 Session::remove_redirect (Redirect* redirect)
3393 PortInsert* port_insert;
3394 PluginInsert* plugin_insert;
3396 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3397 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3398 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3399 if (x != _port_inserts.end()) {
3400 insert_bitset[port_insert->bit_slot()] = false;
3401 _port_inserts.erase (x);
3403 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3404 _plugin_inserts.remove (plugin_insert);
3406 fatal << string_compose (_("programming error: %1"),
3407 X_("unknown type of Insert deleted!"))
3411 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3412 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3413 if (x != _sends.end()) {
3414 send_bitset[send->bit_slot()] = false;
3418 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3426 Session::available_capture_duration ()
3428 float sample_bytes_on_disk = 4.0; // keep gcc happy
3430 switch (Config->get_native_file_data_format()) {
3432 sample_bytes_on_disk = 4.0;
3436 sample_bytes_on_disk = 3.0;
3440 /* impossible, but keep some gcc versions happy */
3441 fatal << string_compose (_("programming error: %1"),
3442 X_("illegal native file data format"))
3447 double scale = 4096.0 / sample_bytes_on_disk;
3449 if (_total_free_4k_blocks * scale > (double) max_frames) {
3453 return (nframes_t) floor (_total_free_4k_blocks * scale);
3457 Session::add_connection (ARDOUR::Connection* connection)
3460 Glib::Mutex::Lock guard (connection_lock);
3461 _connections.push_back (connection);
3464 ConnectionAdded (connection); /* EMIT SIGNAL */
3470 Session::remove_connection (ARDOUR::Connection* connection)
3472 bool removed = false;
3475 Glib::Mutex::Lock guard (connection_lock);
3476 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3478 if (i != _connections.end()) {
3479 _connections.erase (i);
3485 ConnectionRemoved (connection); /* EMIT SIGNAL */
3491 ARDOUR::Connection *
3492 Session::connection_by_name (string name) const
3494 Glib::Mutex::Lock lm (connection_lock);
3496 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3497 if ((*i)->name() == name) {
3506 Session::tempo_map_changed (Change ignored)
3513 Session::ensure_passthru_buffers (uint32_t howmany)
3515 while (howmany > _passthru_buffers.size()) {
3517 #ifdef NO_POSIX_MEMALIGN
3518 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3520 posix_memalign((void **)&p,16,current_block_size * 4);
3522 _passthru_buffers.push_back (p);
3526 #ifdef NO_POSIX_MEMALIGN
3527 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3529 posix_memalign((void **)&p,16,current_block_size * 4);
3531 memset (p, 0, sizeof (Sample) * current_block_size);
3532 _silent_buffers.push_back (p);
3536 #ifdef NO_POSIX_MEMALIGN
3537 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3539 posix_memalign((void **)&p,16,current_block_size * 4);
3541 memset (p, 0, sizeof (Sample) * current_block_size);
3542 _send_buffers.push_back (p);
3545 allocate_pan_automation_buffers (current_block_size, howmany, false);
3549 Session::next_insert_id ()
3551 /* this doesn't really loop forever. just think about it */
3554 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3555 if (!insert_bitset[n]) {
3556 insert_bitset[n] = true;
3557 cerr << "Returning " << n << " as insert ID\n";
3563 /* none available, so resize and try again */
3565 insert_bitset.resize (insert_bitset.size() + 16, false);
3570 Session::next_send_id ()
3572 /* this doesn't really loop forever. just think about it */
3575 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3576 if (!send_bitset[n]) {
3577 send_bitset[n] = true;
3578 cerr << "Returning " << n << " as send ID\n";
3584 /* none available, so resize and try again */
3586 send_bitset.resize (send_bitset.size() + 16, false);
3591 Session::mark_send_id (uint32_t id)
3593 if (id >= send_bitset.size()) {
3594 send_bitset.resize (id+16, false);
3596 if (send_bitset[id]) {
3597 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3599 send_bitset[id] = true;
3603 Session::mark_insert_id (uint32_t id)
3605 if (id >= insert_bitset.size()) {
3606 insert_bitset.resize (id+16, false);
3608 if (insert_bitset[id]) {
3609 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3611 insert_bitset[id] = true;
3614 /* Named Selection management */
3617 Session::named_selection_by_name (string name)
3619 Glib::Mutex::Lock lm (named_selection_lock);
3620 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3621 if ((*i)->name == name) {
3629 Session::add_named_selection (NamedSelection* named_selection)
3632 Glib::Mutex::Lock lm (named_selection_lock);
3633 named_selections.insert (named_selections.begin(), named_selection);
3636 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3642 NamedSelectionAdded (); /* EMIT SIGNAL */
3646 Session::remove_named_selection (NamedSelection* named_selection)
3648 bool removed = false;
3651 Glib::Mutex::Lock lm (named_selection_lock);
3653 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3655 if (i != named_selections.end()) {
3657 named_selections.erase (i);
3664 NamedSelectionRemoved (); /* EMIT SIGNAL */
3669 Session::reset_native_file_format ()
3671 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3673 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3674 (*i)->reset_write_sources (false);
3679 Session::route_name_unique (string n) const
3681 shared_ptr<RouteList> r = routes.reader ();
3683 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3684 if ((*i)->name() == n) {
3693 Session::n_playlists () const
3695 Glib::Mutex::Lock lm (playlist_lock);
3696 return playlists.size();
3700 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3702 if (!force && howmany <= _npan_buffers) {
3706 if (_pan_automation_buffer) {
3708 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3709 delete [] _pan_automation_buffer[i];
3712 delete [] _pan_automation_buffer;
3715 _pan_automation_buffer = new pan_t*[howmany];
3717 for (uint32_t i = 0; i < howmany; ++i) {
3718 _pan_automation_buffer[i] = new pan_t[nframes];
3721 _npan_buffers = howmany;
3725 Session::freeze (InterThreadInfo& itt)
3727 shared_ptr<RouteList> r = routes.reader ();
3729 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3733 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3734 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3745 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3746 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3749 boost::shared_ptr<Playlist> playlist;
3750 boost::shared_ptr<AudioFileSource> fsource;
3752 char buf[PATH_MAX+1];
3756 nframes_t this_chunk;
3758 vector<Sample*> buffers;
3760 // any bigger than this seems to cause stack overflows in called functions
3761 const nframes_t chunk_size = (128 * 1024)/4;
3763 g_atomic_int_set (&processing_prohibited, 1);
3765 /* call tree *MUST* hold route_lock */
3767 if ((playlist = track.diskstream()->playlist()) == 0) {
3771 /* external redirects will be a problem */
3773 if (track.has_external_redirects()) {
3777 nchans = track.audio_diskstream()->n_channels();
3779 dir = discover_best_sound_dir ();
3781 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3783 for (x = 0; x < 99999; ++x) {
3784 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3785 if (access (buf, F_OK) != 0) {
3791 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3796 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3799 catch (failed_constructor& err) {
3800 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3804 srcs.push_back (fsource);
3807 /* XXX need to flush all redirects */
3812 /* create a set of reasonably-sized buffers */
3814 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3816 #ifdef NO_POSIX_MEMALIGN
3817 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3819 posix_memalign((void **)&b,16,chunk_size * 4);
3821 buffers.push_back (b);
3824 while (to_do && !itt.cancel) {
3826 this_chunk = min (to_do, chunk_size);
3828 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3833 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3834 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3837 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3843 start += this_chunk;
3844 to_do -= this_chunk;
3846 itt.progress = (float) (1.0 - ((double) to_do / len));
3855 xnow = localtime (&now);
3857 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3858 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3861 afs->update_header (position, *xnow, now);
3865 /* build peakfile for new source */
3867 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3868 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3870 afs->build_peaks ();
3874 /* construct a region to represent the bounced material */
3876 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3877 region_name_from_path (srcs.front()->name(), true));
3884 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3885 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3888 afs->mark_for_remove ();
3891 (*src)->drop_references ();
3895 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3899 g_atomic_int_set (&processing_prohibited, 0);
3907 Session::get_silent_buffers (uint32_t howmany)
3909 for (uint32_t i = 0; i < howmany; ++i) {
3910 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3912 return _silent_buffers;
3916 Session::ntracks () const
3919 shared_ptr<RouteList> r = routes.reader ();
3921 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3922 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3931 Session::nbusses () const
3934 shared_ptr<RouteList> r = routes.reader ();
3936 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3937 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3946 Session::add_automation_list(AutomationList *al)
3948 automation_lists[al->id()] = al;
3952 Session::compute_initial_length ()
3954 return _engine.frame_rate() * 60 * 5;