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.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/auditioner.h>
53 #include <ardour/recent_sessions.h>
54 #include <ardour/redirect.h>
55 #include <ardour/send.h>
56 #include <ardour/insert.h>
57 #include <ardour/connection.h>
58 #include <ardour/slave.h>
59 #include <ardour/tempo.h>
60 #include <ardour/audio_track.h>
61 #include <ardour/cycle_timer.h>
62 #include <ardour/named_selection.h>
63 #include <ardour/crossfade.h>
64 #include <ardour/playlist.h>
65 #include <ardour/click.h>
66 #include <ardour/data_type.h>
67 #include <ardour/source_factory.h>
68 #include <ardour/region_factory.h>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
81 const char* Session::_template_suffix = X_(".template");
82 const char* Session::_statefile_suffix = X_(".ardour");
83 const char* Session::_pending_suffix = X_(".pending");
84 const char* Session::old_sound_dir_name = X_("sounds");
85 const char* Session::sound_dir_name = X_("audiofiles");
86 const char* Session::peak_dir_name = X_("peaks");
87 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 const char* Session::interchange_dir_name = X_("interchange");
89 const char* Session::export_dir_name = X_("export");
91 Session::compute_peak_t Session::compute_peak = 0;
92 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
93 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
94 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
96 sigc::signal<int> Session::AskAboutPendingState;
97 sigc::signal<void> Session::SendFeedback;
99 sigc::signal<void> Session::SMPTEOffsetChanged;
100 sigc::signal<void> Session::StartTimeChanged;
101 sigc::signal<void> Session::EndTimeChanged;
104 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
107 char buf[PATH_MAX+1];
111 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
112 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
118 /* check to see if it exists, and what it is */
120 if (stat (str.c_str(), &statbuf)) {
121 if (errno == ENOENT) {
124 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
132 /* it exists, so it must either be the name
133 of the directory, or the name of the statefile
137 if (S_ISDIR (statbuf.st_mode)) {
139 string::size_type slash = str.find_last_of ('/');
141 if (slash == string::npos) {
143 /* a subdirectory of cwd, so statefile should be ... */
149 tmp += _statefile_suffix;
153 if (stat (tmp.c_str(), &statbuf)) {
154 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
164 /* some directory someplace in the filesystem.
165 the snapshot name is the directory name
170 snapshot = str.substr (slash+1);
174 } else if (S_ISREG (statbuf.st_mode)) {
176 string::size_type slash = str.find_last_of ('/');
177 string::size_type suffix;
179 /* remove the suffix */
181 if (slash != string::npos) {
182 snapshot = str.substr (slash+1);
187 suffix = snapshot.find (_statefile_suffix);
189 if (suffix == string::npos) {
190 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
196 snapshot = snapshot.substr (0, suffix);
198 if (slash == string::npos) {
200 /* we must be in the directory where the
201 statefile lives. get it using cwd().
204 char cwd[PATH_MAX+1];
206 if (getcwd (cwd, sizeof (cwd)) == 0) {
207 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
216 /* full path to the statefile */
218 path = str.substr (0, slash);
223 /* what type of file is it? */
224 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
230 /* its the name of a new directory. get the name
234 string::size_type slash = str.find_last_of ('/');
236 if (slash == string::npos) {
238 /* no slash, just use the name, but clean it up */
240 path = legalize_for_path (str);
246 snapshot = str.substr (slash+1);
253 Session::Session (AudioEngine &eng,
255 string snapshot_name,
256 string* mix_template)
259 _mmc_port (default_mmc_port),
260 _mtc_port (default_mtc_port),
261 _midi_port (default_midi_port),
262 pending_events (2048),
263 midi_requests (128), // the size of this should match the midi request pool size
264 diskstreams (new DiskstreamList),
265 routes (new RouteList),
266 auditioner ((Auditioner*) 0),
272 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
274 n_physical_outputs = _engine.n_physical_outputs();
275 n_physical_inputs = _engine.n_physical_inputs();
277 first_stage_init (fullpath, snapshot_name);
279 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
281 if (create (new_session, mix_template, compute_initial_length())) {
282 cerr << "create failed\n";
284 throw failed_constructor ();
288 if (second_stage_init (new_session)) {
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)) {
350 throw failed_constructor ();
355 /* set up Master Out and Control Out if necessary */
360 if (control_out_channels) {
361 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
362 r->set_remote_control_id (control_id++);
367 if (master_out_channels) {
368 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
369 r->set_remote_control_id (control_id);
373 /* prohibit auto-connect to master, because there isn't one */
374 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
383 Config->set_input_auto_connect (input_ac);
384 Config->set_output_auto_connect (output_ac);
386 if (second_stage_init (new_session)) {
388 throw failed_constructor ();
391 store_recent_sessions(_name, _path);
393 bool was_dirty = dirty ();
395 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
397 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
400 DirtyChanged (); /* EMIT SIGNAL */
412 /* if we got to here, leaving pending capture state around
416 remove_pending_capture_state ();
418 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
419 _engine.remove_session ();
421 GoingAway (); /* EMIT SIGNAL */
427 /* clear history so that no references to objects are held any more */
431 /* clear state tree so that no references to objects are held any more */
437 terminate_butler_thread ();
438 terminate_midi_thread ();
440 if (click_data && click_data != default_click) {
441 delete [] click_data;
444 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
445 delete [] click_emphasis_data;
450 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
454 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
458 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
462 AudioDiskstream::free_working_buffers();
464 /* this should cause deletion of the auditioner */
466 // auditioner.reset ();
468 #undef TRACK_DESTRUCTION
469 #ifdef TRACK_DESTRUCTION
470 cerr << "delete named selections\n";
471 #endif /* TRACK_DESTRUCTION */
472 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
473 NamedSelectionList::iterator tmp;
482 #ifdef TRACK_DESTRUCTION
483 cerr << "delete playlists\n";
484 #endif /* TRACK_DESTRUCTION */
485 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
486 PlaylistList::iterator tmp;
491 (*i)->drop_references ();
496 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
497 PlaylistList::iterator tmp;
502 (*i)->drop_references ();
508 unused_playlists.clear ();
510 #ifdef TRACK_DESTRUCTION
511 cerr << "delete audio regions\n";
512 #endif /* TRACK_DESTRUCTION */
514 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
515 AudioRegionList::iterator tmp;
520 i->second->drop_references ();
525 audio_regions.clear ();
527 #ifdef TRACK_DESTRUCTION
528 cerr << "delete routes\n";
529 #endif /* TRACK_DESTRUCTION */
531 RCUWriter<RouteList> writer (routes);
532 boost::shared_ptr<RouteList> r = writer.get_copy ();
533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
534 (*i)->drop_references ();
537 /* writer goes out of scope and updates master */
542 #ifdef TRACK_DESTRUCTION
543 cerr << "delete diskstreams\n";
544 #endif /* TRACK_DESTRUCTION */
546 RCUWriter<DiskstreamList> dwriter (diskstreams);
547 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
548 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
549 (*i)->drop_references ();
553 diskstreams.flush ();
555 #ifdef TRACK_DESTRUCTION
556 cerr << "delete audio sources\n";
557 #endif /* TRACK_DESTRUCTION */
558 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
559 AudioSourceList::iterator tmp;
564 i->second->drop_references ();
569 audio_sources.clear ();
571 #ifdef TRACK_DESTRUCTION
572 cerr << "delete mix groups\n";
573 #endif /* TRACK_DESTRUCTION */
574 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
575 list<RouteGroup*>::iterator tmp;
585 #ifdef TRACK_DESTRUCTION
586 cerr << "delete edit groups\n";
587 #endif /* TRACK_DESTRUCTION */
588 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
589 list<RouteGroup*>::iterator tmp;
599 #ifdef TRACK_DESTRUCTION
600 cerr << "delete connections\n";
601 #endif /* TRACK_DESTRUCTION */
602 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
603 ConnectionList::iterator tmp;
613 if (butler_mixdown_buffer) {
614 delete [] butler_mixdown_buffer;
617 if (butler_gain_buffer) {
618 delete [] butler_gain_buffer;
621 Crossfade::set_buffer_size (0);
629 Session::set_worst_io_latencies ()
631 _worst_output_latency = 0;
632 _worst_input_latency = 0;
634 if (!_engine.connected()) {
638 boost::shared_ptr<RouteList> r = routes.reader ();
640 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
641 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
642 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
647 Session::when_engine_running ()
649 string first_physical_output;
651 /* we don't want to run execute this again */
653 set_block_size (_engine.frames_per_cycle());
654 set_frame_rate (_engine.frame_rate());
656 Config->map_parameters (mem_fun (*this, &Session::config_changed));
658 /* every time we reconnect, recompute worst case output latencies */
660 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
662 if (synced_to_jack()) {
663 _engine.transport_stop ();
666 if (Config->get_jack_time_master()) {
667 _engine.transport_locate (_transport_frame);
675 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
677 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
679 /* existing state for Click */
681 if (_click_io->set_state (*child->children().front()) == 0) {
683 _clicking = Config->get_clicking ();
687 error << _("could not setup Click I/O") << endmsg;
693 /* default state for Click */
695 first_physical_output = _engine.get_nth_physical_output (0);
697 if (first_physical_output.length()) {
698 if (_click_io->add_output_port (first_physical_output, this)) {
699 // relax, even though its an error
701 _clicking = Config->get_clicking ();
707 catch (failed_constructor& err) {
708 error << _("cannot setup Click I/O") << endmsg;
711 set_worst_io_latencies ();
714 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
717 /* Create a set of Connection objects that map
718 to the physical outputs currently available
723 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
725 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
727 Connection* c = new OutputConnection (buf, true);
730 c->add_connection (0, _engine.get_nth_physical_output (np));
735 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
737 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
739 Connection* c = new InputConnection (buf, true);
742 c->add_connection (0, _engine.get_nth_physical_input (np));
749 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
751 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
753 Connection* c = new OutputConnection (buf, true);
757 c->add_connection (0, _engine.get_nth_physical_output (np));
758 c->add_connection (1, _engine.get_nth_physical_output (np+1));
763 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
765 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
767 Connection* c = new InputConnection (buf, true);
771 c->add_connection (0, _engine.get_nth_physical_input (np));
772 c->add_connection (1, _engine.get_nth_physical_input (np+1));
781 /* create master/control ports */
786 /* force the master to ignore any later call to this */
788 if (_master_out->pending_state_node) {
789 _master_out->ports_became_legal();
792 /* no panner resets till we are through */
794 _master_out->defer_pan_reset ();
796 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
797 if (_master_out->add_input_port ("", this)) {
798 error << _("cannot setup master inputs")
804 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
805 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
806 error << _("cannot setup master outputs")
813 _master_out->allow_pan_reset ();
817 Connection* c = new OutputConnection (_("Master Out"), true);
819 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
821 c->add_connection ((int) n, _master_out->input(n)->name());
828 /* catch up on send+insert cnts */
832 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
835 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
836 if (id > insert_cnt) {
844 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
847 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
855 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
857 /* hook us up to the engine */
859 _engine.set_session (this);
864 osc->set_session (*this);
867 _state_of_the_state = Clean;
869 DirtyChanged (); /* EMIT SIGNAL */
873 Session::hookup_io ()
875 /* stop graph reordering notifications from
876 causing resorts, etc.
879 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
881 if (auditioner == 0) {
883 /* we delay creating the auditioner till now because
884 it makes its own connections to ports.
885 the engine has to be running for this to work.
889 auditioner.reset (new Auditioner (*this));
892 catch (failed_constructor& err) {
893 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
897 /* Tell all IO objects to create their ports */
904 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
905 if (_control_out->add_input_port ("", this)) {
906 error << _("cannot setup control inputs")
912 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
913 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
914 error << _("cannot set up master outputs")
922 /* Tell all IO objects to connect themselves together */
924 IO::enable_connecting ();
926 /* Now reset all panners */
928 IO::reset_panners ();
930 /* Anyone who cares about input state, wake up and do something */
932 IOConnectionsComplete (); /* EMIT SIGNAL */
934 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
936 /* now handle the whole enchilada as if it was one
942 /* update mixer solo state */
948 Session::playlist_length_changed ()
950 /* we can't just increase end_location->end() if pl->get_maximum_extent()
951 if larger. if the playlist used to be the longest playlist,
952 and its now shorter, we have to decrease end_location->end(). hence,
953 we have to iterate over all diskstreams and check the
954 playlists currently in use.
960 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
962 boost::shared_ptr<Playlist> playlist;
964 if ((playlist = dstream->playlist()) != 0) {
965 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
968 /* see comment in playlist_length_changed () */
973 Session::record_enabling_legal () const
975 /* this used to be in here, but survey says.... we don't need to restrict it */
976 // if (record_status() == Recording) {
980 if (Config->get_all_safe()) {
987 Session::reset_input_monitor_state ()
989 if (transport_rolling()) {
991 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
993 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
994 if ((*i)->record_enabled ()) {
995 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
996 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1000 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1002 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1003 if ((*i)->record_enabled ()) {
1004 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1005 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1012 Session::auto_punch_start_changed (Location* location)
1014 replace_event (Event::PunchIn, location->start());
1016 if (get_record_enabled() && Config->get_punch_in()) {
1017 /* capture start has been changed, so save new pending state */
1018 save_state ("", true);
1023 Session::auto_punch_end_changed (Location* location)
1025 nframes_t when_to_stop = location->end();
1026 // when_to_stop += _worst_output_latency + _worst_input_latency;
1027 replace_event (Event::PunchOut, when_to_stop);
1031 Session::auto_punch_changed (Location* location)
1033 nframes_t when_to_stop = location->end();
1035 replace_event (Event::PunchIn, location->start());
1036 //when_to_stop += _worst_output_latency + _worst_input_latency;
1037 replace_event (Event::PunchOut, when_to_stop);
1041 Session::auto_loop_changed (Location* location)
1043 replace_event (Event::AutoLoop, location->end(), location->start());
1045 if (transport_rolling() && play_loop) {
1047 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1049 if (_transport_frame > location->end()) {
1050 // relocate to beginning of loop
1051 clear_events (Event::LocateRoll);
1053 request_locate (location->start(), true);
1056 else if (Config->get_seamless_loop() && !loop_changing) {
1058 // schedule a locate-roll to refill the diskstreams at the
1059 // previous loop end
1060 loop_changing = true;
1062 if (location->end() > last_loopend) {
1063 clear_events (Event::LocateRoll);
1064 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1071 last_loopend = location->end();
1076 Session::set_auto_punch_location (Location* location)
1080 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1081 auto_punch_start_changed_connection.disconnect();
1082 auto_punch_end_changed_connection.disconnect();
1083 auto_punch_changed_connection.disconnect();
1084 existing->set_auto_punch (false, this);
1085 remove_event (existing->start(), Event::PunchIn);
1086 clear_events (Event::PunchOut);
1087 auto_punch_location_changed (0);
1092 if (location == 0) {
1096 if (location->end() <= location->start()) {
1097 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1101 auto_punch_start_changed_connection.disconnect();
1102 auto_punch_end_changed_connection.disconnect();
1103 auto_punch_changed_connection.disconnect();
1105 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1106 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1107 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1109 location->set_auto_punch (true, this);
1110 auto_punch_location_changed (location);
1114 Session::set_auto_loop_location (Location* location)
1118 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1119 auto_loop_start_changed_connection.disconnect();
1120 auto_loop_end_changed_connection.disconnect();
1121 auto_loop_changed_connection.disconnect();
1122 existing->set_auto_loop (false, this);
1123 remove_event (existing->end(), Event::AutoLoop);
1124 auto_loop_location_changed (0);
1129 if (location == 0) {
1133 if (location->end() <= location->start()) {
1134 error << _("Session: you can't use a mark for auto loop") << endmsg;
1138 last_loopend = location->end();
1140 auto_loop_start_changed_connection.disconnect();
1141 auto_loop_end_changed_connection.disconnect();
1142 auto_loop_changed_connection.disconnect();
1144 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1145 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1146 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1148 location->set_auto_loop (true, this);
1149 auto_loop_location_changed (location);
1153 Session::locations_added (Location* ignored)
1159 Session::locations_changed ()
1161 _locations.apply (*this, &Session::handle_locations_changed);
1165 Session::handle_locations_changed (Locations::LocationList& locations)
1167 Locations::LocationList::iterator i;
1169 bool set_loop = false;
1170 bool set_punch = false;
1172 for (i = locations.begin(); i != locations.end(); ++i) {
1176 if (location->is_auto_punch()) {
1177 set_auto_punch_location (location);
1180 if (location->is_auto_loop()) {
1181 set_auto_loop_location (location);
1188 set_auto_loop_location (0);
1191 set_auto_punch_location (0);
1198 Session::enable_record ()
1200 /* XXX really atomic compare+swap here */
1201 if (g_atomic_int_get (&_record_status) != Recording) {
1202 g_atomic_int_set (&_record_status, Recording);
1203 _last_record_location = _transport_frame;
1204 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1206 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1207 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1208 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1209 if ((*i)->record_enabled ()) {
1210 (*i)->monitor_input (true);
1215 RecordStateChanged ();
1220 Session::disable_record (bool rt_context, bool force)
1224 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1226 if (!Config->get_latched_record_enable () || force) {
1227 g_atomic_int_set (&_record_status, Disabled);
1229 if (rs == Recording) {
1230 g_atomic_int_set (&_record_status, Enabled);
1234 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1236 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1237 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1239 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1240 if ((*i)->record_enabled ()) {
1241 (*i)->monitor_input (false);
1246 RecordStateChanged (); /* emit signal */
1249 remove_pending_capture_state ();
1255 Session::step_back_from_record ()
1257 g_atomic_int_set (&_record_status, Enabled);
1259 if (Config->get_monitoring_model() == HardwareMonitoring) {
1260 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1262 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1263 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1264 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1265 (*i)->monitor_input (false);
1272 Session::maybe_enable_record ()
1274 g_atomic_int_set (&_record_status, Enabled);
1276 /* this function is currently called from somewhere other than an RT thread.
1277 this save_state() call therefore doesn't impact anything.
1280 save_state ("", true);
1282 if (_transport_speed) {
1283 if (!Config->get_punch_in()) {
1287 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1288 RecordStateChanged (); /* EMIT SIGNAL */
1295 Session::audible_frame () const
1301 /* the first of these two possible settings for "offset"
1302 mean that the audible frame is stationary until
1303 audio emerges from the latency compensation
1306 the second means that the audible frame is stationary
1307 until audio would emerge from a physical port
1308 in the absence of any plugin latency compensation
1311 offset = _worst_output_latency;
1313 if (offset > current_block_size) {
1314 offset -= current_block_size;
1316 /* XXX is this correct? if we have no external
1317 physical connections and everything is internal
1318 then surely this is zero? still, how
1319 likely is that anyway?
1321 offset = current_block_size;
1324 if (synced_to_jack()) {
1325 tf = _engine.transport_frame();
1327 tf = _transport_frame;
1330 if (_transport_speed == 0) {
1340 if (!non_realtime_work_pending()) {
1344 /* take latency into account */
1353 Session::set_frame_rate (nframes_t frames_per_second)
1355 /** \fn void Session::set_frame_size(nframes_t)
1356 the AudioEngine object that calls this guarantees
1357 that it will not be called while we are also in
1358 ::process(). Its fine to do things that block
1362 _base_frame_rate = frames_per_second;
1366 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1368 // XXX we need some equivalent to this, somehow
1369 // SndFileSource::setup_standard_crossfades (frames_per_second);
1373 /* XXX need to reset/reinstantiate all LADSPA plugins */
1377 Session::set_block_size (nframes_t nframes)
1379 /* the AudioEngine guarantees
1380 that it will not be called while we are also in
1381 ::process(). It is therefore fine to do things that block
1386 vector<Sample*>::iterator i;
1389 current_block_size = nframes;
1391 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1395 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1399 _passthru_buffers.clear ();
1400 _silent_buffers.clear ();
1402 ensure_passthru_buffers (np);
1404 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1408 #ifdef NO_POSIX_MEMALIGN
1409 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1411 posix_memalign((void **)&buf,16,current_block_size * 4);
1415 memset (*i, 0, sizeof (Sample) * current_block_size);
1419 if (_gain_automation_buffer) {
1420 delete [] _gain_automation_buffer;
1422 _gain_automation_buffer = new gain_t[nframes];
1424 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1426 boost::shared_ptr<RouteList> r = routes.reader ();
1428 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1429 (*i)->set_block_size (nframes);
1432 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1433 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1434 (*i)->set_block_size (nframes);
1437 set_worst_io_latencies ();
1442 Session::set_default_fade (float steepness, float fade_msecs)
1445 nframes_t fade_frames;
1447 /* Don't allow fade of less 1 frame */
1449 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1456 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1460 default_fade_msecs = fade_msecs;
1461 default_fade_steepness = steepness;
1464 // jlc, WTF is this!
1465 Glib::RWLock::ReaderLock lm (route_lock);
1466 AudioRegion::set_default_fade (steepness, fade_frames);
1471 /* XXX have to do this at some point */
1472 /* foreach region using default fade, reset, then
1473 refill_all_diskstream_buffers ();
1478 struct RouteSorter {
1479 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1480 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1482 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1485 if (r1->fed_by.empty()) {
1486 if (r2->fed_by.empty()) {
1487 /* no ardour-based connections inbound to either route. just use signal order */
1488 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1490 /* r2 has connections, r1 does not; run r1 early */
1494 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1501 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1503 shared_ptr<Route> r2;
1505 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1506 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1510 /* make a copy of the existing list of routes that feed r1 */
1512 set<shared_ptr<Route> > existing = r1->fed_by;
1514 /* for each route that feeds r1, recurse, marking it as feeding
1518 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1521 /* r2 is a route that feeds r1 which somehow feeds base. mark
1522 base as being fed by r2
1525 rbase->fed_by.insert (r2);
1529 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1533 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1537 /* now recurse, so that we can mark base as being fed by
1538 all routes that feed r2
1541 trace_terminal (r2, rbase);
1548 Session::resort_routes ()
1550 /* don't do anything here with signals emitted
1551 by Routes while we are being destroyed.
1554 if (_state_of_the_state & Deletion) {
1561 RCUWriter<RouteList> writer (routes);
1562 shared_ptr<RouteList> r = writer.get_copy ();
1563 resort_routes_using (r);
1564 /* writer goes out of scope and forces update */
1569 Session::resort_routes_using (shared_ptr<RouteList> r)
1571 RouteList::iterator i, j;
1573 for (i = r->begin(); i != r->end(); ++i) {
1575 (*i)->fed_by.clear ();
1577 for (j = r->begin(); j != r->end(); ++j) {
1579 /* although routes can feed themselves, it will
1580 cause an endless recursive descent if we
1581 detect it. so don't bother checking for
1589 if ((*j)->feeds (*i)) {
1590 (*i)->fed_by.insert (*j);
1595 for (i = r->begin(); i != r->end(); ++i) {
1596 trace_terminal (*i, *i);
1602 /* don't leave dangling references to routes in Route::fed_by */
1604 for (i = r->begin(); i != r->end(); ++i) {
1605 (*i)->fed_by.clear ();
1609 cerr << "finished route resort\n";
1611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1612 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1619 list<boost::shared_ptr<AudioTrack> >
1620 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1622 char track_name[32];
1623 uint32_t track_id = 0;
1625 uint32_t channels_used = 0;
1627 RouteList new_routes;
1628 list<boost::shared_ptr<AudioTrack> > ret;
1629 uint32_t control_id;
1631 /* count existing audio tracks */
1634 shared_ptr<RouteList> r = routes.reader ();
1636 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1637 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1638 if (!(*i)->hidden()) {
1640 channels_used += (*i)->n_inputs();
1646 vector<string> physinputs;
1647 vector<string> physoutputs;
1648 uint32_t nphysical_in;
1649 uint32_t nphysical_out;
1651 _engine.get_physical_outputs (physoutputs);
1652 _engine.get_physical_inputs (physinputs);
1653 control_id = ntracks() + nbusses() + 1;
1657 /* check for duplicate route names, since we might have pre-existing
1658 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1659 save, close,restart,add new route - first named route is now
1667 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1669 if (route_by_name (track_name) == 0) {
1673 } while (track_id < (UINT_MAX-1));
1675 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1676 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1681 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1682 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1688 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1690 if (track->ensure_io (input_channels, output_channels, false, this)) {
1691 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1692 input_channels, output_channels)
1697 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1701 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1702 port = physinputs[(channels_used+x)%nphysical_in];
1705 if (port.length() && track->connect_input (track->input (x), port, this)) {
1711 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1715 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1716 port = physoutputs[(channels_used+x)%nphysical_out];
1717 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1719 port = _master_out->input (x%_master_out->n_inputs())->name();
1723 if (port.length() && track->connect_output (track->output (x), port, this)) {
1728 channels_used += track->n_inputs ();
1731 vector<string> cports;
1732 uint32_t ni = _control_out->n_inputs();
1734 for (n = 0; n < ni; ++n) {
1735 cports.push_back (_control_out->input(n)->name());
1738 track->set_control_outs (cports);
1741 // assert (current_thread != RT_thread)
1743 track->audio_diskstream()->non_realtime_input_change();
1745 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1746 track->set_remote_control_id (control_id);
1749 new_routes.push_back (track);
1750 ret.push_back (track);
1753 catch (failed_constructor &err) {
1754 error << _("Session: could not create new audio track.") << endmsg;
1755 // XXX should we delete the tracks already created?
1763 if (!new_routes.empty()) {
1764 add_routes (new_routes, false);
1765 save_state (_current_snapshot_name);
1772 Session::set_remote_control_ids ()
1774 RemoteModel m = Config->get_remote_model();
1776 shared_ptr<RouteList> r = routes.reader ();
1778 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1779 if ( MixerOrdered == m) {
1780 long order = (*i)->order_key(N_("signal"));
1781 (*i)->set_remote_control_id( order+1 );
1782 } else if ( EditorOrdered == m) {
1783 long order = (*i)->order_key(N_("editor"));
1784 (*i)->set_remote_control_id( order+1 );
1785 } else if ( UserOrdered == m) {
1786 //do nothing ... only changes to remote id's are initiated by user
1793 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1796 uint32_t bus_id = 1;
1800 uint32_t control_id;
1802 /* count existing audio busses */
1805 shared_ptr<RouteList> r = routes.reader ();
1807 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1808 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1809 if (!(*i)->hidden()) {
1816 vector<string> physinputs;
1817 vector<string> physoutputs;
1819 _engine.get_physical_outputs (physoutputs);
1820 _engine.get_physical_inputs (physinputs);
1821 control_id = ntracks() + nbusses() + 1;
1828 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1830 if (route_by_name (bus_name) == 0) {
1834 } while (bus_id < (UINT_MAX-1));
1837 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1839 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1840 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1841 input_channels, output_channels)
1845 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1849 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1850 port = physinputs[((n+x)%n_physical_inputs)];
1853 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1858 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1862 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1863 port = physoutputs[((n+x)%n_physical_outputs)];
1864 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1866 port = _master_out->input (x%_master_out->n_inputs())->name();
1870 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1876 vector<string> cports;
1877 uint32_t ni = _control_out->n_inputs();
1879 for (uint32_t n = 0; n < ni; ++n) {
1880 cports.push_back (_control_out->input(n)->name());
1882 bus->set_control_outs (cports);
1885 bus->set_remote_control_id (control_id);
1888 ret.push_back (bus);
1892 catch (failed_constructor &err) {
1893 error << _("Session: could not create new audio route.") << endmsg;
1902 add_routes (ret, false);
1903 save_state (_current_snapshot_name);
1911 Session::add_routes (RouteList& new_routes, bool save)
1914 RCUWriter<RouteList> writer (routes);
1915 shared_ptr<RouteList> r = writer.get_copy ();
1916 r->insert (r->end(), new_routes.begin(), new_routes.end());
1917 resort_routes_using (r);
1920 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1922 boost::weak_ptr<Route> wpr (*x);
1924 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1925 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1926 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1927 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1929 if ((*x)->master()) {
1933 if ((*x)->control()) {
1934 _control_out = (*x);
1941 save_state (_current_snapshot_name);
1944 RouteAdded (new_routes); /* EMIT SIGNAL */
1948 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1950 /* need to do this in case we're rolling at the time, to prevent false underruns */
1951 dstream->do_refill_with_alloc();
1954 RCUWriter<DiskstreamList> writer (diskstreams);
1955 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1956 ds->push_back (dstream);
1959 dstream->set_block_size (current_block_size);
1961 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1962 /* this will connect to future changes, and check the current length */
1963 diskstream_playlist_changed (dstream);
1965 dstream->prepare ();
1969 Session::remove_route (shared_ptr<Route> route)
1972 RCUWriter<RouteList> writer (routes);
1973 shared_ptr<RouteList> rs = writer.get_copy ();
1977 /* deleting the master out seems like a dumb
1978 idea, but its more of a UI policy issue
1982 if (route == _master_out) {
1983 _master_out = shared_ptr<Route> ();
1986 if (route == _control_out) {
1987 _control_out = shared_ptr<Route> ();
1989 /* cancel control outs for all routes */
1991 vector<string> empty;
1993 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1994 (*r)->set_control_outs (empty);
1998 update_route_solo_state ();
2000 /* writer goes out of scope, forces route list update */
2003 // FIXME: audio specific
2005 boost::shared_ptr<AudioDiskstream> ds;
2007 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2008 ds = at->audio_diskstream();
2014 RCUWriter<DiskstreamList> dsl (diskstreams);
2015 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2020 find_current_end ();
2022 update_latency_compensation (false, false);
2025 // We need to disconnect the routes inputs and outputs
2026 route->disconnect_inputs(NULL);
2027 route->disconnect_outputs(NULL);
2029 /* get rid of it from the dead wood collection in the route list manager */
2031 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2035 /* try to cause everyone to drop their references */
2037 route->drop_references ();
2039 /* save the new state of the world */
2041 if (save_state (_current_snapshot_name)) {
2042 save_history (_current_snapshot_name);
2047 Session::route_mute_changed (void* src)
2053 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2055 if (solo_update_disabled) {
2061 boost::shared_ptr<Route> route = wpr.lock ();
2064 /* should not happen */
2065 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2069 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2071 shared_ptr<RouteList> r = routes.reader ();
2073 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2075 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2079 /* don't mess with busses */
2081 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2087 /* don't mess with tracks */
2089 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2094 if ((*i) != route &&
2095 ((*i)->mix_group () == 0 ||
2096 (*i)->mix_group () != route->mix_group () ||
2097 !route->mix_group ()->is_active())) {
2099 if ((*i)->soloed()) {
2101 /* if its already soloed, and solo latching is enabled,
2102 then leave it as it is.
2105 if (Config->get_solo_latched()) {
2112 solo_update_disabled = true;
2113 (*i)->set_solo (false, src);
2114 solo_update_disabled = false;
2118 bool something_soloed = false;
2119 bool same_thing_soloed = false;
2120 bool signal = false;
2122 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 if ((*i)->soloed()) {
2124 something_soloed = true;
2125 if (dynamic_cast<AudioTrack*>((*i).get())) {
2127 same_thing_soloed = true;
2132 same_thing_soloed = true;
2140 if (something_soloed != currently_soloing) {
2142 currently_soloing = something_soloed;
2145 modify_solo_mute (is_track, same_thing_soloed);
2148 SoloActive (currently_soloing); /* EMIT SIGNAL */
2151 SoloChanged (); /* EMIT SIGNAL */
2157 Session::update_route_solo_state ()
2160 bool is_track = false;
2161 bool signal = false;
2163 /* caller must hold RouteLock */
2165 /* this is where we actually implement solo by changing
2166 the solo mute setting of each track.
2169 shared_ptr<RouteList> r = routes.reader ();
2171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2172 if ((*i)->soloed()) {
2174 if (dynamic_cast<AudioTrack*>((*i).get())) {
2181 if (mute != currently_soloing) {
2183 currently_soloing = mute;
2186 if (!is_track && !mute) {
2188 /* nothing is soloed */
2190 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2191 (*i)->set_solo_mute (false);
2201 modify_solo_mute (is_track, mute);
2204 SoloActive (currently_soloing);
2209 Session::modify_solo_mute (bool is_track, bool mute)
2211 shared_ptr<RouteList> r = routes.reader ();
2213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2217 /* only alter track solo mute */
2219 if (dynamic_cast<AudioTrack*>((*i).get())) {
2220 if ((*i)->soloed()) {
2221 (*i)->set_solo_mute (!mute);
2223 (*i)->set_solo_mute (mute);
2229 /* only alter bus solo mute */
2231 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2233 if ((*i)->soloed()) {
2235 (*i)->set_solo_mute (false);
2239 /* don't mute master or control outs
2240 in response to another bus solo
2243 if ((*i) != _master_out &&
2244 (*i) != _control_out) {
2245 (*i)->set_solo_mute (mute);
2256 Session::catch_up_on_solo ()
2258 /* this is called after set_state() to catch the full solo
2259 state, which can't be correctly determined on a per-route
2260 basis, but needs the global overview that only the session
2263 update_route_solo_state();
2267 Session::route_by_name (string name)
2269 shared_ptr<RouteList> r = routes.reader ();
2271 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2272 if ((*i)->name() == name) {
2277 return shared_ptr<Route> ((Route*) 0);
2281 Session::route_by_id (PBD::ID id)
2283 shared_ptr<RouteList> r = routes.reader ();
2285 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2286 if ((*i)->id() == id) {
2291 return shared_ptr<Route> ((Route*) 0);
2295 Session::route_by_remote_id (uint32_t id)
2297 shared_ptr<RouteList> r = routes.reader ();
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 if ((*i)->remote_control_id() == id) {
2305 return shared_ptr<Route> ((Route*) 0);
2309 Session::find_current_end ()
2311 if (_state_of_the_state & Loading) {
2315 nframes_t max = get_maximum_extent ();
2317 if (max > end_location->end()) {
2318 end_location->set_end (max);
2320 DurationChanged(); /* EMIT SIGNAL */
2325 Session::get_maximum_extent () const
2330 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2332 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2333 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2334 if ((me = pl->get_maximum_extent()) > max) {
2342 boost::shared_ptr<Diskstream>
2343 Session::diskstream_by_name (string name)
2345 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2347 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2348 if ((*i)->name() == name) {
2353 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2356 boost::shared_ptr<Diskstream>
2357 Session::diskstream_by_id (const PBD::ID& id)
2359 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2361 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2362 if ((*i)->id() == id) {
2367 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2370 /* AudioRegion management */
2373 Session::new_region_name (string old)
2375 string::size_type last_period;
2377 string::size_type len = old.length() + 64;
2380 if ((last_period = old.find_last_of ('.')) == string::npos) {
2382 /* no period present - add one explicitly */
2385 last_period = old.length() - 1;
2390 number = atoi (old.substr (last_period+1).c_str());
2394 while (number < (UINT_MAX-1)) {
2396 AudioRegionList::const_iterator i;
2401 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2404 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2405 if (i->second->name() == sbuf) {
2410 if (i == audio_regions.end()) {
2415 if (number != (UINT_MAX-1)) {
2419 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2424 Session::region_name (string& result, string base, bool newlevel) const
2431 Glib::Mutex::Lock lm (region_lock);
2433 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2441 /* XXX this is going to be slow. optimize me later */
2446 string::size_type pos;
2448 pos = base.find_last_of ('.');
2450 /* pos may be npos, but then we just use entire base */
2452 subbase = base.substr (0, pos);
2456 bool name_taken = true;
2459 Glib::Mutex::Lock lm (region_lock);
2461 for (int n = 1; n < 5000; ++n) {
2464 snprintf (buf, sizeof (buf), ".%d", n);
2469 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2470 if (i->second->name() == result) {
2483 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2491 Session::add_region (boost::shared_ptr<Region> region)
2493 boost::shared_ptr<AudioRegion> ar;
2494 boost::shared_ptr<AudioRegion> oar;
2498 Glib::Mutex::Lock lm (region_lock);
2500 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2502 AudioRegionList::iterator x;
2504 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2506 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2508 if (ar->region_list_equivalent (oar)) {
2513 if (x == audio_regions.end()) {
2515 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2517 entry.first = region->id();
2520 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2532 fatal << _("programming error: ")
2533 << X_("unknown region type passed to Session::add_region()")
2540 /* mark dirty because something has changed even if we didn't
2541 add the region to the region list.
2547 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2548 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2549 AudioRegionAdded (ar); /* EMIT SIGNAL */
2554 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2556 boost::shared_ptr<Region> region (weak_region.lock ());
2562 if (what_changed & Region::HiddenChanged) {
2563 /* relay hidden changes */
2564 RegionHiddenChange (region);
2569 Session::remove_region (boost::weak_ptr<Region> weak_region)
2571 AudioRegionList::iterator i;
2572 boost::shared_ptr<Region> region (weak_region.lock ());
2578 boost::shared_ptr<AudioRegion> ar;
2579 bool removed = false;
2582 Glib::Mutex::Lock lm (region_lock);
2584 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2585 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2586 audio_regions.erase (i);
2592 fatal << _("programming error: ")
2593 << X_("unknown region type passed to Session::remove_region()")
2599 /* mark dirty because something has changed even if we didn't
2600 remove the region from the region list.
2606 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2610 boost::shared_ptr<AudioRegion>
2611 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2613 AudioRegionList::iterator i;
2614 boost::shared_ptr<AudioRegion> region;
2615 Glib::Mutex::Lock lm (region_lock);
2617 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2621 if (region->whole_file()) {
2623 if (child->source_equivalent (region)) {
2629 return boost::shared_ptr<AudioRegion> ();
2633 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2635 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2636 (*i)->get_region_list_equivalent_regions (region, result);
2640 Session::destroy_region (boost::shared_ptr<Region> region)
2642 vector<boost::shared_ptr<Source> > srcs;
2645 boost::shared_ptr<AudioRegion> aregion;
2647 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2651 if (aregion->playlist()) {
2652 aregion->playlist()->destroy_region (region);
2655 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2656 srcs.push_back (aregion->source (n));
2660 region->drop_references ();
2662 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2664 if (!(*i)->used()) {
2665 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2668 (afs)->mark_for_remove ();
2671 (*i)->drop_references ();
2673 cerr << "source was not used by any playlist\n";
2681 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2683 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2684 destroy_region (*i);
2690 Session::remove_last_capture ()
2692 list<boost::shared_ptr<Region> > r;
2694 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2696 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2697 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2700 r.insert (r.end(), l.begin(), l.end());
2705 destroy_regions (r);
2710 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2716 /* Source Management */
2719 Session::add_source (boost::shared_ptr<Source> source)
2721 boost::shared_ptr<AudioFileSource> afs;
2723 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2725 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2726 pair<AudioSourceList::iterator,bool> result;
2728 entry.first = source->id();
2732 Glib::Mutex::Lock lm (audio_source_lock);
2733 result = audio_sources.insert (entry);
2736 if (result.second) {
2737 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2745 Session::remove_source (boost::weak_ptr<Source> src)
2747 AudioSourceList::iterator i;
2748 boost::shared_ptr<Source> source = src.lock();
2755 Glib::Mutex::Lock lm (audio_source_lock);
2757 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2758 audio_sources.erase (i);
2762 if (!_state_of_the_state & InCleanup) {
2764 /* save state so we don't end up with a session file
2765 referring to non-existent sources.
2768 save_state (_current_snapshot_name);
2772 boost::shared_ptr<Source>
2773 Session::source_by_id (const PBD::ID& id)
2775 Glib::Mutex::Lock lm (audio_source_lock);
2776 AudioSourceList::iterator i;
2777 boost::shared_ptr<Source> source;
2779 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2783 /* XXX search MIDI or other searches here */
2789 Session::peak_path_from_audio_path (string audio_path) const
2794 res += PBD::basename_nosuffix (audio_path);
2801 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2804 string old_basename = PBD::basename_nosuffix (oldname);
2805 string new_legalized = legalize_for_path (newname);
2807 /* note: we know (or assume) the old path is already valid */
2811 /* destructive file sources have a name of the form:
2813 /path/to/Tnnnn-NAME(%[LR])?.wav
2815 the task here is to replace NAME with the new name.
2818 /* find last slash */
2822 string::size_type slash;
2823 string::size_type dash;
2825 if ((slash = path.find_last_of ('/')) == string::npos) {
2829 dir = path.substr (0, slash+1);
2831 /* '-' is not a legal character for the NAME part of the path */
2833 if ((dash = path.find_last_of ('-')) == string::npos) {
2837 prefix = path.substr (slash+1, dash-(slash+1));
2842 path += new_legalized;
2843 path += ".wav"; /* XXX gag me with a spoon */
2847 /* non-destructive file sources have a name of the form:
2849 /path/to/NAME-nnnnn(%[LR])?.wav
2851 the task here is to replace NAME with the new name.
2856 string::size_type slash;
2857 string::size_type dash;
2858 string::size_type postfix;
2860 /* find last slash */
2862 if ((slash = path.find_last_of ('/')) == string::npos) {
2866 dir = path.substr (0, slash+1);
2868 /* '-' is not a legal character for the NAME part of the path */
2870 if ((dash = path.find_last_of ('-')) == string::npos) {
2874 suffix = path.substr (dash+1);
2876 // Suffix is now everything after the dash. Now we need to eliminate
2877 // the nnnnn part, which is done by either finding a '%' or a '.'
2879 postfix = suffix.find_last_of ("%");
2880 if (postfix == string::npos) {
2881 postfix = suffix.find_last_of ('.');
2884 if (postfix != string::npos) {
2885 suffix = suffix.substr (postfix);
2887 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2891 const uint32_t limit = 10000;
2892 char buf[PATH_MAX+1];
2894 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2896 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2898 if (access (buf, F_OK) != 0) {
2906 error << "FATAL ERROR! Could not find a " << endl;
2915 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2919 char buf[PATH_MAX+1];
2920 const uint32_t limit = 10000;
2924 legalized = legalize_for_path (name);
2926 /* find a "version" of the file name that doesn't exist in
2927 any of the possible directories.
2930 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2932 vector<space_and_path>::iterator i;
2933 uint32_t existing = 0;
2935 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2939 spath += sound_dir (false);
2943 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2944 } else if (nchan == 2) {
2946 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2948 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2950 } else if (nchan < 26) {
2951 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2953 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2962 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2963 } else if (nchan == 2) {
2965 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2967 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2969 } else if (nchan < 26) {
2970 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2972 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2976 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2982 if (existing == 0) {
2987 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2989 throw failed_constructor();
2993 /* we now have a unique name for the file, but figure out where to
2999 spath = discover_best_sound_dir ();
3002 string::size_type pos = foo.find_last_of ('/');
3004 if (pos == string::npos) {
3007 spath += foo.substr (pos + 1);
3013 boost::shared_ptr<AudioFileSource>
3014 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3016 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3017 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3020 /* Playlist management */
3022 boost::shared_ptr<Playlist>
3023 Session::playlist_by_name (string name)
3025 Glib::Mutex::Lock lm (playlist_lock);
3026 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3027 if ((*i)->name() == name) {
3031 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3032 if ((*i)->name() == name) {
3037 return boost::shared_ptr<Playlist>();
3041 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3043 if (playlist->hidden()) {
3048 Glib::Mutex::Lock lm (playlist_lock);
3049 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3050 playlists.insert (playlists.begin(), playlist);
3051 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3052 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3058 PlaylistAdded (playlist); /* EMIT SIGNAL */
3062 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3065 Glib::Mutex::Lock lm (playlist_lock);
3066 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3069 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3076 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3078 boost::shared_ptr<Playlist> pl(wpl.lock());
3084 PlaylistList::iterator x;
3087 /* its not supposed to be visible */
3092 Glib::Mutex::Lock lm (playlist_lock);
3096 unused_playlists.insert (pl);
3098 if ((x = playlists.find (pl)) != playlists.end()) {
3099 playlists.erase (x);
3105 playlists.insert (pl);
3107 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3108 unused_playlists.erase (x);
3115 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3117 if (_state_of_the_state & Deletion) {
3121 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3128 Glib::Mutex::Lock lm (playlist_lock);
3130 PlaylistList::iterator i;
3132 i = find (playlists.begin(), playlists.end(), playlist);
3133 if (i != playlists.end()) {
3134 playlists.erase (i);
3137 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3138 if (i != unused_playlists.end()) {
3139 unused_playlists.erase (i);
3146 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3150 Session::set_audition (boost::shared_ptr<Region> r)
3152 pending_audition_region = r;
3153 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3154 schedule_butler_transport_work ();
3158 Session::audition_playlist ()
3160 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3161 ev->region.reset ();
3166 Session::non_realtime_set_audition ()
3168 if (!pending_audition_region) {
3169 auditioner->audition_current_playlist ();
3171 auditioner->audition_region (pending_audition_region);
3172 pending_audition_region.reset ();
3174 AuditionActive (true); /* EMIT SIGNAL */
3178 Session::audition_region (boost::shared_ptr<Region> r)
3180 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3186 Session::cancel_audition ()
3188 if (auditioner->active()) {
3189 auditioner->cancel_audition ();
3190 AuditionActive (false); /* EMIT SIGNAL */
3195 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3197 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3201 Session::remove_empty_sounds ()
3203 PathScanner scanner;
3205 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3207 Glib::Mutex::Lock lm (audio_source_lock);
3209 regex_t compiled_tape_track_pattern;
3212 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3216 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3218 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3222 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3224 /* never remove files that appear to be a tape track */
3226 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3231 if (AudioFileSource::is_empty (*this, *(*i))) {
3233 unlink ((*i)->c_str());
3235 string peak_path = peak_path_from_audio_path (**i);
3236 unlink (peak_path.c_str());
3242 delete possible_audiofiles;
3246 Session::is_auditioning () const
3248 /* can be called before we have an auditioner object */
3250 return auditioner->active();
3257 Session::set_all_solo (bool yn)
3259 shared_ptr<RouteList> r = routes.reader ();
3261 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3262 if (!(*i)->hidden()) {
3263 (*i)->set_solo (yn, this);
3271 Session::set_all_mute (bool yn)
3273 shared_ptr<RouteList> r = routes.reader ();
3275 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3276 if (!(*i)->hidden()) {
3277 (*i)->set_mute (yn, this);
3285 Session::n_diskstreams () const
3289 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3291 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3292 if (!(*i)->hidden()) {
3300 Session::graph_reordered ()
3302 /* don't do this stuff if we are setting up connections
3303 from a set_state() call.
3306 if (_state_of_the_state & InitialConnecting) {
3310 /* every track/bus asked for this to be handled but it was deferred because
3311 we were connecting. do it now.
3314 request_input_change_handling ();
3318 /* force all diskstreams to update their capture offset values to
3319 reflect any changes in latencies within the graph.
3322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3325 (*i)->set_capture_offset ();
3330 Session::record_disenable_all ()
3332 record_enable_change_all (false);
3336 Session::record_enable_all ()
3338 record_enable_change_all (true);
3342 Session::record_enable_change_all (bool yn)
3344 shared_ptr<RouteList> r = routes.reader ();
3346 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3349 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3350 at->set_record_enable (yn, this);
3354 /* since we don't keep rec-enable state, don't mark session dirty */
3358 Session::add_redirect (Redirect* redirect)
3362 PortInsert* port_insert;
3363 PluginInsert* plugin_insert;
3365 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3366 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3367 _port_inserts.insert (_port_inserts.begin(), port_insert);
3368 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3369 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3371 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3374 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3375 _sends.insert (_sends.begin(), send);
3377 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3381 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3387 Session::remove_redirect (Redirect* redirect)
3391 PortInsert* port_insert;
3392 PluginInsert* plugin_insert;
3394 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3395 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3396 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3397 if (x != _port_inserts.end()) {
3398 insert_bitset[port_insert->bit_slot()] = false;
3399 _port_inserts.erase (x);
3401 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3402 _plugin_inserts.remove (plugin_insert);
3404 fatal << string_compose (_("programming error: %1"),
3405 X_("unknown type of Insert deleted!"))
3409 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3410 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3411 if (x != _sends.end()) {
3412 send_bitset[send->bit_slot()] = false;
3416 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3424 Session::available_capture_duration ()
3426 float sample_bytes_on_disk = 4.0; // keep gcc happy
3428 switch (Config->get_native_file_data_format()) {
3430 sample_bytes_on_disk = 4.0;
3434 sample_bytes_on_disk = 3.0;
3438 /* impossible, but keep some gcc versions happy */
3439 fatal << string_compose (_("programming error: %1"),
3440 X_("illegal native file data format"))
3445 double scale = 4096.0 / sample_bytes_on_disk;
3447 if (_total_free_4k_blocks * scale > (double) max_frames) {
3451 return (nframes_t) floor (_total_free_4k_blocks * scale);
3455 Session::add_connection (ARDOUR::Connection* connection)
3458 Glib::Mutex::Lock guard (connection_lock);
3459 _connections.push_back (connection);
3462 ConnectionAdded (connection); /* EMIT SIGNAL */
3468 Session::remove_connection (ARDOUR::Connection* connection)
3470 bool removed = false;
3473 Glib::Mutex::Lock guard (connection_lock);
3474 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3476 if (i != _connections.end()) {
3477 _connections.erase (i);
3483 ConnectionRemoved (connection); /* EMIT SIGNAL */
3489 ARDOUR::Connection *
3490 Session::connection_by_name (string name) const
3492 Glib::Mutex::Lock lm (connection_lock);
3494 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3495 if ((*i)->name() == name) {
3504 Session::tempo_map_changed (Change ignored)
3511 Session::ensure_passthru_buffers (uint32_t howmany)
3513 while (howmany > _passthru_buffers.size()) {
3515 #ifdef NO_POSIX_MEMALIGN
3516 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3518 posix_memalign((void **)&p,16,current_block_size * 4);
3520 _passthru_buffers.push_back (p);
3524 #ifdef NO_POSIX_MEMALIGN
3525 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3527 posix_memalign((void **)&p,16,current_block_size * 4);
3529 memset (p, 0, sizeof (Sample) * current_block_size);
3530 _silent_buffers.push_back (p);
3534 #ifdef NO_POSIX_MEMALIGN
3535 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3537 posix_memalign((void **)&p,16,current_block_size * 4);
3539 memset (p, 0, sizeof (Sample) * current_block_size);
3540 _send_buffers.push_back (p);
3543 allocate_pan_automation_buffers (current_block_size, howmany, false);
3547 Session::next_insert_id ()
3549 /* this doesn't really loop forever. just think about it */
3552 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3553 if (!insert_bitset[n]) {
3554 insert_bitset[n] = true;
3555 cerr << "Returning " << n << " as insert ID\n";
3561 /* none available, so resize and try again */
3563 insert_bitset.resize (insert_bitset.size() + 16, false);
3568 Session::next_send_id ()
3570 /* this doesn't really loop forever. just think about it */
3573 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3574 if (!send_bitset[n]) {
3575 send_bitset[n] = true;
3576 cerr << "Returning " << n << " as send ID\n";
3582 /* none available, so resize and try again */
3584 send_bitset.resize (send_bitset.size() + 16, false);
3589 Session::mark_send_id (uint32_t id)
3591 if (id >= send_bitset.size()) {
3592 send_bitset.resize (id+16, false);
3594 if (send_bitset[id]) {
3595 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3597 send_bitset[id] = true;
3601 Session::mark_insert_id (uint32_t id)
3603 if (id >= insert_bitset.size()) {
3604 insert_bitset.resize (id+16, false);
3606 if (insert_bitset[id]) {
3607 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3609 insert_bitset[id] = true;
3612 /* Named Selection management */
3615 Session::named_selection_by_name (string name)
3617 Glib::Mutex::Lock lm (named_selection_lock);
3618 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3619 if ((*i)->name == name) {
3627 Session::add_named_selection (NamedSelection* named_selection)
3630 Glib::Mutex::Lock lm (named_selection_lock);
3631 named_selections.insert (named_selections.begin(), named_selection);
3634 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3640 NamedSelectionAdded (); /* EMIT SIGNAL */
3644 Session::remove_named_selection (NamedSelection* named_selection)
3646 bool removed = false;
3649 Glib::Mutex::Lock lm (named_selection_lock);
3651 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3653 if (i != named_selections.end()) {
3655 named_selections.erase (i);
3662 NamedSelectionRemoved (); /* EMIT SIGNAL */
3667 Session::reset_native_file_format ()
3669 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3671 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3672 (*i)->reset_write_sources (false);
3677 Session::route_name_unique (string n) const
3679 shared_ptr<RouteList> r = routes.reader ();
3681 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3682 if ((*i)->name() == n) {
3691 Session::n_playlists () const
3693 Glib::Mutex::Lock lm (playlist_lock);
3694 return playlists.size();
3698 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3700 if (!force && howmany <= _npan_buffers) {
3704 if (_pan_automation_buffer) {
3706 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3707 delete [] _pan_automation_buffer[i];
3710 delete [] _pan_automation_buffer;
3713 _pan_automation_buffer = new pan_t*[howmany];
3715 for (uint32_t i = 0; i < howmany; ++i) {
3716 _pan_automation_buffer[i] = new pan_t[nframes];
3719 _npan_buffers = howmany;
3723 Session::freeze (InterThreadInfo& itt)
3725 shared_ptr<RouteList> r = routes.reader ();
3727 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3731 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3732 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3743 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3744 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3747 boost::shared_ptr<Playlist> playlist;
3748 boost::shared_ptr<AudioFileSource> fsource;
3750 char buf[PATH_MAX+1];
3754 nframes_t this_chunk;
3756 vector<Sample*> buffers;
3758 // any bigger than this seems to cause stack overflows in called functions
3759 const nframes_t chunk_size = (128 * 1024)/4;
3761 g_atomic_int_set (&processing_prohibited, 1);
3763 /* call tree *MUST* hold route_lock */
3765 if ((playlist = track.diskstream()->playlist()) == 0) {
3769 /* external redirects will be a problem */
3771 if (track.has_external_redirects()) {
3775 nchans = track.audio_diskstream()->n_channels();
3777 dir = discover_best_sound_dir ();
3779 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3781 for (x = 0; x < 99999; ++x) {
3782 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3783 if (access (buf, F_OK) != 0) {
3789 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3794 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3797 catch (failed_constructor& err) {
3798 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3802 srcs.push_back (fsource);
3805 /* XXX need to flush all redirects */
3810 /* create a set of reasonably-sized buffers */
3812 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3814 #ifdef NO_POSIX_MEMALIGN
3815 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3817 posix_memalign((void **)&b,16,chunk_size * 4);
3819 buffers.push_back (b);
3822 while (to_do && !itt.cancel) {
3824 this_chunk = min (to_do, chunk_size);
3826 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3831 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3832 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3835 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3841 start += this_chunk;
3842 to_do -= this_chunk;
3844 itt.progress = (float) (1.0 - ((double) to_do / len));
3853 xnow = localtime (&now);
3855 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3856 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3859 afs->update_header (position, *xnow, now);
3863 /* build peakfile for new source */
3865 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3866 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3868 afs->build_peaks ();
3872 /* construct a region to represent the bounced material */
3874 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3875 region_name_from_path (srcs.front()->name(), true));
3882 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3883 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3886 afs->mark_for_remove ();
3889 (*src)->drop_references ();
3893 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3897 g_atomic_int_set (&processing_prohibited, 0);
3905 Session::get_silent_buffers (uint32_t howmany)
3907 for (uint32_t i = 0; i < howmany; ++i) {
3908 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3910 return _silent_buffers;
3914 Session::ntracks () const
3917 shared_ptr<RouteList> r = routes.reader ();
3919 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3920 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3929 Session::nbusses () const
3932 shared_ptr<RouteList> r = routes.reader ();
3934 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3935 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3944 Session::add_automation_list(AutomationList *al)
3946 automation_lists[al->id()] = al;
3950 Session::compute_initial_length ()
3952 return _engine.frame_rate() * 60 * 5;