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>
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/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
68 #include <ardour/source_factory.h>
69 #include <ardour/region_factory.h>
72 #include <ardour/osc.h>
78 using namespace ARDOUR;
80 using boost::shared_ptr;
82 const char* Session::_template_suffix = X_(".template");
83 const char* Session::_statefile_suffix = X_(".ardour");
84 const char* Session::_pending_suffix = X_(".pending");
85 const char* Session::old_sound_dir_name = X_("sounds");
86 const char* Session::sound_dir_name = X_("audiofiles");
87 const char* Session::peak_dir_name = X_("peaks");
88 const char* Session::dead_sound_dir_name = X_("dead_sounds");
89 const char* Session::interchange_dir_name = X_("interchange");
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, _engine.frame_rate() * 60 * 5)) {
282 cerr << "create failed\n";
283 throw failed_constructor ();
287 if (second_stage_init (new_session)) {
288 cerr << "2nd state failed\n";
289 throw failed_constructor ();
292 store_recent_sessions(_name, _path);
294 bool was_dirty = dirty();
296 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
298 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
301 DirtyChanged (); /* EMIT SIGNAL */
305 Session::Session (AudioEngine &eng,
307 string snapshot_name,
308 AutoConnectOption input_ac,
309 AutoConnectOption output_ac,
310 uint32_t control_out_channels,
311 uint32_t master_out_channels,
312 uint32_t requested_physical_in,
313 uint32_t requested_physical_out,
314 nframes_t initial_length)
317 _mmc_port (default_mmc_port),
318 _mtc_port (default_mtc_port),
319 _midi_port (default_midi_port),
320 pending_events (2048),
322 diskstreams (new DiskstreamList),
323 routes (new RouteList),
329 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
331 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
332 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
334 first_stage_init (fullpath, snapshot_name);
336 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
338 if (create (new_session, 0, initial_length)) {
339 throw failed_constructor ();
343 if (control_out_channels) {
344 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
351 if (master_out_channels) {
352 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
358 /* prohibit auto-connect to master, because there isn't one */
359 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
362 Config->set_input_auto_connect (input_ac);
363 Config->set_output_auto_connect (output_ac);
365 if (second_stage_init (new_session)) {
366 throw failed_constructor ();
369 store_recent_sessions(_name, _path);
371 bool was_dirty = dirty ();
373 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
376 DirtyChanged (); /* EMIT SIGNAL */
382 /* if we got to here, leaving pending capture state around
386 remove_pending_capture_state ();
388 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
389 _engine.remove_session ();
391 GoingAway (); /* EMIT SIGNAL */
397 /* clear history so that no references to objects are held any more */
401 /* clear state tree so that no references to objects are held any more */
407 terminate_butler_thread ();
408 terminate_midi_thread ();
410 if (click_data && click_data != default_click) {
411 delete [] click_data;
414 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
415 delete [] click_emphasis_data;
420 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
424 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
428 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
432 AudioDiskstream::free_working_buffers();
434 #undef TRACK_DESTRUCTION
435 #ifdef TRACK_DESTRUCTION
436 cerr << "delete named selections\n";
437 #endif /* TRACK_DESTRUCTION */
438 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
439 NamedSelectionList::iterator tmp;
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete playlists\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
452 PlaylistList::iterator tmp;
462 #ifdef TRACK_DESTRUCTION
463 cerr << "delete audio regions\n";
464 #endif /* TRACK_DESTRUCTION */
466 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
467 AudioRegionList::iterator tmp;
472 cerr << "dropping refs on an audio region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl;
473 i->second->drop_references ();
474 cerr << "AFTER: UC = " << i->second.use_count() << endl;
479 audio_regions.clear ();
481 #ifdef TRACK_DESTRUCTION
482 cerr << "delete routes\n";
483 #endif /* TRACK_DESTRUCTION */
485 RCUWriter<RouteList> writer (routes);
486 boost::shared_ptr<RouteList> r = writer.get_copy ();
487 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
488 (*i)->drop_references ();
491 /* writer goes out of scope and updates master */
496 #ifdef TRACK_DESTRUCTION
497 cerr << "delete diskstreams\n";
498 #endif /* TRACK_DESTRUCTION */
500 RCUWriter<DiskstreamList> dwriter (diskstreams);
501 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
502 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
503 (*i)->drop_references ();
507 diskstreams.flush ();
509 #ifdef TRACK_DESTRUCTION
510 cerr << "delete audio sources\n";
511 #endif /* TRACK_DESTRUCTION */
512 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
513 AudioSourceList::iterator tmp;
518 i->second->drop_references ();
523 audio_sources.clear ();
525 #ifdef TRACK_DESTRUCTION
526 cerr << "delete mix groups\n";
527 #endif /* TRACK_DESTRUCTION */
528 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
529 list<RouteGroup*>::iterator tmp;
539 #ifdef TRACK_DESTRUCTION
540 cerr << "delete edit groups\n";
541 #endif /* TRACK_DESTRUCTION */
542 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
543 list<RouteGroup*>::iterator tmp;
553 #ifdef TRACK_DESTRUCTION
554 cerr << "delete connections\n";
555 #endif /* TRACK_DESTRUCTION */
556 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
557 ConnectionList::iterator tmp;
567 if (butler_mixdown_buffer) {
568 delete [] butler_mixdown_buffer;
571 if (butler_gain_buffer) {
572 delete [] butler_gain_buffer;
575 Crossfade::set_buffer_size (0);
583 Session::set_worst_io_latencies ()
585 _worst_output_latency = 0;
586 _worst_input_latency = 0;
588 if (!_engine.connected()) {
592 boost::shared_ptr<RouteList> r = routes.reader ();
594 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
595 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
596 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
601 Session::when_engine_running ()
603 string first_physical_output;
605 /* we don't want to run execute this again */
607 first_time_running.disconnect ();
609 set_block_size (_engine.frames_per_cycle());
610 set_frame_rate (_engine.frame_rate());
612 Config->map_parameters (mem_fun (*this, &Session::config_changed));
614 /* every time we reconnect, recompute worst case output latencies */
616 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
618 if (synced_to_jack()) {
619 _engine.transport_stop ();
622 if (Config->get_jack_time_master()) {
623 _engine.transport_locate (_transport_frame);
631 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
633 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
635 /* existing state for Click */
637 if (_click_io->set_state (*child->children().front()) == 0) {
639 _clicking = Config->get_clicking ();
643 error << _("could not setup Click I/O") << endmsg;
649 /* default state for Click */
651 first_physical_output = _engine.get_nth_physical_output (0);
653 if (first_physical_output.length()) {
654 if (_click_io->add_output_port (first_physical_output, this)) {
655 // relax, even though its an error
657 _clicking = Config->get_clicking ();
663 catch (failed_constructor& err) {
664 error << _("cannot setup Click I/O") << endmsg;
667 set_worst_io_latencies ();
670 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
673 if (auditioner == 0) {
675 /* we delay creating the auditioner till now because
676 it makes its own connections to ports named
677 in the ARDOUR_RC config file. the engine has
678 to be running for this to work.
682 auditioner.reset (new Auditioner (*this));
685 catch (failed_constructor& err) {
686 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
690 /* Create a set of Connection objects that map
691 to the physical outputs currently available
696 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
698 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
700 Connection* c = new OutputConnection (buf, true);
703 c->add_connection (0, _engine.get_nth_physical_output (np));
708 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
710 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
712 Connection* c = new InputConnection (buf, true);
715 c->add_connection (0, _engine.get_nth_physical_input (np));
722 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
724 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
726 Connection* c = new OutputConnection (buf, true);
730 c->add_connection (0, _engine.get_nth_physical_output (np));
731 c->add_connection (1, _engine.get_nth_physical_output (np+1));
736 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
738 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
740 Connection* c = new InputConnection (buf, true);
744 c->add_connection (0, _engine.get_nth_physical_input (np));
745 c->add_connection (1, _engine.get_nth_physical_input (np+1));
754 /* create master/control ports */
759 /* force the master to ignore any later call to this */
761 if (_master_out->pending_state_node) {
762 _master_out->ports_became_legal();
765 /* no panner resets till we are through */
767 _master_out->defer_pan_reset ();
769 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
770 if (_master_out->add_input_port ("", this)) {
771 error << _("cannot setup master inputs")
777 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
778 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
779 error << _("cannot setup master outputs")
786 _master_out->allow_pan_reset ();
790 Connection* c = new OutputConnection (_("Master Out"), true);
792 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
794 c->add_connection ((int) n, _master_out->input(n)->name());
801 /* catch up on send+insert cnts */
805 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
808 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
809 if (id > insert_cnt) {
817 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
820 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
827 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
829 /* hook us up to the engine */
831 _engine.set_session (this);
836 osc->set_session (*this);
839 _state_of_the_state = Clean;
841 DirtyChanged (); /* EMIT SIGNAL */
845 Session::hookup_io ()
847 /* stop graph reordering notifications from
848 causing resorts, etc.
851 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
853 /* Tell all IO objects to create their ports */
860 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
861 if (_control_out->add_input_port ("", this)) {
862 error << _("cannot setup control inputs")
868 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
869 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
870 error << _("cannot set up master outputs")
878 /* Tell all IO objects to connect themselves together */
880 IO::enable_connecting ();
882 /* Now reset all panners */
884 IO::reset_panners ();
886 /* Anyone who cares about input state, wake up and do something */
888 IOConnectionsComplete (); /* EMIT SIGNAL */
890 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
892 /* now handle the whole enchilada as if it was one
898 /* update mixer solo state */
904 Session::playlist_length_changed (Playlist* pl)
906 /* we can't just increase end_location->end() if pl->get_maximum_extent()
907 if larger. if the playlist used to be the longest playlist,
908 and its now shorter, we have to decrease end_location->end(). hence,
909 we have to iterate over all diskstreams and check the
910 playlists currently in use.
916 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
920 if ((playlist = dstream->playlist()) != 0) {
921 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
924 /* see comment in playlist_length_changed () */
929 Session::record_enabling_legal () const
931 /* this used to be in here, but survey says.... we don't need to restrict it */
932 // if (record_status() == Recording) {
936 if (Config->get_all_safe()) {
943 Session::reset_input_monitor_state ()
945 if (transport_rolling()) {
947 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
949 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
950 if ((*i)->record_enabled ()) {
951 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
952 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
956 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
958 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
959 if ((*i)->record_enabled ()) {
960 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
961 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
968 Session::auto_punch_start_changed (Location* location)
970 replace_event (Event::PunchIn, location->start());
972 if (get_record_enabled() && Config->get_punch_in()) {
973 /* capture start has been changed, so save new pending state */
974 save_state ("", true);
979 Session::auto_punch_end_changed (Location* location)
981 nframes_t when_to_stop = location->end();
982 // when_to_stop += _worst_output_latency + _worst_input_latency;
983 replace_event (Event::PunchOut, when_to_stop);
987 Session::auto_punch_changed (Location* location)
989 nframes_t when_to_stop = location->end();
991 replace_event (Event::PunchIn, location->start());
992 //when_to_stop += _worst_output_latency + _worst_input_latency;
993 replace_event (Event::PunchOut, when_to_stop);
997 Session::auto_loop_changed (Location* location)
999 replace_event (Event::AutoLoop, location->end(), location->start());
1001 if (transport_rolling() && play_loop) {
1003 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1005 if (_transport_frame > location->end()) {
1006 // relocate to beginning of loop
1007 clear_events (Event::LocateRoll);
1009 request_locate (location->start(), true);
1012 else if (Config->get_seamless_loop() && !loop_changing) {
1014 // schedule a locate-roll to refill the diskstreams at the
1015 // previous loop end
1016 loop_changing = true;
1018 if (location->end() > last_loopend) {
1019 clear_events (Event::LocateRoll);
1020 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1027 last_loopend = location->end();
1032 Session::set_auto_punch_location (Location* location)
1036 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1037 auto_punch_start_changed_connection.disconnect();
1038 auto_punch_end_changed_connection.disconnect();
1039 auto_punch_changed_connection.disconnect();
1040 existing->set_auto_punch (false, this);
1041 remove_event (existing->start(), Event::PunchIn);
1042 clear_events (Event::PunchOut);
1043 auto_punch_location_changed (0);
1048 if (location == 0) {
1052 if (location->end() <= location->start()) {
1053 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1057 auto_punch_start_changed_connection.disconnect();
1058 auto_punch_end_changed_connection.disconnect();
1059 auto_punch_changed_connection.disconnect();
1061 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1062 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1063 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1065 location->set_auto_punch (true, this);
1066 auto_punch_location_changed (location);
1070 Session::set_auto_loop_location (Location* location)
1074 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1075 auto_loop_start_changed_connection.disconnect();
1076 auto_loop_end_changed_connection.disconnect();
1077 auto_loop_changed_connection.disconnect();
1078 existing->set_auto_loop (false, this);
1079 remove_event (existing->end(), Event::AutoLoop);
1080 auto_loop_location_changed (0);
1085 if (location == 0) {
1089 if (location->end() <= location->start()) {
1090 error << _("Session: you can't use a mark for auto loop") << endmsg;
1094 last_loopend = location->end();
1096 auto_loop_start_changed_connection.disconnect();
1097 auto_loop_end_changed_connection.disconnect();
1098 auto_loop_changed_connection.disconnect();
1100 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1101 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1102 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1104 location->set_auto_loop (true, this);
1105 auto_loop_location_changed (location);
1109 Session::locations_added (Location* ignored)
1115 Session::locations_changed ()
1117 _locations.apply (*this, &Session::handle_locations_changed);
1121 Session::handle_locations_changed (Locations::LocationList& locations)
1123 Locations::LocationList::iterator i;
1125 bool set_loop = false;
1126 bool set_punch = false;
1128 for (i = locations.begin(); i != locations.end(); ++i) {
1132 if (location->is_auto_punch()) {
1133 set_auto_punch_location (location);
1136 if (location->is_auto_loop()) {
1137 set_auto_loop_location (location);
1144 set_auto_loop_location (0);
1147 set_auto_punch_location (0);
1154 Session::enable_record ()
1156 /* XXX really atomic compare+swap here */
1157 if (g_atomic_int_get (&_record_status) != Recording) {
1158 g_atomic_int_set (&_record_status, Recording);
1159 _last_record_location = _transport_frame;
1160 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1162 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1163 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1164 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1165 if ((*i)->record_enabled ()) {
1166 (*i)->monitor_input (true);
1171 RecordStateChanged ();
1176 Session::disable_record (bool rt_context, bool force)
1180 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1182 if (!Config->get_latched_record_enable () || force) {
1183 g_atomic_int_set (&_record_status, Disabled);
1185 if (rs == Recording) {
1186 g_atomic_int_set (&_record_status, Enabled);
1190 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1192 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1193 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1195 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1196 if ((*i)->record_enabled ()) {
1197 (*i)->monitor_input (false);
1202 RecordStateChanged (); /* emit signal */
1205 remove_pending_capture_state ();
1211 Session::step_back_from_record ()
1213 g_atomic_int_set (&_record_status, Enabled);
1215 if (Config->get_monitoring_model() == HardwareMonitoring) {
1216 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1218 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1219 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1220 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1221 (*i)->monitor_input (false);
1228 Session::maybe_enable_record ()
1230 g_atomic_int_set (&_record_status, Enabled);
1232 /* this function is currently called from somewhere other than an RT thread.
1233 this save_state() call therefore doesn't impact anything.
1236 save_state ("", true);
1238 if (_transport_speed) {
1239 if (!Config->get_punch_in()) {
1243 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1244 RecordStateChanged (); /* EMIT SIGNAL */
1251 Session::audible_frame () const
1257 /* the first of these two possible settings for "offset"
1258 mean that the audible frame is stationary until
1259 audio emerges from the latency compensation
1262 the second means that the audible frame is stationary
1263 until audio would emerge from a physical port
1264 in the absence of any plugin latency compensation
1267 offset = _worst_output_latency;
1269 if (offset > current_block_size) {
1270 offset -= current_block_size;
1272 /* XXX is this correct? if we have no external
1273 physical connections and everything is internal
1274 then surely this is zero? still, how
1275 likely is that anyway?
1277 offset = current_block_size;
1280 if (synced_to_jack()) {
1281 tf = _engine.transport_frame();
1283 tf = _transport_frame;
1286 if (_transport_speed == 0) {
1296 if (!non_realtime_work_pending()) {
1300 /* take latency into account */
1309 Session::set_frame_rate (nframes_t frames_per_second)
1311 /** \fn void Session::set_frame_size(nframes_t)
1312 the AudioEngine object that calls this guarantees
1313 that it will not be called while we are also in
1314 ::process(). Its fine to do things that block
1318 _base_frame_rate = frames_per_second;
1322 // XXX we need some equivalent to this, somehow
1323 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1327 /* XXX need to reset/reinstantiate all LADSPA plugins */
1331 Session::set_block_size (nframes_t nframes)
1333 /* the AudioEngine guarantees
1334 that it will not be called while we are also in
1335 ::process(). It is therefore fine to do things that block
1340 vector<Sample*>::iterator i;
1343 current_block_size = nframes;
1345 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1349 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1353 _passthru_buffers.clear ();
1354 _silent_buffers.clear ();
1356 ensure_passthru_buffers (np);
1358 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1362 #ifdef NO_POSIX_MEMALIGN
1363 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1365 posix_memalign((void **)&buf,16,current_block_size * 4);
1369 memset (*i, 0, sizeof (Sample) * current_block_size);
1373 if (_gain_automation_buffer) {
1374 delete [] _gain_automation_buffer;
1376 _gain_automation_buffer = new gain_t[nframes];
1378 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1380 boost::shared_ptr<RouteList> r = routes.reader ();
1382 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1383 (*i)->set_block_size (nframes);
1386 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1387 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1388 (*i)->set_block_size (nframes);
1391 set_worst_io_latencies ();
1396 Session::set_default_fade (float steepness, float fade_msecs)
1399 nframes_t fade_frames;
1401 /* Don't allow fade of less 1 frame */
1403 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1410 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1414 default_fade_msecs = fade_msecs;
1415 default_fade_steepness = steepness;
1418 // jlc, WTF is this!
1419 Glib::RWLock::ReaderLock lm (route_lock);
1420 AudioRegion::set_default_fade (steepness, fade_frames);
1425 /* XXX have to do this at some point */
1426 /* foreach region using default fade, reset, then
1427 refill_all_diskstream_buffers ();
1432 struct RouteSorter {
1433 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1434 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1436 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1439 if (r1->fed_by.empty()) {
1440 if (r2->fed_by.empty()) {
1441 /* no ardour-based connections inbound to either route. just use signal order */
1442 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1444 /* r2 has connections, r1 does not; run r1 early */
1448 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1455 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1457 shared_ptr<Route> r2;
1459 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1460 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1464 /* make a copy of the existing list of routes that feed r1 */
1466 set<shared_ptr<Route> > existing = r1->fed_by;
1468 /* for each route that feeds r1, recurse, marking it as feeding
1472 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1475 /* r2 is a route that feeds r1 which somehow feeds base. mark
1476 base as being fed by r2
1479 rbase->fed_by.insert (r2);
1483 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1487 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1491 /* now recurse, so that we can mark base as being fed by
1492 all routes that feed r2
1495 trace_terminal (r2, rbase);
1502 Session::resort_routes ()
1504 /* don't do anything here with signals emitted
1505 by Routes while we are being destroyed.
1508 if (_state_of_the_state & Deletion) {
1515 RCUWriter<RouteList> writer (routes);
1516 shared_ptr<RouteList> r = writer.get_copy ();
1517 resort_routes_using (r);
1518 /* writer goes out of scope and forces update */
1523 Session::resort_routes_using (shared_ptr<RouteList> r)
1525 RouteList::iterator i, j;
1527 for (i = r->begin(); i != r->end(); ++i) {
1529 (*i)->fed_by.clear ();
1531 for (j = r->begin(); j != r->end(); ++j) {
1533 /* although routes can feed themselves, it will
1534 cause an endless recursive descent if we
1535 detect it. so don't bother checking for
1543 if ((*j)->feeds (*i)) {
1544 (*i)->fed_by.insert (*j);
1549 for (i = r->begin(); i != r->end(); ++i) {
1550 trace_terminal (*i, *i);
1557 cerr << "finished route resort\n";
1559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1560 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1567 list<boost::shared_ptr<AudioTrack> >
1568 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1570 char track_name[32];
1571 uint32_t track_id = 0;
1573 uint32_t channels_used = 0;
1575 RouteList new_routes;
1576 list<boost::shared_ptr<AudioTrack> > ret;
1578 /* count existing audio tracks */
1581 shared_ptr<RouteList> r = routes.reader ();
1583 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1584 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1585 if (!(*i)->hidden()) {
1587 channels_used += (*i)->n_inputs();
1593 vector<string> physinputs;
1594 vector<string> physoutputs;
1595 uint32_t nphysical_in;
1596 uint32_t nphysical_out;
1598 _engine.get_physical_outputs (physoutputs);
1599 _engine.get_physical_inputs (physinputs);
1603 /* check for duplicate route names, since we might have pre-existing
1604 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1605 save, close,restart,add new route - first named route is now
1613 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1615 if (route_by_name (track_name) == 0) {
1619 } while (track_id < (UINT_MAX-1));
1621 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1622 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1627 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1628 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1634 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1636 if (track->ensure_io (input_channels, output_channels, false, this)) {
1637 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1638 input_channels, output_channels)
1643 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1647 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1648 port = physinputs[(channels_used+x)%nphysical_in];
1651 if (port.length() && track->connect_input (track->input (x), port, this)) {
1657 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1661 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1662 port = physoutputs[(channels_used+x)%nphysical_out];
1663 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1665 port = _master_out->input (x%_master_out->n_inputs())->name();
1669 if (port.length() && track->connect_output (track->output (x), port, this)) {
1674 channels_used += track->n_inputs ();
1677 vector<string> cports;
1678 uint32_t ni = _control_out->n_inputs();
1680 for (n = 0; n < ni; ++n) {
1681 cports.push_back (_control_out->input(n)->name());
1684 track->set_control_outs (cports);
1687 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1688 track->set_remote_control_id (ntracks());
1690 new_routes.push_back (track);
1691 ret.push_back (track);
1694 catch (failed_constructor &err) {
1695 error << _("Session: could not create new audio track.") << endmsg;
1696 // XXX should we delete the tracks already created?
1704 if (!new_routes.empty()) {
1705 add_routes (new_routes, false);
1706 save_state (_current_snapshot_name);
1713 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1716 uint32_t bus_id = 1;
1721 /* count existing audio busses */
1724 shared_ptr<RouteList> r = routes.reader ();
1726 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1727 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1728 if (!(*i)->hidden()) {
1735 vector<string> physinputs;
1736 vector<string> physoutputs;
1738 _engine.get_physical_outputs (physoutputs);
1739 _engine.get_physical_inputs (physinputs);
1746 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1748 if (route_by_name (bus_name) == 0) {
1752 } while (bus_id < (UINT_MAX-1));
1755 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1757 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1758 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1759 input_channels, output_channels)
1763 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1767 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1768 port = physinputs[((n+x)%n_physical_inputs)];
1771 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1776 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1780 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1781 port = physoutputs[((n+x)%n_physical_outputs)];
1782 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1784 port = _master_out->input (x%_master_out->n_inputs())->name();
1788 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1794 vector<string> cports;
1795 uint32_t ni = _control_out->n_inputs();
1797 for (uint32_t n = 0; n < ni; ++n) {
1798 cports.push_back (_control_out->input(n)->name());
1800 bus->set_control_outs (cports);
1803 ret.push_back (bus);
1807 catch (failed_constructor &err) {
1808 error << _("Session: could not create new audio route.") << endmsg;
1817 add_routes (ret, false);
1818 save_state (_current_snapshot_name);
1826 Session::add_routes (RouteList& new_routes, bool save)
1829 RCUWriter<RouteList> writer (routes);
1830 shared_ptr<RouteList> r = writer.get_copy ();
1831 r->insert (r->end(), new_routes.begin(), new_routes.end());
1832 resort_routes_using (r);
1835 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1837 boost::weak_ptr<Route> wpr (*x);
1839 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1840 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1841 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1842 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1844 if ((*x)->master()) {
1848 if ((*x)->control()) {
1849 _control_out = (*x);
1856 save_state (_current_snapshot_name);
1859 RouteAdded (new_routes); /* EMIT SIGNAL */
1863 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1865 /* need to do this in case we're rolling at the time, to prevent false underruns */
1866 dstream->do_refill_with_alloc();
1869 RCUWriter<DiskstreamList> writer (diskstreams);
1870 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1871 ds->push_back (dstream);
1874 dstream->set_block_size (current_block_size);
1876 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1877 /* this will connect to future changes, and check the current length */
1878 diskstream_playlist_changed (dstream);
1880 dstream->prepare ();
1884 Session::remove_route (shared_ptr<Route> route)
1887 RCUWriter<RouteList> writer (routes);
1888 shared_ptr<RouteList> rs = writer.get_copy ();
1891 /* deleting the master out seems like a dumb
1892 idea, but its more of a UI policy issue
1896 if (route == _master_out) {
1897 _master_out = shared_ptr<Route> ();
1900 if (route == _control_out) {
1901 _control_out = shared_ptr<Route> ();
1903 /* cancel control outs for all routes */
1905 vector<string> empty;
1907 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1908 (*r)->set_control_outs (empty);
1912 update_route_solo_state ();
1914 /* writer goes out of scope, forces route list update */
1917 // FIXME: audio specific
1919 boost::shared_ptr<AudioDiskstream> ds;
1921 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1922 ds = at->audio_diskstream();
1928 RCUWriter<DiskstreamList> dsl (diskstreams);
1929 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1934 find_current_end ();
1936 update_latency_compensation (false, false);
1939 // We need to disconnect the routes inputs and outputs
1940 route->disconnect_inputs(NULL);
1941 route->disconnect_outputs(NULL);
1943 /* get rid of it from the dead wood collection in the route list manager */
1945 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1949 /* try to cause everyone to drop their references */
1951 route->drop_references ();
1953 /* save the new state of the world */
1955 if (save_state (_current_snapshot_name)) {
1956 save_history (_current_snapshot_name);
1961 Session::route_mute_changed (void* src)
1967 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1969 if (solo_update_disabled) {
1975 boost::shared_ptr<Route> route = wpr.lock ();
1978 /* should not happen */
1979 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1983 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1985 shared_ptr<RouteList> r = routes.reader ();
1987 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1989 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1993 /* don't mess with busses */
1995 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2001 /* don't mess with tracks */
2003 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2008 if ((*i) != route &&
2009 ((*i)->mix_group () == 0 ||
2010 (*i)->mix_group () != route->mix_group () ||
2011 !route->mix_group ()->is_active())) {
2013 if ((*i)->soloed()) {
2015 /* if its already soloed, and solo latching is enabled,
2016 then leave it as it is.
2019 if (Config->get_solo_latched()) {
2026 solo_update_disabled = true;
2027 (*i)->set_solo (false, src);
2028 solo_update_disabled = false;
2032 bool something_soloed = false;
2033 bool same_thing_soloed = false;
2034 bool signal = false;
2036 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2037 if ((*i)->soloed()) {
2038 something_soloed = true;
2039 if (dynamic_cast<AudioTrack*>((*i).get())) {
2041 same_thing_soloed = true;
2046 same_thing_soloed = true;
2054 if (something_soloed != currently_soloing) {
2056 currently_soloing = something_soloed;
2059 modify_solo_mute (is_track, same_thing_soloed);
2062 SoloActive (currently_soloing);
2069 Session::update_route_solo_state ()
2072 bool is_track = false;
2073 bool signal = false;
2075 /* caller must hold RouteLock */
2077 /* this is where we actually implement solo by changing
2078 the solo mute setting of each track.
2081 shared_ptr<RouteList> r = routes.reader ();
2083 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2084 if ((*i)->soloed()) {
2086 if (dynamic_cast<AudioTrack*>((*i).get())) {
2093 if (mute != currently_soloing) {
2095 currently_soloing = mute;
2098 if (!is_track && !mute) {
2100 /* nothing is soloed */
2102 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2103 (*i)->set_solo_mute (false);
2113 modify_solo_mute (is_track, mute);
2116 SoloActive (currently_soloing);
2121 Session::modify_solo_mute (bool is_track, bool mute)
2123 shared_ptr<RouteList> r = routes.reader ();
2125 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2129 /* only alter track solo mute */
2131 if (dynamic_cast<AudioTrack*>((*i).get())) {
2132 if ((*i)->soloed()) {
2133 (*i)->set_solo_mute (!mute);
2135 (*i)->set_solo_mute (mute);
2141 /* only alter bus solo mute */
2143 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2145 if ((*i)->soloed()) {
2147 (*i)->set_solo_mute (false);
2151 /* don't mute master or control outs
2152 in response to another bus solo
2155 if ((*i) != _master_out &&
2156 (*i) != _control_out) {
2157 (*i)->set_solo_mute (mute);
2168 Session::catch_up_on_solo ()
2170 /* this is called after set_state() to catch the full solo
2171 state, which can't be correctly determined on a per-route
2172 basis, but needs the global overview that only the session
2175 update_route_solo_state();
2179 Session::route_by_name (string name)
2181 shared_ptr<RouteList> r = routes.reader ();
2183 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2184 if ((*i)->name() == name) {
2189 return shared_ptr<Route> ((Route*) 0);
2193 Session::route_by_id (PBD::ID id)
2195 shared_ptr<RouteList> r = routes.reader ();
2197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2198 if ((*i)->id() == id) {
2203 return shared_ptr<Route> ((Route*) 0);
2207 Session::route_by_remote_id (uint32_t id)
2209 shared_ptr<RouteList> r = routes.reader ();
2211 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2212 if ((*i)->remote_control_id() == id) {
2217 return shared_ptr<Route> ((Route*) 0);
2221 Session::find_current_end ()
2223 if (_state_of_the_state & Loading) {
2227 nframes_t max = get_maximum_extent ();
2229 if (max > end_location->end()) {
2230 end_location->set_end (max);
2232 DurationChanged(); /* EMIT SIGNAL */
2237 Session::get_maximum_extent () const
2242 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2244 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2245 Playlist* pl = (*i)->playlist();
2246 if ((me = pl->get_maximum_extent()) > max) {
2254 boost::shared_ptr<Diskstream>
2255 Session::diskstream_by_name (string name)
2257 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2259 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2260 if ((*i)->name() == name) {
2265 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2268 boost::shared_ptr<Diskstream>
2269 Session::diskstream_by_id (const PBD::ID& id)
2271 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2273 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2274 if ((*i)->id() == id) {
2279 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2282 /* AudioRegion management */
2285 Session::new_region_name (string old)
2287 string::size_type last_period;
2289 string::size_type len = old.length() + 64;
2292 if ((last_period = old.find_last_of ('.')) == string::npos) {
2294 /* no period present - add one explicitly */
2297 last_period = old.length() - 1;
2302 number = atoi (old.substr (last_period+1).c_str());
2306 while (number < (UINT_MAX-1)) {
2308 AudioRegionList::const_iterator i;
2313 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2316 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2317 if (i->second->name() == sbuf) {
2322 if (i == audio_regions.end()) {
2327 if (number != (UINT_MAX-1)) {
2331 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2336 Session::region_name (string& result, string base, bool newlevel) const
2343 Glib::Mutex::Lock lm (region_lock);
2345 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2353 /* XXX this is going to be slow. optimize me later */
2358 string::size_type pos;
2360 pos = base.find_last_of ('.');
2362 /* pos may be npos, but then we just use entire base */
2364 subbase = base.substr (0, pos);
2368 bool name_taken = true;
2371 Glib::Mutex::Lock lm (region_lock);
2373 for (int n = 1; n < 5000; ++n) {
2376 snprintf (buf, sizeof (buf), ".%d", n);
2381 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2382 if (i->second->name() == result) {
2395 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2403 Session::add_region (boost::shared_ptr<Region> region)
2405 boost::shared_ptr<AudioRegion> ar;
2406 boost::shared_ptr<AudioRegion> oar;
2410 Glib::Mutex::Lock lm (region_lock);
2412 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2414 AudioRegionList::iterator x;
2416 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2418 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2420 if (ar->region_list_equivalent (oar)) {
2425 if (x == audio_regions.end()) {
2427 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2429 entry.first = region->id();
2432 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2444 fatal << _("programming error: ")
2445 << X_("unknown region type passed to Session::add_region()")
2452 /* mark dirty because something has changed even if we didn't
2453 add the region to the region list.
2459 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2460 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2461 AudioRegionAdded (ar); /* EMIT SIGNAL */
2466 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2468 boost::shared_ptr<Region> region (weak_region.lock ());
2474 if (what_changed & Region::HiddenChanged) {
2475 /* relay hidden changes */
2476 RegionHiddenChange (region);
2481 Session::remove_region (boost::weak_ptr<Region> weak_region)
2483 AudioRegionList::iterator i;
2484 boost::shared_ptr<Region> region (weak_region.lock ());
2490 boost::shared_ptr<AudioRegion> ar;
2491 bool removed = false;
2494 Glib::Mutex::Lock lm (region_lock);
2496 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2497 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2498 audio_regions.erase (i);
2504 fatal << _("programming error: ")
2505 << X_("unknown region type passed to Session::remove_region()")
2511 /* mark dirty because something has changed even if we didn't
2512 remove the region from the region list.
2518 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2522 boost::shared_ptr<AudioRegion>
2523 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2525 AudioRegionList::iterator i;
2526 boost::shared_ptr<AudioRegion> region;
2527 Glib::Mutex::Lock lm (region_lock);
2529 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2533 if (region->whole_file()) {
2535 if (child->source_equivalent (region)) {
2541 return boost::shared_ptr<AudioRegion> ();
2545 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2547 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2548 (*i)->get_region_list_equivalent_regions (region, result);
2552 Session::destroy_region (boost::shared_ptr<Region> region)
2554 boost::shared_ptr<AudioRegion> aregion;
2556 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2560 if (aregion->playlist()) {
2561 aregion->playlist()->destroy_region (region);
2564 vector<boost::shared_ptr<Source> > srcs;
2566 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2567 srcs.push_back (aregion->source (n));
2570 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2572 if ((*i).use_count() == 1) {
2573 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2576 (afs)->mark_for_remove ();
2579 (*i)->drop_references ();
2587 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2589 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2590 destroy_region (*i);
2596 Session::remove_last_capture ()
2598 list<boost::shared_ptr<Region> > r;
2600 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2602 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2603 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2606 r.insert (r.end(), l.begin(), l.end());
2611 destroy_regions (r);
2616 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2622 /* Source Management */
2625 Session::add_source (boost::shared_ptr<Source> source)
2627 boost::shared_ptr<AudioFileSource> afs;
2629 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2631 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2632 pair<AudioSourceList::iterator,bool> result;
2634 entry.first = source->id();
2638 Glib::Mutex::Lock lm (audio_source_lock);
2639 result = audio_sources.insert (entry);
2642 if (!result.second) {
2643 cerr << "\tNOT inserted ? " << result.second << endl;
2646 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2649 SourceAdded (source); /* EMIT SIGNAL */
2651 cerr << "\tNOT AUDIO FILE\n";
2656 Session::remove_source (boost::weak_ptr<Source> src)
2658 AudioSourceList::iterator i;
2659 boost::shared_ptr<Source> source = src.lock();
2666 Glib::Mutex::Lock lm (audio_source_lock);
2668 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2669 audio_sources.erase (i);
2673 if (!_state_of_the_state & InCleanup) {
2675 /* save state so we don't end up with a session file
2676 referring to non-existent sources.
2679 save_state (_current_snapshot_name);
2682 SourceRemoved(source); /* EMIT SIGNAL */
2685 boost::shared_ptr<Source>
2686 Session::source_by_id (const PBD::ID& id)
2688 Glib::Mutex::Lock lm (audio_source_lock);
2689 AudioSourceList::iterator i;
2690 boost::shared_ptr<Source> source;
2692 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2696 /* XXX search MIDI or other searches here */
2702 Session::peak_path_from_audio_path (string audio_path) const
2707 res += PBD::basename_nosuffix (audio_path);
2714 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2717 string old_basename = PBD::basename_nosuffix (oldname);
2718 string new_legalized = legalize_for_path (newname);
2720 /* note: we know (or assume) the old path is already valid */
2724 /* destructive file sources have a name of the form:
2726 /path/to/Tnnnn-NAME(%[LR])?.wav
2728 the task here is to replace NAME with the new name.
2731 /* find last slash */
2735 string::size_type slash;
2736 string::size_type dash;
2738 if ((slash = path.find_last_of ('/')) == string::npos) {
2742 dir = path.substr (0, slash+1);
2744 /* '-' is not a legal character for the NAME part of the path */
2746 if ((dash = path.find_last_of ('-')) == string::npos) {
2750 prefix = path.substr (slash+1, dash-(slash+1));
2755 path += new_legalized;
2756 path += ".wav"; /* XXX gag me with a spoon */
2760 /* non-destructive file sources have a name of the form:
2762 /path/to/NAME-nnnnn(%[LR])?.wav
2764 the task here is to replace NAME with the new name.
2769 string::size_type slash;
2770 string::size_type dash;
2771 string::size_type postfix;
2773 /* find last slash */
2775 if ((slash = path.find_last_of ('/')) == string::npos) {
2779 dir = path.substr (0, slash+1);
2781 /* '-' is not a legal character for the NAME part of the path */
2783 if ((dash = path.find_last_of ('-')) == string::npos) {
2787 suffix = path.substr (dash+1);
2789 // Suffix is now everything after the dash. Now we need to eliminate
2790 // the nnnnn part, which is done by either finding a '%' or a '.'
2792 postfix = suffix.find_last_of ("%");
2793 if (postfix == string::npos) {
2794 postfix = suffix.find_last_of ('.');
2797 if (postfix != string::npos) {
2798 suffix = suffix.substr (postfix);
2800 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2804 const uint32_t limit = 10000;
2805 char buf[PATH_MAX+1];
2807 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2809 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2811 if (access (buf, F_OK) != 0) {
2819 error << "FATAL ERROR! Could not find a " << endl;
2828 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2832 char buf[PATH_MAX+1];
2833 const uint32_t limit = 10000;
2837 legalized = legalize_for_path (name);
2839 /* find a "version" of the file name that doesn't exist in
2840 any of the possible directories.
2843 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2845 vector<space_and_path>::iterator i;
2846 uint32_t existing = 0;
2848 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2852 spath += sound_dir (false);
2856 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2857 } else if (nchan == 2) {
2859 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2861 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2863 } else if (nchan < 26) {
2864 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2866 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2874 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2875 } else if (nchan == 2) {
2877 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2879 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2881 } else if (nchan < 26) {
2882 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2884 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2888 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2894 if (existing == 0) {
2899 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2900 throw failed_constructor();
2904 /* we now have a unique name for the file, but figure out where to
2910 spath = discover_best_sound_dir ();
2912 string::size_type pos = foo.find_last_of ('/');
2914 if (pos == string::npos) {
2917 spath += foo.substr (pos + 1);
2923 boost::shared_ptr<AudioFileSource>
2924 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2926 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2927 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2930 /* Playlist management */
2933 Session::playlist_by_name (string name)
2935 Glib::Mutex::Lock lm (playlist_lock);
2936 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2937 if ((*i)->name() == name) {
2941 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2942 if ((*i)->name() == name) {
2950 Session::add_playlist (Playlist* playlist)
2952 if (playlist->hidden()) {
2957 Glib::Mutex::Lock lm (playlist_lock);
2958 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2959 playlists.insert (playlists.begin(), playlist);
2961 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2962 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2968 PlaylistAdded (playlist); /* EMIT SIGNAL */
2972 Session::track_playlist (Playlist* pl, bool inuse)
2974 PlaylistList::iterator x;
2977 Glib::Mutex::Lock lm (playlist_lock);
2980 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2982 unused_playlists.insert (pl);
2984 if ((x = playlists.find (pl)) != playlists.end()) {
2985 playlists.erase (x);
2990 //cerr << "shifting playlist to used: " << pl->name() << endl;
2992 playlists.insert (pl);
2994 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2995 unused_playlists.erase (x);
3002 Session::remove_playlist (Playlist* playlist)
3004 if (_state_of_the_state & Deletion) {
3009 Glib::Mutex::Lock lm (playlist_lock);
3010 // cerr << "removing playlist: " << playlist->name() << endl;
3012 PlaylistList::iterator i;
3014 i = find (playlists.begin(), playlists.end(), playlist);
3016 if (i != playlists.end()) {
3017 playlists.erase (i);
3020 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3021 if (i != unused_playlists.end()) {
3022 unused_playlists.erase (i);
3029 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3033 Session::set_audition (boost::shared_ptr<Region> r)
3035 pending_audition_region = r;
3036 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3037 schedule_butler_transport_work ();
3041 Session::audition_playlist ()
3043 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3044 ev->region.reset ();
3049 Session::non_realtime_set_audition ()
3051 if (!pending_audition_region) {
3052 auditioner->audition_current_playlist ();
3054 auditioner->audition_region (pending_audition_region);
3055 pending_audition_region.reset ();
3057 AuditionActive (true); /* EMIT SIGNAL */
3061 Session::audition_region (boost::shared_ptr<Region> r)
3063 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3069 Session::cancel_audition ()
3071 if (auditioner->active()) {
3072 auditioner->cancel_audition ();
3073 AuditionActive (false); /* EMIT SIGNAL */
3078 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3080 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3084 Session::remove_empty_sounds ()
3086 PathScanner scanner;
3088 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3090 Glib::Mutex::Lock lm (audio_source_lock);
3092 regex_t compiled_tape_track_pattern;
3095 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3099 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3101 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3105 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3107 /* never remove files that appear to be a tape track */
3109 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3114 if (AudioFileSource::is_empty (*this, *(*i))) {
3116 unlink ((*i)->c_str());
3118 string peak_path = peak_path_from_audio_path (**i);
3119 unlink (peak_path.c_str());
3125 delete possible_audiofiles;
3129 Session::is_auditioning () const
3131 /* can be called before we have an auditioner object */
3133 return auditioner->active();
3140 Session::set_all_solo (bool yn)
3142 shared_ptr<RouteList> r = routes.reader ();
3144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3145 if (!(*i)->hidden()) {
3146 (*i)->set_solo (yn, this);
3154 Session::set_all_mute (bool yn)
3156 shared_ptr<RouteList> r = routes.reader ();
3158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3159 if (!(*i)->hidden()) {
3160 (*i)->set_mute (yn, this);
3168 Session::n_diskstreams () const
3172 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3174 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3175 if (!(*i)->hidden()) {
3183 Session::graph_reordered ()
3185 /* don't do this stuff if we are setting up connections
3186 from a set_state() call.
3189 if (_state_of_the_state & InitialConnecting) {
3195 /* force all diskstreams to update their capture offset values to
3196 reflect any changes in latencies within the graph.
3199 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3201 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3202 (*i)->set_capture_offset ();
3207 Session::record_disenable_all ()
3209 record_enable_change_all (false);
3213 Session::record_enable_all ()
3215 record_enable_change_all (true);
3219 Session::record_enable_change_all (bool yn)
3221 shared_ptr<RouteList> r = routes.reader ();
3223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3226 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3227 at->set_record_enable (yn, this);
3231 /* since we don't keep rec-enable state, don't mark session dirty */
3235 Session::add_redirect (Redirect* redirect)
3239 PortInsert* port_insert;
3240 PluginInsert* plugin_insert;
3242 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3243 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3244 _port_inserts.insert (_port_inserts.begin(), port_insert);
3245 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3246 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3248 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3251 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3252 _sends.insert (_sends.begin(), send);
3254 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3258 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3264 Session::remove_redirect (Redirect* redirect)
3268 PortInsert* port_insert;
3269 PluginInsert* plugin_insert;
3271 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3272 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3273 _port_inserts.remove (port_insert);
3274 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3275 _plugin_inserts.remove (plugin_insert);
3277 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3280 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3281 _sends.remove (send);
3283 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3291 Session::available_capture_duration ()
3293 float sample_bytes_on_disk;
3295 switch (Config->get_native_file_data_format()) {
3297 sample_bytes_on_disk = 4;
3301 sample_bytes_on_disk = 3;
3305 double scale = 4096.0 / sample_bytes_on_disk;
3307 if (_total_free_4k_blocks * scale > (double) max_frames) {
3311 return (nframes_t) floor (_total_free_4k_blocks * scale);
3315 Session::add_connection (ARDOUR::Connection* connection)
3318 Glib::Mutex::Lock guard (connection_lock);
3319 _connections.push_back (connection);
3322 ConnectionAdded (connection); /* EMIT SIGNAL */
3328 Session::remove_connection (ARDOUR::Connection* connection)
3330 bool removed = false;
3333 Glib::Mutex::Lock guard (connection_lock);
3334 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3336 if (i != _connections.end()) {
3337 _connections.erase (i);
3343 ConnectionRemoved (connection); /* EMIT SIGNAL */
3349 ARDOUR::Connection *
3350 Session::connection_by_name (string name) const
3352 Glib::Mutex::Lock lm (connection_lock);
3354 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3355 if ((*i)->name() == name) {
3364 Session::tempo_map_changed (Change ignored)
3371 Session::ensure_passthru_buffers (uint32_t howmany)
3373 while (howmany > _passthru_buffers.size()) {
3375 #ifdef NO_POSIX_MEMALIGN
3376 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3378 posix_memalign((void **)&p,16,current_block_size * 4);
3380 _passthru_buffers.push_back (p);
3384 #ifdef NO_POSIX_MEMALIGN
3385 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3387 posix_memalign((void **)&p,16,current_block_size * 4);
3389 memset (p, 0, sizeof (Sample) * current_block_size);
3390 _silent_buffers.push_back (p);
3394 #ifdef NO_POSIX_MEMALIGN
3395 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3397 posix_memalign((void **)&p,16,current_block_size * 4);
3399 memset (p, 0, sizeof (Sample) * current_block_size);
3400 _send_buffers.push_back (p);
3403 allocate_pan_automation_buffers (current_block_size, howmany, false);
3407 Session::next_send_name ()
3410 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3415 Session::next_insert_name ()
3418 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3422 /* Named Selection management */
3425 Session::named_selection_by_name (string name)
3427 Glib::Mutex::Lock lm (named_selection_lock);
3428 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3429 if ((*i)->name == name) {
3437 Session::add_named_selection (NamedSelection* named_selection)
3440 Glib::Mutex::Lock lm (named_selection_lock);
3441 named_selections.insert (named_selections.begin(), named_selection);
3446 NamedSelectionAdded (); /* EMIT SIGNAL */
3450 Session::remove_named_selection (NamedSelection* named_selection)
3452 bool removed = false;
3455 Glib::Mutex::Lock lm (named_selection_lock);
3457 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3459 if (i != named_selections.end()) {
3461 named_selections.erase (i);
3468 NamedSelectionRemoved (); /* EMIT SIGNAL */
3473 Session::reset_native_file_format ()
3475 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3477 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3478 (*i)->reset_write_sources (false);
3483 Session::route_name_unique (string n) const
3485 shared_ptr<RouteList> r = routes.reader ();
3487 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3488 if ((*i)->name() == n) {
3497 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3499 return fs->move_to_trash (dead_sound_dir_name);
3503 Session::n_playlists () const
3505 Glib::Mutex::Lock lm (playlist_lock);
3506 return playlists.size();
3510 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3512 if (!force && howmany <= _npan_buffers) {
3516 if (_pan_automation_buffer) {
3518 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3519 delete [] _pan_automation_buffer[i];
3522 delete [] _pan_automation_buffer;
3525 _pan_automation_buffer = new pan_t*[howmany];
3527 for (uint32_t i = 0; i < howmany; ++i) {
3528 _pan_automation_buffer[i] = new pan_t[nframes];
3531 _npan_buffers = howmany;
3535 Session::freeze (InterThreadInfo& itt)
3537 shared_ptr<RouteList> r = routes.reader ();
3539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3543 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3544 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3555 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3556 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3560 boost::shared_ptr<AudioFileSource> fsource;
3562 char buf[PATH_MAX+1];
3566 nframes_t this_chunk;
3568 vector<Sample*> buffers;
3570 // any bigger than this seems to cause stack overflows in called functions
3571 const nframes_t chunk_size = (128 * 1024)/4;
3573 g_atomic_int_set (&processing_prohibited, 1);
3575 /* call tree *MUST* hold route_lock */
3577 if ((playlist = track.diskstream()->playlist()) == 0) {
3581 /* external redirects will be a problem */
3583 if (track.has_external_redirects()) {
3587 nchans = track.audio_diskstream()->n_channels();
3589 dir = discover_best_sound_dir ();
3591 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3593 for (x = 0; x < 99999; ++x) {
3594 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3595 if (access (buf, F_OK) != 0) {
3601 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3606 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3609 catch (failed_constructor& err) {
3610 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3614 srcs.push_back (fsource);
3617 /* XXX need to flush all redirects */
3622 /* create a set of reasonably-sized buffers */
3624 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3626 #ifdef NO_POSIX_MEMALIGN
3627 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3629 posix_memalign((void **)&b,16,chunk_size * 4);
3631 buffers.push_back (b);
3634 while (to_do && !itt.cancel) {
3636 this_chunk = min (to_do, chunk_size);
3638 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3643 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3644 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3647 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3653 start += this_chunk;
3654 to_do -= this_chunk;
3656 itt.progress = (float) (1.0 - ((double) to_do / len));
3665 xnow = localtime (&now);
3667 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3668 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3671 afs->update_header (position, *xnow, now);
3675 /* build peakfile for new source */
3677 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3678 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3680 afs->build_peaks ();
3684 /* construct a region to represent the bounced material */
3686 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3687 region_name_from_path (srcs.front()->name()));
3694 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3695 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3698 afs->mark_for_remove ();
3701 (*src)->drop_references ();
3705 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3709 g_atomic_int_set (&processing_prohibited, 0);
3717 Session::get_silent_buffers (uint32_t howmany)
3719 for (uint32_t i = 0; i < howmany; ++i) {
3720 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3722 return _silent_buffers;
3726 Session::ntracks () const
3729 shared_ptr<RouteList> r = routes.reader ();
3731 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3732 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3741 Session::nbusses () const
3744 shared_ptr<RouteList> r = routes.reader ();
3746 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3747 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3756 Session::add_curve(Curve *curve)
3758 curves[curve->id()] = curve;
3762 Session::add_automation_list(AutomationList *al)
3764 automation_lists[al->id()] = al;