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>
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");
90 Session::compute_peak_t Session::compute_peak = 0;
91 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
92 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
93 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::StartTimeChanged;
100 sigc::signal<void> Session::EndTimeChanged;
103 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
106 char buf[PATH_MAX+1];
110 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
111 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
117 /* check to see if it exists, and what it is */
119 if (stat (str.c_str(), &statbuf)) {
120 if (errno == ENOENT) {
123 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
131 /* it exists, so it must either be the name
132 of the directory, or the name of the statefile
136 if (S_ISDIR (statbuf.st_mode)) {
138 string::size_type slash = str.find_last_of ('/');
140 if (slash == string::npos) {
142 /* a subdirectory of cwd, so statefile should be ... */
148 tmp += _statefile_suffix;
152 if (stat (tmp.c_str(), &statbuf)) {
153 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
163 /* some directory someplace in the filesystem.
164 the snapshot name is the directory name
169 snapshot = str.substr (slash+1);
173 } else if (S_ISREG (statbuf.st_mode)) {
175 string::size_type slash = str.find_last_of ('/');
176 string::size_type suffix;
178 /* remove the suffix */
180 if (slash != string::npos) {
181 snapshot = str.substr (slash+1);
186 suffix = snapshot.find (_statefile_suffix);
188 if (suffix == string::npos) {
189 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
195 snapshot = snapshot.substr (0, suffix);
197 if (slash == string::npos) {
199 /* we must be in the directory where the
200 statefile lives. get it using cwd().
203 char cwd[PATH_MAX+1];
205 if (getcwd (cwd, sizeof (cwd)) == 0) {
206 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
215 /* full path to the statefile */
217 path = str.substr (0, slash);
222 /* what type of file is it? */
223 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
229 /* its the name of a new directory. get the name
233 string::size_type slash = str.find_last_of ('/');
235 if (slash == string::npos) {
237 /* no slash, just use the name, but clean it up */
239 path = legalize_for_path (str);
245 snapshot = str.substr (slash+1);
252 Session::Session (AudioEngine &eng,
254 string snapshot_name,
255 string* mix_template)
258 _mmc_port (default_mmc_port),
259 _mtc_port (default_mtc_port),
260 _midi_port (default_midi_port),
261 pending_events (2048),
262 midi_requests (128), // the size of this should match the midi request pool size
263 diskstreams (new DiskstreamList),
264 routes (new RouteList),
265 auditioner ((Auditioner*) 0),
271 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
273 n_physical_outputs = _engine.n_physical_outputs();
274 n_physical_inputs = _engine.n_physical_inputs();
276 first_stage_init (fullpath, snapshot_name);
278 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
280 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
281 cerr << "create failed\n";
282 throw failed_constructor ();
286 if (second_stage_init (new_session)) {
287 cerr << "2nd state failed\n";
288 throw failed_constructor ();
291 store_recent_sessions(_name, _path);
293 bool was_dirty = dirty();
295 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
297 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
300 DirtyChanged (); /* EMIT SIGNAL */
304 Session::Session (AudioEngine &eng,
306 string snapshot_name,
307 AutoConnectOption input_ac,
308 AutoConnectOption output_ac,
309 uint32_t control_out_channels,
310 uint32_t master_out_channels,
311 uint32_t requested_physical_in,
312 uint32_t requested_physical_out,
313 nframes_t initial_length)
316 _mmc_port (default_mmc_port),
317 _mtc_port (default_mtc_port),
318 _midi_port (default_midi_port),
319 pending_events (2048),
321 diskstreams (new DiskstreamList),
322 routes (new RouteList),
328 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
330 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
331 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
333 first_stage_init (fullpath, snapshot_name);
335 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
337 if (create (new_session, 0, initial_length)) {
338 throw failed_constructor ();
342 if (control_out_channels) {
343 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
350 if (master_out_channels) {
351 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
357 /* prohibit auto-connect to master, because there isn't one */
358 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
361 Config->set_input_auto_connect (input_ac);
362 Config->set_output_auto_connect (output_ac);
364 if (second_stage_init (new_session)) {
365 throw failed_constructor ();
368 store_recent_sessions(_name, _path);
370 bool was_dirty = dirty ();
372 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
375 DirtyChanged (); /* EMIT SIGNAL */
381 /* if we got to here, leaving pending capture state around
385 remove_pending_capture_state ();
387 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
388 _engine.remove_session ();
390 GoingAway (); /* EMIT SIGNAL */
396 /* clear history so that no references to objects are held any more */
400 /* clear state tree so that no references to objects are held any more */
406 terminate_butler_thread ();
407 terminate_midi_thread ();
409 if (click_data && click_data != default_click) {
410 delete [] click_data;
413 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
414 delete [] click_emphasis_data;
419 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
423 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
427 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
431 AudioDiskstream::free_working_buffers();
433 #undef TRACK_DESTRUCTION
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete named selections\n";
436 #endif /* TRACK_DESTRUCTION */
437 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
438 NamedSelectionList::iterator tmp;
447 #ifdef TRACK_DESTRUCTION
448 cerr << "delete playlists\n";
449 #endif /* TRACK_DESTRUCTION */
450 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
451 PlaylistList::iterator tmp;
461 #ifdef TRACK_DESTRUCTION
462 cerr << "delete audio regions\n";
463 #endif /* TRACK_DESTRUCTION */
465 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
466 i->second->drop_references ();
469 audio_regions.clear ();
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete routes\n";
473 #endif /* TRACK_DESTRUCTION */
475 RCUWriter<RouteList> writer (routes);
476 boost::shared_ptr<RouteList> r = writer.get_copy ();
477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
478 (*i)->drop_references ();
481 /* writer goes out of scope and updates master */
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete diskstreams\n";
488 #endif /* TRACK_DESTRUCTION */
490 RCUWriter<DiskstreamList> dwriter (diskstreams);
491 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
492 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
493 (*i)->drop_references ();
497 diskstreams.flush ();
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete audio sources\n";
501 #endif /* TRACK_DESTRUCTION */
502 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
503 AudioSourceList::iterator tmp;
508 i->second->drop_references ();
513 audio_sources.clear ();
515 #ifdef TRACK_DESTRUCTION
516 cerr << "delete mix groups\n";
517 #endif /* TRACK_DESTRUCTION */
518 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
519 list<RouteGroup*>::iterator tmp;
529 #ifdef TRACK_DESTRUCTION
530 cerr << "delete edit groups\n";
531 #endif /* TRACK_DESTRUCTION */
532 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
533 list<RouteGroup*>::iterator tmp;
543 #ifdef TRACK_DESTRUCTION
544 cerr << "delete connections\n";
545 #endif /* TRACK_DESTRUCTION */
546 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
547 ConnectionList::iterator tmp;
557 if (butler_mixdown_buffer) {
558 delete [] butler_mixdown_buffer;
561 if (butler_gain_buffer) {
562 delete [] butler_gain_buffer;
565 Crossfade::set_buffer_size (0);
573 Session::set_worst_io_latencies ()
575 _worst_output_latency = 0;
576 _worst_input_latency = 0;
578 if (!_engine.connected()) {
582 boost::shared_ptr<RouteList> r = routes.reader ();
584 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
585 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
586 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
591 Session::when_engine_running ()
593 string first_physical_output;
595 /* we don't want to run execute this again */
597 first_time_running.disconnect ();
599 set_block_size (_engine.frames_per_cycle());
600 set_frame_rate (_engine.frame_rate());
602 Config->map_parameters (mem_fun (*this, &Session::config_changed));
604 /* every time we reconnect, recompute worst case output latencies */
606 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
608 if (synced_to_jack()) {
609 _engine.transport_stop ();
612 if (Config->get_jack_time_master()) {
613 _engine.transport_locate (_transport_frame);
621 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
623 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
625 /* existing state for Click */
627 if (_click_io->set_state (*child->children().front()) == 0) {
629 _clicking = Config->get_clicking ();
633 error << _("could not setup Click I/O") << endmsg;
639 /* default state for Click */
641 first_physical_output = _engine.get_nth_physical_output (0);
643 if (first_physical_output.length()) {
644 if (_click_io->add_output_port (first_physical_output, this)) {
645 // relax, even though its an error
647 _clicking = Config->get_clicking ();
653 catch (failed_constructor& err) {
654 error << _("cannot setup Click I/O") << endmsg;
657 set_worst_io_latencies ();
660 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
663 if (auditioner == 0) {
665 /* we delay creating the auditioner till now because
666 it makes its own connections to ports named
667 in the ARDOUR_RC config file. the engine has
668 to be running for this to work.
672 auditioner.reset (new Auditioner (*this));
675 catch (failed_constructor& err) {
676 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
680 /* Create a set of Connection objects that map
681 to the physical outputs currently available
686 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
688 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
690 Connection* c = new OutputConnection (buf, true);
693 c->add_connection (0, _engine.get_nth_physical_output (np));
698 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
700 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
702 Connection* c = new InputConnection (buf, true);
705 c->add_connection (0, _engine.get_nth_physical_input (np));
712 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
714 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
716 Connection* c = new OutputConnection (buf, true);
720 c->add_connection (0, _engine.get_nth_physical_output (np));
721 c->add_connection (1, _engine.get_nth_physical_output (np+1));
726 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
728 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
730 Connection* c = new InputConnection (buf, true);
734 c->add_connection (0, _engine.get_nth_physical_input (np));
735 c->add_connection (1, _engine.get_nth_physical_input (np+1));
744 /* create master/control ports */
749 /* force the master to ignore any later call to this */
751 if (_master_out->pending_state_node) {
752 _master_out->ports_became_legal();
755 /* no panner resets till we are through */
757 _master_out->defer_pan_reset ();
759 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
760 if (_master_out->add_input_port ("", this)) {
761 error << _("cannot setup master inputs")
767 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
768 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
769 error << _("cannot setup master outputs")
776 _master_out->allow_pan_reset ();
780 Connection* c = new OutputConnection (_("Master Out"), true);
782 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
784 c->add_connection ((int) n, _master_out->input(n)->name());
791 /* catch up on send+insert cnts */
795 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
798 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
799 if (id > insert_cnt) {
807 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
810 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
817 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
819 /* hook us up to the engine */
821 _engine.set_session (this);
826 osc->set_session (*this);
829 _state_of_the_state = Clean;
831 DirtyChanged (); /* EMIT SIGNAL */
835 Session::hookup_io ()
837 /* stop graph reordering notifications from
838 causing resorts, etc.
841 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
843 /* Tell all IO objects to create their ports */
850 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
851 if (_control_out->add_input_port ("", this)) {
852 error << _("cannot setup control inputs")
858 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
859 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
860 error << _("cannot set up master outputs")
868 /* Tell all IO objects to connect themselves together */
870 IO::enable_connecting ();
872 /* Now reset all panners */
874 IO::reset_panners ();
876 /* Anyone who cares about input state, wake up and do something */
878 IOConnectionsComplete (); /* EMIT SIGNAL */
880 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
882 /* now handle the whole enchilada as if it was one
888 /* update mixer solo state */
894 Session::playlist_length_changed (Playlist* pl)
896 /* we can't just increase end_location->end() if pl->get_maximum_extent()
897 if larger. if the playlist used to be the longest playlist,
898 and its now shorter, we have to decrease end_location->end(). hence,
899 we have to iterate over all diskstreams and check the
900 playlists currently in use.
906 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
910 if ((playlist = dstream->playlist()) != 0) {
911 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
914 /* see comment in playlist_length_changed () */
919 Session::record_enabling_legal () const
921 /* this used to be in here, but survey says.... we don't need to restrict it */
922 // if (record_status() == Recording) {
926 if (Config->get_all_safe()) {
933 Session::reset_input_monitor_state ()
935 if (transport_rolling()) {
937 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
939 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
940 if ((*i)->record_enabled ()) {
941 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
942 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
946 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
948 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
949 if ((*i)->record_enabled ()) {
950 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
951 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
958 Session::auto_punch_start_changed (Location* location)
960 replace_event (Event::PunchIn, location->start());
962 if (get_record_enabled() && Config->get_punch_in()) {
963 /* capture start has been changed, so save new pending state */
964 save_state ("", true);
969 Session::auto_punch_end_changed (Location* location)
971 nframes_t when_to_stop = location->end();
972 // when_to_stop += _worst_output_latency + _worst_input_latency;
973 replace_event (Event::PunchOut, when_to_stop);
977 Session::auto_punch_changed (Location* location)
979 nframes_t when_to_stop = location->end();
981 replace_event (Event::PunchIn, location->start());
982 //when_to_stop += _worst_output_latency + _worst_input_latency;
983 replace_event (Event::PunchOut, when_to_stop);
987 Session::auto_loop_changed (Location* location)
989 replace_event (Event::AutoLoop, location->end(), location->start());
991 if (transport_rolling() && play_loop) {
993 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
995 if (_transport_frame > location->end()) {
996 // relocate to beginning of loop
997 clear_events (Event::LocateRoll);
999 request_locate (location->start(), true);
1002 else if (Config->get_seamless_loop() && !loop_changing) {
1004 // schedule a locate-roll to refill the diskstreams at the
1005 // previous loop end
1006 loop_changing = true;
1008 if (location->end() > last_loopend) {
1009 clear_events (Event::LocateRoll);
1010 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1017 last_loopend = location->end();
1022 Session::set_auto_punch_location (Location* location)
1026 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1027 auto_punch_start_changed_connection.disconnect();
1028 auto_punch_end_changed_connection.disconnect();
1029 auto_punch_changed_connection.disconnect();
1030 existing->set_auto_punch (false, this);
1031 remove_event (existing->start(), Event::PunchIn);
1032 clear_events (Event::PunchOut);
1033 auto_punch_location_changed (0);
1038 if (location == 0) {
1042 if (location->end() <= location->start()) {
1043 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1047 auto_punch_start_changed_connection.disconnect();
1048 auto_punch_end_changed_connection.disconnect();
1049 auto_punch_changed_connection.disconnect();
1051 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1052 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1053 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1055 location->set_auto_punch (true, this);
1056 auto_punch_location_changed (location);
1060 Session::set_auto_loop_location (Location* location)
1064 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1065 auto_loop_start_changed_connection.disconnect();
1066 auto_loop_end_changed_connection.disconnect();
1067 auto_loop_changed_connection.disconnect();
1068 existing->set_auto_loop (false, this);
1069 remove_event (existing->end(), Event::AutoLoop);
1070 auto_loop_location_changed (0);
1075 if (location == 0) {
1079 if (location->end() <= location->start()) {
1080 error << _("Session: you can't use a mark for auto loop") << endmsg;
1084 last_loopend = location->end();
1086 auto_loop_start_changed_connection.disconnect();
1087 auto_loop_end_changed_connection.disconnect();
1088 auto_loop_changed_connection.disconnect();
1090 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1091 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1092 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1094 location->set_auto_loop (true, this);
1095 auto_loop_location_changed (location);
1099 Session::locations_added (Location* ignored)
1105 Session::locations_changed ()
1107 _locations.apply (*this, &Session::handle_locations_changed);
1111 Session::handle_locations_changed (Locations::LocationList& locations)
1113 Locations::LocationList::iterator i;
1115 bool set_loop = false;
1116 bool set_punch = false;
1118 for (i = locations.begin(); i != locations.end(); ++i) {
1122 if (location->is_auto_punch()) {
1123 set_auto_punch_location (location);
1126 if (location->is_auto_loop()) {
1127 set_auto_loop_location (location);
1134 set_auto_loop_location (0);
1137 set_auto_punch_location (0);
1144 Session::enable_record ()
1146 /* XXX really atomic compare+swap here */
1147 if (g_atomic_int_get (&_record_status) != Recording) {
1148 g_atomic_int_set (&_record_status, Recording);
1149 _last_record_location = _transport_frame;
1150 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1152 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1153 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1154 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1155 if ((*i)->record_enabled ()) {
1156 (*i)->monitor_input (true);
1161 RecordStateChanged ();
1166 Session::disable_record (bool rt_context, bool force)
1170 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1172 if (!Config->get_latched_record_enable () || force) {
1173 g_atomic_int_set (&_record_status, Disabled);
1175 if (rs == Recording) {
1176 g_atomic_int_set (&_record_status, Enabled);
1180 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1182 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1185 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1186 if ((*i)->record_enabled ()) {
1187 (*i)->monitor_input (false);
1192 RecordStateChanged (); /* emit signal */
1195 remove_pending_capture_state ();
1201 Session::step_back_from_record ()
1203 g_atomic_int_set (&_record_status, Enabled);
1205 if (Config->get_monitoring_model() == HardwareMonitoring) {
1206 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1208 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1209 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1210 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1211 (*i)->monitor_input (false);
1218 Session::maybe_enable_record ()
1220 g_atomic_int_set (&_record_status, Enabled);
1222 /* XXX this save should really happen in another thread. its needed so that
1223 pending capture state can be recovered if we crash.
1226 save_state ("", true);
1228 if (_transport_speed) {
1229 if (!Config->get_punch_in()) {
1233 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1234 RecordStateChanged (); /* EMIT SIGNAL */
1241 Session::audible_frame () const
1247 /* the first of these two possible settings for "offset"
1248 mean that the audible frame is stationary until
1249 audio emerges from the latency compensation
1252 the second means that the audible frame is stationary
1253 until audio would emerge from a physical port
1254 in the absence of any plugin latency compensation
1257 offset = _worst_output_latency;
1259 if (offset > current_block_size) {
1260 offset -= current_block_size;
1262 /* XXX is this correct? if we have no external
1263 physical connections and everything is internal
1264 then surely this is zero? still, how
1265 likely is that anyway?
1267 offset = current_block_size;
1270 if (synced_to_jack()) {
1271 tf = _engine.transport_frame();
1273 tf = _transport_frame;
1276 if (_transport_speed == 0) {
1286 if (!non_realtime_work_pending()) {
1290 /* take latency into account */
1299 Session::set_frame_rate (nframes_t frames_per_second)
1301 /** \fn void Session::set_frame_size(nframes_t)
1302 the AudioEngine object that calls this guarantees
1303 that it will not be called while we are also in
1304 ::process(). Its fine to do things that block
1308 _base_frame_rate = frames_per_second;
1312 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1314 // XXX we need some equivalent to this, somehow
1315 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1319 /* XXX need to reset/reinstantiate all LADSPA plugins */
1323 Session::set_block_size (nframes_t nframes)
1325 /* the AudioEngine guarantees
1326 that it will not be called while we are also in
1327 ::process(). It is therefore fine to do things that block
1332 vector<Sample*>::iterator i;
1335 current_block_size = nframes;
1337 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1341 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1345 _passthru_buffers.clear ();
1346 _silent_buffers.clear ();
1348 ensure_passthru_buffers (np);
1350 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1354 #ifdef NO_POSIX_MEMALIGN
1355 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1357 posix_memalign((void **)&buf,16,current_block_size * 4);
1361 memset (*i, 0, sizeof (Sample) * current_block_size);
1365 if (_gain_automation_buffer) {
1366 delete [] _gain_automation_buffer;
1368 _gain_automation_buffer = new gain_t[nframes];
1370 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1372 boost::shared_ptr<RouteList> r = routes.reader ();
1374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1375 (*i)->set_block_size (nframes);
1378 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1379 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1380 (*i)->set_block_size (nframes);
1383 set_worst_io_latencies ();
1388 Session::set_default_fade (float steepness, float fade_msecs)
1391 nframes_t fade_frames;
1393 /* Don't allow fade of less 1 frame */
1395 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1402 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1406 default_fade_msecs = fade_msecs;
1407 default_fade_steepness = steepness;
1410 // jlc, WTF is this!
1411 Glib::RWLock::ReaderLock lm (route_lock);
1412 AudioRegion::set_default_fade (steepness, fade_frames);
1417 /* XXX have to do this at some point */
1418 /* foreach region using default fade, reset, then
1419 refill_all_diskstream_buffers ();
1424 struct RouteSorter {
1425 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1426 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1428 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1431 if (r1->fed_by.empty()) {
1432 if (r2->fed_by.empty()) {
1433 /* no ardour-based connections inbound to either route. just use signal order */
1434 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1436 /* r2 has connections, r1 does not; run r1 early */
1440 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1447 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1449 shared_ptr<Route> r2;
1451 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1452 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1456 /* make a copy of the existing list of routes that feed r1 */
1458 set<shared_ptr<Route> > existing = r1->fed_by;
1460 /* for each route that feeds r1, recurse, marking it as feeding
1464 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1467 /* r2 is a route that feeds r1 which somehow feeds base. mark
1468 base as being fed by r2
1471 rbase->fed_by.insert (r2);
1475 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1479 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1483 /* now recurse, so that we can mark base as being fed by
1484 all routes that feed r2
1487 trace_terminal (r2, rbase);
1494 Session::resort_routes ()
1496 /* don't do anything here with signals emitted
1497 by Routes while we are being destroyed.
1500 if (_state_of_the_state & Deletion) {
1507 RCUWriter<RouteList> writer (routes);
1508 shared_ptr<RouteList> r = writer.get_copy ();
1509 resort_routes_using (r);
1510 /* writer goes out of scope and forces update */
1515 Session::resort_routes_using (shared_ptr<RouteList> r)
1517 RouteList::iterator i, j;
1519 for (i = r->begin(); i != r->end(); ++i) {
1521 (*i)->fed_by.clear ();
1523 for (j = r->begin(); j != r->end(); ++j) {
1525 /* although routes can feed themselves, it will
1526 cause an endless recursive descent if we
1527 detect it. so don't bother checking for
1535 if ((*j)->feeds (*i)) {
1536 (*i)->fed_by.insert (*j);
1541 for (i = r->begin(); i != r->end(); ++i) {
1542 trace_terminal (*i, *i);
1549 cerr << "finished route resort\n";
1551 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1552 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1559 list<boost::shared_ptr<AudioTrack> >
1560 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1562 char track_name[32];
1563 uint32_t track_id = 0;
1565 uint32_t channels_used = 0;
1567 RouteList new_routes;
1568 list<boost::shared_ptr<AudioTrack> > ret;
1570 /* count existing audio tracks */
1573 shared_ptr<RouteList> r = routes.reader ();
1575 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1576 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1577 if (!(*i)->hidden()) {
1579 channels_used += (*i)->n_inputs();
1585 vector<string> physinputs;
1586 vector<string> physoutputs;
1587 uint32_t nphysical_in;
1588 uint32_t nphysical_out;
1590 _engine.get_physical_outputs (physoutputs);
1591 _engine.get_physical_inputs (physinputs);
1595 /* check for duplicate route names, since we might have pre-existing
1596 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1597 save, close,restart,add new route - first named route is now
1605 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1607 if (route_by_name (track_name) == 0) {
1611 } while (track_id < (UINT_MAX-1));
1613 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1614 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1619 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1620 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1626 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1628 if (track->ensure_io (input_channels, output_channels, false, this)) {
1629 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1630 input_channels, output_channels)
1635 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1639 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1640 port = physinputs[(channels_used+x)%nphysical_in];
1643 if (port.length() && track->connect_input (track->input (x), port, this)) {
1649 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1653 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1654 port = physoutputs[(channels_used+x)%nphysical_out];
1655 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1657 port = _master_out->input (x%_master_out->n_inputs())->name();
1661 if (port.length() && track->connect_output (track->output (x), port, this)) {
1666 channels_used += track->n_inputs ();
1669 vector<string> cports;
1670 uint32_t ni = _control_out->n_inputs();
1672 for (n = 0; n < ni; ++n) {
1673 cports.push_back (_control_out->input(n)->name());
1676 track->set_control_outs (cports);
1679 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1680 track->set_remote_control_id (ntracks());
1682 new_routes.push_back (track);
1683 ret.push_back (track);
1686 catch (failed_constructor &err) {
1687 error << _("Session: could not create new audio track.") << endmsg;
1688 // XXX should we delete the tracks already created?
1696 if (!new_routes.empty()) {
1697 add_routes (new_routes, false);
1698 save_state (_current_snapshot_name);
1705 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1708 uint32_t bus_id = 1;
1713 /* count existing audio busses */
1716 shared_ptr<RouteList> r = routes.reader ();
1718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1719 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1720 if (!(*i)->hidden()) {
1727 vector<string> physinputs;
1728 vector<string> physoutputs;
1730 _engine.get_physical_outputs (physoutputs);
1731 _engine.get_physical_inputs (physinputs);
1738 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1740 if (route_by_name (bus_name) == 0) {
1744 } while (bus_id < (UINT_MAX-1));
1747 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1749 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1750 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1751 input_channels, output_channels)
1755 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1759 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1760 port = physinputs[((n+x)%n_physical_inputs)];
1763 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1768 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1772 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1773 port = physoutputs[((n+x)%n_physical_outputs)];
1774 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1776 port = _master_out->input (x%_master_out->n_inputs())->name();
1780 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1786 vector<string> cports;
1787 uint32_t ni = _control_out->n_inputs();
1789 for (uint32_t n = 0; n < ni; ++n) {
1790 cports.push_back (_control_out->input(n)->name());
1792 bus->set_control_outs (cports);
1795 ret.push_back (bus);
1799 catch (failed_constructor &err) {
1800 error << _("Session: could not create new audio route.") << endmsg;
1809 add_routes (ret, false);
1810 save_state (_current_snapshot_name);
1818 Session::add_routes (RouteList& new_routes, bool save)
1821 RCUWriter<RouteList> writer (routes);
1822 shared_ptr<RouteList> r = writer.get_copy ();
1823 r->insert (r->end(), new_routes.begin(), new_routes.end());
1824 resort_routes_using (r);
1827 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1829 boost::weak_ptr<Route> wpr (*x);
1831 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1832 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1833 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1834 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1836 if ((*x)->master()) {
1840 if ((*x)->control()) {
1841 _control_out = (*x);
1848 save_state (_current_snapshot_name);
1851 RouteAdded (new_routes); /* EMIT SIGNAL */
1855 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1857 /* need to do this in case we're rolling at the time, to prevent false underruns */
1858 dstream->do_refill_with_alloc();
1861 RCUWriter<DiskstreamList> writer (diskstreams);
1862 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1863 ds->push_back (dstream);
1866 dstream->set_block_size (current_block_size);
1868 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1869 /* this will connect to future changes, and check the current length */
1870 diskstream_playlist_changed (dstream);
1872 dstream->prepare ();
1876 Session::remove_route (shared_ptr<Route> route)
1879 RCUWriter<RouteList> writer (routes);
1880 shared_ptr<RouteList> rs = writer.get_copy ();
1883 /* deleting the master out seems like a dumb
1884 idea, but its more of a UI policy issue
1888 if (route == _master_out) {
1889 _master_out = shared_ptr<Route> ();
1892 if (route == _control_out) {
1893 _control_out = shared_ptr<Route> ();
1895 /* cancel control outs for all routes */
1897 vector<string> empty;
1899 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1900 (*r)->set_control_outs (empty);
1904 update_route_solo_state ();
1906 /* writer goes out of scope, forces route list update */
1909 // FIXME: audio specific
1911 boost::shared_ptr<AudioDiskstream> ds;
1913 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1914 ds = at->audio_diskstream();
1920 RCUWriter<DiskstreamList> dsl (diskstreams);
1921 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1926 find_current_end ();
1928 update_latency_compensation (false, false);
1931 /* get rid of it from the dead wood collection in the route list manager */
1933 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1937 /* try to cause everyone to drop their references */
1939 route->drop_references ();
1941 /* save the new state of the world */
1943 if (save_state (_current_snapshot_name)) {
1944 save_history (_current_snapshot_name);
1949 Session::route_mute_changed (void* src)
1955 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1957 if (solo_update_disabled) {
1963 boost::shared_ptr<Route> route = wpr.lock ();
1966 /* should not happen */
1967 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1971 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1973 shared_ptr<RouteList> r = routes.reader ();
1975 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1977 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1981 /* don't mess with busses */
1983 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1989 /* don't mess with tracks */
1991 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1996 if ((*i) != route &&
1997 ((*i)->mix_group () == 0 ||
1998 (*i)->mix_group () != route->mix_group () ||
1999 !route->mix_group ()->is_active())) {
2001 if ((*i)->soloed()) {
2003 /* if its already soloed, and solo latching is enabled,
2004 then leave it as it is.
2007 if (Config->get_solo_latched()) {
2014 solo_update_disabled = true;
2015 (*i)->set_solo (false, src);
2016 solo_update_disabled = false;
2020 bool something_soloed = false;
2021 bool same_thing_soloed = false;
2022 bool signal = false;
2024 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2025 if ((*i)->soloed()) {
2026 something_soloed = true;
2027 if (dynamic_cast<AudioTrack*>((*i).get())) {
2029 same_thing_soloed = true;
2034 same_thing_soloed = true;
2042 if (something_soloed != currently_soloing) {
2044 currently_soloing = something_soloed;
2047 modify_solo_mute (is_track, same_thing_soloed);
2050 SoloActive (currently_soloing);
2057 Session::update_route_solo_state ()
2060 bool is_track = false;
2061 bool signal = false;
2063 /* caller must hold RouteLock */
2065 /* this is where we actually implement solo by changing
2066 the solo mute setting of each track.
2069 shared_ptr<RouteList> r = routes.reader ();
2071 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2072 if ((*i)->soloed()) {
2074 if (dynamic_cast<AudioTrack*>((*i).get())) {
2081 if (mute != currently_soloing) {
2083 currently_soloing = mute;
2086 if (!is_track && !mute) {
2088 /* nothing is soloed */
2090 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2091 (*i)->set_solo_mute (false);
2101 modify_solo_mute (is_track, mute);
2104 SoloActive (currently_soloing);
2109 Session::modify_solo_mute (bool is_track, bool mute)
2111 shared_ptr<RouteList> r = routes.reader ();
2113 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2117 /* only alter track solo mute */
2119 if (dynamic_cast<AudioTrack*>((*i).get())) {
2120 if ((*i)->soloed()) {
2121 (*i)->set_solo_mute (!mute);
2123 (*i)->set_solo_mute (mute);
2129 /* only alter bus solo mute */
2131 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2133 if ((*i)->soloed()) {
2135 (*i)->set_solo_mute (false);
2139 /* don't mute master or control outs
2140 in response to another bus solo
2143 if ((*i) != _master_out &&
2144 (*i) != _control_out) {
2145 (*i)->set_solo_mute (mute);
2156 Session::catch_up_on_solo ()
2158 /* this is called after set_state() to catch the full solo
2159 state, which can't be correctly determined on a per-route
2160 basis, but needs the global overview that only the session
2163 update_route_solo_state();
2167 Session::route_by_name (string name)
2169 shared_ptr<RouteList> r = routes.reader ();
2171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2172 if ((*i)->name() == name) {
2177 return shared_ptr<Route> ((Route*) 0);
2181 Session::route_by_id (PBD::ID id)
2183 shared_ptr<RouteList> r = routes.reader ();
2185 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2186 if ((*i)->id() == id) {
2191 return shared_ptr<Route> ((Route*) 0);
2195 Session::route_by_remote_id (uint32_t id)
2197 shared_ptr<RouteList> r = routes.reader ();
2199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2200 if ((*i)->remote_control_id() == id) {
2205 return shared_ptr<Route> ((Route*) 0);
2209 Session::find_current_end ()
2211 if (_state_of_the_state & Loading) {
2215 nframes_t max = get_maximum_extent ();
2217 if (max > end_location->end()) {
2218 end_location->set_end (max);
2220 DurationChanged(); /* EMIT SIGNAL */
2225 Session::get_maximum_extent () const
2230 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2232 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2233 Playlist* pl = (*i)->playlist();
2234 if ((me = pl->get_maximum_extent()) > max) {
2242 boost::shared_ptr<Diskstream>
2243 Session::diskstream_by_name (string name)
2245 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2247 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2248 if ((*i)->name() == name) {
2253 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2256 boost::shared_ptr<Diskstream>
2257 Session::diskstream_by_id (const PBD::ID& id)
2259 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2261 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2262 if ((*i)->id() == id) {
2267 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2270 /* AudioRegion management */
2273 Session::new_region_name (string old)
2275 string::size_type last_period;
2277 string::size_type len = old.length() + 64;
2280 if ((last_period = old.find_last_of ('.')) == string::npos) {
2282 /* no period present - add one explicitly */
2285 last_period = old.length() - 1;
2290 number = atoi (old.substr (last_period+1).c_str());
2294 while (number < (UINT_MAX-1)) {
2296 AudioRegionList::const_iterator i;
2301 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2304 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2305 if (i->second->name() == sbuf) {
2310 if (i == audio_regions.end()) {
2315 if (number != (UINT_MAX-1)) {
2319 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2324 Session::region_name (string& result, string base, bool newlevel) const
2331 Glib::Mutex::Lock lm (region_lock);
2333 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2341 /* XXX this is going to be slow. optimize me later */
2346 string::size_type pos;
2348 pos = base.find_last_of ('.');
2350 /* pos may be npos, but then we just use entire base */
2352 subbase = base.substr (0, pos);
2356 bool name_taken = true;
2359 Glib::Mutex::Lock lm (region_lock);
2361 for (int n = 1; n < 5000; ++n) {
2364 snprintf (buf, sizeof (buf), ".%d", n);
2369 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2370 if (i->second->name() == result) {
2383 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2391 Session::add_region (boost::shared_ptr<Region> region)
2393 boost::shared_ptr<AudioRegion> ar;
2394 boost::shared_ptr<AudioRegion> oar;
2398 Glib::Mutex::Lock lm (region_lock);
2400 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2402 AudioRegionList::iterator x;
2404 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2406 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2408 if (ar->region_list_equivalent (oar)) {
2413 if (x == audio_regions.end()) {
2415 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2417 entry.first = region->id();
2420 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2432 fatal << _("programming error: ")
2433 << X_("unknown region type passed to Session::add_region()")
2440 /* mark dirty because something has changed even if we didn't
2441 add the region to the region list.
2447 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2448 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2449 AudioRegionAdded (ar); /* EMIT SIGNAL */
2454 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2456 if (what_changed & Region::HiddenChanged) {
2457 /* relay hidden changes */
2458 RegionHiddenChange (region);
2463 Session::region_renamed (boost::shared_ptr<Region> region)
2465 add_region (region);
2469 Session::remove_region (boost::shared_ptr<Region> region)
2471 AudioRegionList::iterator i;
2472 boost::shared_ptr<AudioRegion> ar;
2473 bool removed = false;
2476 Glib::Mutex::Lock lm (region_lock);
2478 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2479 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2480 audio_regions.erase (i);
2486 fatal << _("programming error: ")
2487 << X_("unknown region type passed to Session::remove_region()")
2493 /* mark dirty because something has changed even if we didn't
2494 remove the region from the region list.
2500 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2504 boost::shared_ptr<AudioRegion>
2505 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2507 AudioRegionList::iterator i;
2508 boost::shared_ptr<AudioRegion> region;
2509 Glib::Mutex::Lock lm (region_lock);
2511 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2515 if (region->whole_file()) {
2517 if (child->source_equivalent (region)) {
2523 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2527 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2529 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2530 (*i)->get_region_list_equivalent_regions (region, result);
2534 Session::destroy_region (boost::shared_ptr<Region> region)
2536 boost::shared_ptr<AudioRegion> aregion;
2538 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2542 if (aregion->playlist()) {
2543 aregion->playlist()->destroy_region (region);
2546 vector<boost::shared_ptr<Source> > srcs;
2548 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2549 srcs.push_back (aregion->source (n));
2552 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2554 if ((*i).use_count() == 1) {
2555 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2558 (afs)->mark_for_remove ();
2561 (*i)->drop_references ();
2569 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2571 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2572 destroy_region (*i);
2578 Session::remove_last_capture ()
2580 list<boost::shared_ptr<Region> > r;
2582 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2584 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2585 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2588 r.insert (r.end(), l.begin(), l.end());
2593 destroy_regions (r);
2598 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2604 /* Source Management */
2607 Session::add_source (boost::shared_ptr<Source> source)
2609 boost::shared_ptr<AudioFileSource> afs;
2611 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2613 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2614 pair<AudioSourceList::iterator,bool> result;
2616 entry.first = source->id();
2620 Glib::Mutex::Lock lm (audio_source_lock);
2621 result = audio_sources.insert (entry);
2624 if (!result.second) {
2625 cerr << "\tNOT inserted ? " << result.second << endl;
2628 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2631 SourceAdded (source); /* EMIT SIGNAL */
2633 cerr << "\tNOT AUDIO FILE\n";
2638 Session::remove_source (boost::weak_ptr<Source> src)
2640 AudioSourceList::iterator i;
2641 boost::shared_ptr<Source> source = src.lock();
2644 cerr << "removing a source DEAD\n";
2646 cerr << "removing a source " << source->name () << endl;
2649 Glib::Mutex::Lock lm (audio_source_lock);
2651 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2652 audio_sources.erase (i);
2656 if (!_state_of_the_state & InCleanup) {
2658 /* save state so we don't end up with a session file
2659 referring to non-existent sources.
2662 save_state (_current_snapshot_name);
2665 SourceRemoved(source); /* EMIT SIGNAL */
2669 boost::shared_ptr<Source>
2670 Session::source_by_id (const PBD::ID& id)
2672 Glib::Mutex::Lock lm (audio_source_lock);
2673 AudioSourceList::iterator i;
2674 boost::shared_ptr<Source> source;
2676 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2680 /* XXX search MIDI or other searches here */
2686 Session::peak_path_from_audio_path (string audio_path) const
2691 res += PBD::basename_nosuffix (audio_path);
2698 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2701 string old_basename = PBD::basename_nosuffix (oldname);
2702 string new_legalized = legalize_for_path (newname);
2704 /* note: we know (or assume) the old path is already valid */
2708 /* destructive file sources have a name of the form:
2710 /path/to/Tnnnn-NAME(%[LR])?.wav
2712 the task here is to replace NAME with the new name.
2715 /* find last slash */
2719 string::size_type slash;
2720 string::size_type dash;
2722 if ((slash = path.find_last_of ('/')) == string::npos) {
2726 dir = path.substr (0, slash+1);
2728 /* '-' is not a legal character for the NAME part of the path */
2730 if ((dash = path.find_last_of ('-')) == string::npos) {
2734 prefix = path.substr (slash+1, dash-(slash+1));
2739 path += new_legalized;
2740 path += ".wav"; /* XXX gag me with a spoon */
2744 /* non-destructive file sources have a name of the form:
2746 /path/to/NAME-nnnnn(%[LR])?.wav
2748 the task here is to replace NAME with the new name.
2753 string::size_type slash;
2754 string::size_type dash;
2755 string::size_type postfix;
2757 /* find last slash */
2759 if ((slash = path.find_last_of ('/')) == string::npos) {
2763 dir = path.substr (0, slash+1);
2765 /* '-' is not a legal character for the NAME part of the path */
2767 if ((dash = path.find_last_of ('-')) == string::npos) {
2771 suffix = path.substr (dash+1);
2773 // Suffix is now everything after the dash. Now we need to eliminate
2774 // the nnnnn part, which is done by either finding a '%' or a '.'
2776 postfix = suffix.find_last_of ("%");
2777 if (postfix == string::npos) {
2778 postfix = suffix.find_last_of ('.');
2781 if (postfix != string::npos) {
2782 suffix = suffix.substr (postfix);
2784 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2788 const uint32_t limit = 10000;
2789 char buf[PATH_MAX+1];
2791 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2793 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2795 if (access (buf, F_OK) != 0) {
2803 error << "FATAL ERROR! Could not find a " << endl;
2812 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2816 char buf[PATH_MAX+1];
2817 const uint32_t limit = 10000;
2821 legalized = legalize_for_path (name);
2823 /* find a "version" of the file name that doesn't exist in
2824 any of the possible directories.
2827 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2829 vector<space_and_path>::iterator i;
2830 uint32_t existing = 0;
2832 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2836 spath += sound_dir (false);
2840 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2841 } else if (nchan == 2) {
2843 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2845 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2847 } else if (nchan < 26) {
2848 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2850 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2858 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2859 } else if (nchan == 2) {
2861 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2863 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2865 } else if (nchan < 26) {
2866 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2868 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2872 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2878 if (existing == 0) {
2883 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2884 throw failed_constructor();
2888 /* we now have a unique name for the file, but figure out where to
2894 spath = discover_best_sound_dir ();
2896 string::size_type pos = foo.find_last_of ('/');
2898 if (pos == string::npos) {
2901 spath += foo.substr (pos + 1);
2907 boost::shared_ptr<AudioFileSource>
2908 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2910 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2911 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2914 /* Playlist management */
2917 Session::playlist_by_name (string name)
2919 Glib::Mutex::Lock lm (playlist_lock);
2920 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2921 if ((*i)->name() == name) {
2925 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2926 if ((*i)->name() == name) {
2934 Session::add_playlist (Playlist* playlist)
2936 if (playlist->hidden()) {
2941 Glib::Mutex::Lock lm (playlist_lock);
2942 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2943 playlists.insert (playlists.begin(), playlist);
2945 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2946 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2952 PlaylistAdded (playlist); /* EMIT SIGNAL */
2956 Session::track_playlist (Playlist* pl, bool inuse)
2958 PlaylistList::iterator x;
2961 Glib::Mutex::Lock lm (playlist_lock);
2964 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2966 unused_playlists.insert (pl);
2968 if ((x = playlists.find (pl)) != playlists.end()) {
2969 playlists.erase (x);
2974 //cerr << "shifting playlist to used: " << pl->name() << endl;
2976 playlists.insert (pl);
2978 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2979 unused_playlists.erase (x);
2986 Session::remove_playlist (Playlist* playlist)
2988 if (_state_of_the_state & Deletion) {
2993 Glib::Mutex::Lock lm (playlist_lock);
2994 // cerr << "removing playlist: " << playlist->name() << endl;
2996 PlaylistList::iterator i;
2998 i = find (playlists.begin(), playlists.end(), playlist);
3000 if (i != playlists.end()) {
3001 playlists.erase (i);
3004 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3005 if (i != unused_playlists.end()) {
3006 unused_playlists.erase (i);
3013 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3017 Session::set_audition (boost::shared_ptr<Region> r)
3019 pending_audition_region = r;
3020 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3021 schedule_butler_transport_work ();
3025 Session::audition_playlist ()
3027 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3028 ev->region.reset ();
3033 Session::non_realtime_set_audition ()
3035 if (!pending_audition_region) {
3036 auditioner->audition_current_playlist ();
3038 auditioner->audition_region (pending_audition_region);
3039 pending_audition_region.reset ();
3041 AuditionActive (true); /* EMIT SIGNAL */
3045 Session::audition_region (boost::shared_ptr<Region> r)
3047 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3053 Session::cancel_audition ()
3055 if (auditioner->active()) {
3056 auditioner->cancel_audition ();
3057 AuditionActive (false); /* EMIT SIGNAL */
3062 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3064 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3068 Session::remove_empty_sounds ()
3070 PathScanner scanner;
3072 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3074 Glib::Mutex::Lock lm (audio_source_lock);
3076 regex_t compiled_tape_track_pattern;
3079 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3083 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3085 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3089 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3091 /* never remove files that appear to be a tape track */
3093 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3098 if (AudioFileSource::is_empty (*this, *(*i))) {
3100 unlink ((*i)->c_str());
3102 string peak_path = peak_path_from_audio_path (**i);
3103 unlink (peak_path.c_str());
3109 delete possible_audiofiles;
3113 Session::is_auditioning () const
3115 /* can be called before we have an auditioner object */
3117 return auditioner->active();
3124 Session::set_all_solo (bool yn)
3126 shared_ptr<RouteList> r = routes.reader ();
3128 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3129 if (!(*i)->hidden()) {
3130 (*i)->set_solo (yn, this);
3138 Session::set_all_mute (bool yn)
3140 shared_ptr<RouteList> r = routes.reader ();
3142 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3143 if (!(*i)->hidden()) {
3144 (*i)->set_mute (yn, this);
3152 Session::n_diskstreams () const
3156 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3158 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3159 if (!(*i)->hidden()) {
3167 Session::graph_reordered ()
3169 /* don't do this stuff if we are setting up connections
3170 from a set_state() call.
3173 if (_state_of_the_state & InitialConnecting) {
3179 /* force all diskstreams to update their capture offset values to
3180 reflect any changes in latencies within the graph.
3183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3185 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3186 (*i)->set_capture_offset ();
3191 Session::record_disenable_all ()
3193 record_enable_change_all (false);
3197 Session::record_enable_all ()
3199 record_enable_change_all (true);
3203 Session::record_enable_change_all (bool yn)
3205 shared_ptr<RouteList> r = routes.reader ();
3207 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3210 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3211 at->set_record_enable (yn, this);
3215 /* since we don't keep rec-enable state, don't mark session dirty */
3219 Session::add_redirect (Redirect* redirect)
3223 PortInsert* port_insert;
3224 PluginInsert* plugin_insert;
3226 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3227 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3228 _port_inserts.insert (_port_inserts.begin(), port_insert);
3229 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3230 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3232 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3235 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3236 _sends.insert (_sends.begin(), send);
3238 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3242 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3248 Session::remove_redirect (Redirect* redirect)
3252 PortInsert* port_insert;
3253 PluginInsert* plugin_insert;
3255 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3256 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3257 _port_inserts.remove (port_insert);
3258 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3259 _plugin_inserts.remove (plugin_insert);
3261 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3264 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3265 _sends.remove (send);
3267 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3275 Session::available_capture_duration ()
3277 const double scale = 4096.0 / sizeof (Sample);
3279 if (_total_free_4k_blocks * scale > (double) max_frames) {
3283 return (nframes_t) floor (_total_free_4k_blocks * scale);
3287 Session::add_connection (ARDOUR::Connection* connection)
3290 Glib::Mutex::Lock guard (connection_lock);
3291 _connections.push_back (connection);
3294 ConnectionAdded (connection); /* EMIT SIGNAL */
3300 Session::remove_connection (ARDOUR::Connection* connection)
3302 bool removed = false;
3305 Glib::Mutex::Lock guard (connection_lock);
3306 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3308 if (i != _connections.end()) {
3309 _connections.erase (i);
3315 ConnectionRemoved (connection); /* EMIT SIGNAL */
3321 ARDOUR::Connection *
3322 Session::connection_by_name (string name) const
3324 Glib::Mutex::Lock lm (connection_lock);
3326 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3327 if ((*i)->name() == name) {
3336 Session::tempo_map_changed (Change ignored)
3343 Session::ensure_passthru_buffers (uint32_t howmany)
3345 while (howmany > _passthru_buffers.size()) {
3347 #ifdef NO_POSIX_MEMALIGN
3348 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3350 posix_memalign((void **)&p,16,current_block_size * 4);
3352 _passthru_buffers.push_back (p);
3356 #ifdef NO_POSIX_MEMALIGN
3357 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3359 posix_memalign((void **)&p,16,current_block_size * 4);
3361 memset (p, 0, sizeof (Sample) * current_block_size);
3362 _silent_buffers.push_back (p);
3366 #ifdef NO_POSIX_MEMALIGN
3367 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3369 posix_memalign((void **)&p,16,current_block_size * 4);
3371 memset (p, 0, sizeof (Sample) * current_block_size);
3372 _send_buffers.push_back (p);
3375 allocate_pan_automation_buffers (current_block_size, howmany, false);
3379 Session::next_send_name ()
3382 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3387 Session::next_insert_name ()
3390 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3394 /* Named Selection management */
3397 Session::named_selection_by_name (string name)
3399 Glib::Mutex::Lock lm (named_selection_lock);
3400 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3401 if ((*i)->name == name) {
3409 Session::add_named_selection (NamedSelection* named_selection)
3412 Glib::Mutex::Lock lm (named_selection_lock);
3413 named_selections.insert (named_selections.begin(), named_selection);
3418 NamedSelectionAdded (); /* EMIT SIGNAL */
3422 Session::remove_named_selection (NamedSelection* named_selection)
3424 bool removed = false;
3427 Glib::Mutex::Lock lm (named_selection_lock);
3429 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3431 if (i != named_selections.end()) {
3433 named_selections.erase (i);
3440 NamedSelectionRemoved (); /* EMIT SIGNAL */
3445 Session::reset_native_file_format ()
3447 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3449 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3450 (*i)->reset_write_sources (false);
3455 Session::route_name_unique (string n) const
3457 shared_ptr<RouteList> r = routes.reader ();
3459 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3460 if ((*i)->name() == n) {
3469 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3471 return fs->move_to_trash (dead_sound_dir_name);
3475 Session::n_playlists () const
3477 Glib::Mutex::Lock lm (playlist_lock);
3478 return playlists.size();
3482 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3484 if (!force && howmany <= _npan_buffers) {
3488 if (_pan_automation_buffer) {
3490 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3491 delete [] _pan_automation_buffer[i];
3494 delete [] _pan_automation_buffer;
3497 _pan_automation_buffer = new pan_t*[howmany];
3499 for (uint32_t i = 0; i < howmany; ++i) {
3500 _pan_automation_buffer[i] = new pan_t[nframes];
3503 _npan_buffers = howmany;
3507 Session::freeze (InterThreadInfo& itt)
3509 shared_ptr<RouteList> r = routes.reader ();
3511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3515 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3516 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3527 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3528 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3532 boost::shared_ptr<AudioFileSource> fsource;
3534 char buf[PATH_MAX+1];
3538 nframes_t this_chunk;
3540 vector<Sample*> buffers;
3542 // any bigger than this seems to cause stack overflows in called functions
3543 const nframes_t chunk_size = (128 * 1024)/4;
3545 g_atomic_int_set (&processing_prohibited, 1);
3547 /* call tree *MUST* hold route_lock */
3549 if ((playlist = track.diskstream()->playlist()) == 0) {
3553 /* external redirects will be a problem */
3555 if (track.has_external_redirects()) {
3559 nchans = track.audio_diskstream()->n_channels();
3561 dir = discover_best_sound_dir ();
3563 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3565 for (x = 0; x < 99999; ++x) {
3566 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3567 if (access (buf, F_OK) != 0) {
3573 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3578 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3581 catch (failed_constructor& err) {
3582 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3586 srcs.push_back (fsource);
3589 /* XXX need to flush all redirects */
3594 /* create a set of reasonably-sized buffers */
3596 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3598 #ifdef NO_POSIX_MEMALIGN
3599 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3601 posix_memalign((void **)&b,16,chunk_size * 4);
3603 buffers.push_back (b);
3606 while (to_do && !itt.cancel) {
3608 this_chunk = min (to_do, chunk_size);
3610 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3615 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3616 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3619 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3625 start += this_chunk;
3626 to_do -= this_chunk;
3628 itt.progress = (float) (1.0 - ((double) to_do / len));
3637 xnow = localtime (&now);
3639 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3640 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3643 afs->update_header (position, *xnow, now);
3647 /* build peakfile for new source */
3649 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3650 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3652 afs->build_peaks ();
3661 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3662 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3665 afs->mark_for_remove ();
3668 (*src)->drop_references ();
3672 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3676 g_atomic_int_set (&processing_prohibited, 0);
3684 Session::get_silent_buffers (uint32_t howmany)
3686 for (uint32_t i = 0; i < howmany; ++i) {
3687 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3689 return _silent_buffers;
3693 Session::ntracks () const
3696 shared_ptr<RouteList> r = routes.reader ();
3698 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3699 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3708 Session::nbusses () const
3711 shared_ptr<RouteList> r = routes.reader ();
3713 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3714 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3723 Session::add_curve(Curve *curve)
3725 curves[curve->id()] = curve;
3729 Session::add_automation_list(AutomationList *al)
3731 automation_lists[al->id()] = al;