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(); ++i) {
467 i->second->drop_references ();
470 audio_regions.clear ();
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete routes\n";
474 #endif /* TRACK_DESTRUCTION */
476 RCUWriter<RouteList> writer (routes);
477 boost::shared_ptr<RouteList> r = writer.get_copy ();
478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
479 (*i)->drop_references ();
482 /* writer goes out of scope and updates master */
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete diskstreams\n";
489 #endif /* TRACK_DESTRUCTION */
491 RCUWriter<DiskstreamList> dwriter (diskstreams);
492 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
493 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
494 (*i)->drop_references ();
498 diskstreams.flush ();
500 #ifdef TRACK_DESTRUCTION
501 cerr << "delete audio sources\n";
502 #endif /* TRACK_DESTRUCTION */
503 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
504 AudioSourceList::iterator tmp;
509 i->second->drop_references ();
514 audio_sources.clear ();
516 #ifdef TRACK_DESTRUCTION
517 cerr << "delete mix groups\n";
518 #endif /* TRACK_DESTRUCTION */
519 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
520 list<RouteGroup*>::iterator tmp;
530 #ifdef TRACK_DESTRUCTION
531 cerr << "delete edit groups\n";
532 #endif /* TRACK_DESTRUCTION */
533 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
534 list<RouteGroup*>::iterator tmp;
544 #ifdef TRACK_DESTRUCTION
545 cerr << "delete connections\n";
546 #endif /* TRACK_DESTRUCTION */
547 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
548 ConnectionList::iterator tmp;
558 if (butler_mixdown_buffer) {
559 delete [] butler_mixdown_buffer;
562 if (butler_gain_buffer) {
563 delete [] butler_gain_buffer;
566 Crossfade::set_buffer_size (0);
574 Session::set_worst_io_latencies ()
576 _worst_output_latency = 0;
577 _worst_input_latency = 0;
579 if (!_engine.connected()) {
583 boost::shared_ptr<RouteList> r = routes.reader ();
585 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
586 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
587 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
592 Session::when_engine_running ()
594 string first_physical_output;
596 /* we don't want to run execute this again */
598 first_time_running.disconnect ();
600 set_block_size (_engine.frames_per_cycle());
601 set_frame_rate (_engine.frame_rate());
603 Config->map_parameters (mem_fun (*this, &Session::config_changed));
605 /* every time we reconnect, recompute worst case output latencies */
607 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
609 if (synced_to_jack()) {
610 _engine.transport_stop ();
613 if (Config->get_jack_time_master()) {
614 _engine.transport_locate (_transport_frame);
622 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
624 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
626 /* existing state for Click */
628 if (_click_io->set_state (*child->children().front()) == 0) {
630 _clicking = Config->get_clicking ();
634 error << _("could not setup Click I/O") << endmsg;
640 /* default state for Click */
642 first_physical_output = _engine.get_nth_physical_output (0);
644 if (first_physical_output.length()) {
645 if (_click_io->add_output_port (first_physical_output, this)) {
646 // relax, even though its an error
648 _clicking = Config->get_clicking ();
654 catch (failed_constructor& err) {
655 error << _("cannot setup Click I/O") << endmsg;
658 set_worst_io_latencies ();
661 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
664 if (auditioner == 0) {
666 /* we delay creating the auditioner till now because
667 it makes its own connections to ports named
668 in the ARDOUR_RC config file. the engine has
669 to be running for this to work.
673 auditioner.reset (new Auditioner (*this));
676 catch (failed_constructor& err) {
677 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
681 /* Create a set of Connection objects that map
682 to the physical outputs currently available
687 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
689 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
691 Connection* c = new OutputConnection (buf, true);
694 c->add_connection (0, _engine.get_nth_physical_output (np));
699 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
701 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
703 Connection* c = new InputConnection (buf, true);
706 c->add_connection (0, _engine.get_nth_physical_input (np));
713 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
715 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
717 Connection* c = new OutputConnection (buf, true);
721 c->add_connection (0, _engine.get_nth_physical_output (np));
722 c->add_connection (1, _engine.get_nth_physical_output (np+1));
727 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
729 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
731 Connection* c = new InputConnection (buf, true);
735 c->add_connection (0, _engine.get_nth_physical_input (np));
736 c->add_connection (1, _engine.get_nth_physical_input (np+1));
745 /* create master/control ports */
750 /* force the master to ignore any later call to this */
752 if (_master_out->pending_state_node) {
753 _master_out->ports_became_legal();
756 /* no panner resets till we are through */
758 _master_out->defer_pan_reset ();
760 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
761 if (_master_out->add_input_port ("", this)) {
762 error << _("cannot setup master inputs")
768 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
769 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
770 error << _("cannot setup master outputs")
777 _master_out->allow_pan_reset ();
781 Connection* c = new OutputConnection (_("Master Out"), true);
783 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
785 c->add_connection ((int) n, _master_out->input(n)->name());
792 /* catch up on send+insert cnts */
796 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
799 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
800 if (id > insert_cnt) {
808 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
811 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
818 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
820 /* hook us up to the engine */
822 _engine.set_session (this);
827 osc->set_session (*this);
830 _state_of_the_state = Clean;
832 DirtyChanged (); /* EMIT SIGNAL */
836 Session::hookup_io ()
838 /* stop graph reordering notifications from
839 causing resorts, etc.
842 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
844 /* Tell all IO objects to create their ports */
851 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
852 if (_control_out->add_input_port ("", this)) {
853 error << _("cannot setup control inputs")
859 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
860 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
861 error << _("cannot set up master outputs")
869 /* Tell all IO objects to connect themselves together */
871 IO::enable_connecting ();
873 /* Now reset all panners */
875 IO::reset_panners ();
877 /* Anyone who cares about input state, wake up and do something */
879 IOConnectionsComplete (); /* EMIT SIGNAL */
881 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
883 /* now handle the whole enchilada as if it was one
889 /* update mixer solo state */
895 Session::playlist_length_changed (Playlist* pl)
897 /* we can't just increase end_location->end() if pl->get_maximum_extent()
898 if larger. if the playlist used to be the longest playlist,
899 and its now shorter, we have to decrease end_location->end(). hence,
900 we have to iterate over all diskstreams and check the
901 playlists currently in use.
907 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
911 if ((playlist = dstream->playlist()) != 0) {
912 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
915 /* see comment in playlist_length_changed () */
920 Session::record_enabling_legal () const
922 /* this used to be in here, but survey says.... we don't need to restrict it */
923 // if (record_status() == Recording) {
927 if (Config->get_all_safe()) {
934 Session::reset_input_monitor_state ()
936 if (transport_rolling()) {
938 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
940 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
941 if ((*i)->record_enabled ()) {
942 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
943 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
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 = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
952 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
959 Session::auto_punch_start_changed (Location* location)
961 replace_event (Event::PunchIn, location->start());
963 if (get_record_enabled() && Config->get_punch_in()) {
964 /* capture start has been changed, so save new pending state */
965 save_state ("", true);
970 Session::auto_punch_end_changed (Location* location)
972 nframes_t when_to_stop = location->end();
973 // when_to_stop += _worst_output_latency + _worst_input_latency;
974 replace_event (Event::PunchOut, when_to_stop);
978 Session::auto_punch_changed (Location* location)
980 nframes_t when_to_stop = location->end();
982 replace_event (Event::PunchIn, location->start());
983 //when_to_stop += _worst_output_latency + _worst_input_latency;
984 replace_event (Event::PunchOut, when_to_stop);
988 Session::auto_loop_changed (Location* location)
990 replace_event (Event::AutoLoop, location->end(), location->start());
992 if (transport_rolling() && play_loop) {
994 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
996 if (_transport_frame > location->end()) {
997 // relocate to beginning of loop
998 clear_events (Event::LocateRoll);
1000 request_locate (location->start(), true);
1003 else if (Config->get_seamless_loop() && !loop_changing) {
1005 // schedule a locate-roll to refill the diskstreams at the
1006 // previous loop end
1007 loop_changing = true;
1009 if (location->end() > last_loopend) {
1010 clear_events (Event::LocateRoll);
1011 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1018 last_loopend = location->end();
1023 Session::set_auto_punch_location (Location* location)
1027 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1028 auto_punch_start_changed_connection.disconnect();
1029 auto_punch_end_changed_connection.disconnect();
1030 auto_punch_changed_connection.disconnect();
1031 existing->set_auto_punch (false, this);
1032 remove_event (existing->start(), Event::PunchIn);
1033 clear_events (Event::PunchOut);
1034 auto_punch_location_changed (0);
1039 if (location == 0) {
1043 if (location->end() <= location->start()) {
1044 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1048 auto_punch_start_changed_connection.disconnect();
1049 auto_punch_end_changed_connection.disconnect();
1050 auto_punch_changed_connection.disconnect();
1052 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1053 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1054 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1056 location->set_auto_punch (true, this);
1057 auto_punch_location_changed (location);
1061 Session::set_auto_loop_location (Location* location)
1065 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1066 auto_loop_start_changed_connection.disconnect();
1067 auto_loop_end_changed_connection.disconnect();
1068 auto_loop_changed_connection.disconnect();
1069 existing->set_auto_loop (false, this);
1070 remove_event (existing->end(), Event::AutoLoop);
1071 auto_loop_location_changed (0);
1076 if (location == 0) {
1080 if (location->end() <= location->start()) {
1081 error << _("Session: you can't use a mark for auto loop") << endmsg;
1085 last_loopend = location->end();
1087 auto_loop_start_changed_connection.disconnect();
1088 auto_loop_end_changed_connection.disconnect();
1089 auto_loop_changed_connection.disconnect();
1091 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1092 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1093 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1095 location->set_auto_loop (true, this);
1096 auto_loop_location_changed (location);
1100 Session::locations_added (Location* ignored)
1106 Session::locations_changed ()
1108 _locations.apply (*this, &Session::handle_locations_changed);
1112 Session::handle_locations_changed (Locations::LocationList& locations)
1114 Locations::LocationList::iterator i;
1116 bool set_loop = false;
1117 bool set_punch = false;
1119 for (i = locations.begin(); i != locations.end(); ++i) {
1123 if (location->is_auto_punch()) {
1124 set_auto_punch_location (location);
1127 if (location->is_auto_loop()) {
1128 set_auto_loop_location (location);
1135 set_auto_loop_location (0);
1138 set_auto_punch_location (0);
1145 Session::enable_record ()
1147 /* XXX really atomic compare+swap here */
1148 if (g_atomic_int_get (&_record_status) != Recording) {
1149 g_atomic_int_set (&_record_status, Recording);
1150 _last_record_location = _transport_frame;
1151 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1153 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1154 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1155 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1156 if ((*i)->record_enabled ()) {
1157 (*i)->monitor_input (true);
1162 RecordStateChanged ();
1167 Session::disable_record (bool rt_context, bool force)
1171 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1173 if (!Config->get_latched_record_enable () || force) {
1174 g_atomic_int_set (&_record_status, Disabled);
1176 if (rs == Recording) {
1177 g_atomic_int_set (&_record_status, Enabled);
1181 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1183 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1184 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1186 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1187 if ((*i)->record_enabled ()) {
1188 (*i)->monitor_input (false);
1193 RecordStateChanged (); /* emit signal */
1196 remove_pending_capture_state ();
1202 Session::step_back_from_record ()
1204 g_atomic_int_set (&_record_status, Enabled);
1206 if (Config->get_monitoring_model() == HardwareMonitoring) {
1207 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1209 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1210 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1211 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1212 (*i)->monitor_input (false);
1219 Session::maybe_enable_record ()
1221 g_atomic_int_set (&_record_status, Enabled);
1223 /* XXX this save should really happen in another thread. its needed so that
1224 pending capture state can be recovered if we crash.
1227 save_state ("", true);
1229 if (_transport_speed) {
1230 if (!Config->get_punch_in()) {
1234 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1235 RecordStateChanged (); /* EMIT SIGNAL */
1242 Session::audible_frame () const
1248 /* the first of these two possible settings for "offset"
1249 mean that the audible frame is stationary until
1250 audio emerges from the latency compensation
1253 the second means that the audible frame is stationary
1254 until audio would emerge from a physical port
1255 in the absence of any plugin latency compensation
1258 offset = _worst_output_latency;
1260 if (offset > current_block_size) {
1261 offset -= current_block_size;
1263 /* XXX is this correct? if we have no external
1264 physical connections and everything is internal
1265 then surely this is zero? still, how
1266 likely is that anyway?
1268 offset = current_block_size;
1271 if (synced_to_jack()) {
1272 tf = _engine.transport_frame();
1274 tf = _transport_frame;
1277 if (_transport_speed == 0) {
1287 if (!non_realtime_work_pending()) {
1291 /* take latency into account */
1300 Session::set_frame_rate (nframes_t frames_per_second)
1302 /** \fn void Session::set_frame_size(nframes_t)
1303 the AudioEngine object that calls this guarantees
1304 that it will not be called while we are also in
1305 ::process(). Its fine to do things that block
1309 _base_frame_rate = frames_per_second;
1313 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1315 // XXX we need some equivalent to this, somehow
1316 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1320 /* XXX need to reset/reinstantiate all LADSPA plugins */
1324 Session::set_block_size (nframes_t nframes)
1326 /* the AudioEngine guarantees
1327 that it will not be called while we are also in
1328 ::process(). It is therefore fine to do things that block
1333 vector<Sample*>::iterator i;
1336 current_block_size = nframes;
1338 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1342 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1346 _passthru_buffers.clear ();
1347 _silent_buffers.clear ();
1349 ensure_passthru_buffers (np);
1351 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1355 #ifdef NO_POSIX_MEMALIGN
1356 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1358 posix_memalign((void **)&buf,16,current_block_size * 4);
1362 memset (*i, 0, sizeof (Sample) * current_block_size);
1366 if (_gain_automation_buffer) {
1367 delete [] _gain_automation_buffer;
1369 _gain_automation_buffer = new gain_t[nframes];
1371 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1373 boost::shared_ptr<RouteList> r = routes.reader ();
1375 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1376 (*i)->set_block_size (nframes);
1379 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1380 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1381 (*i)->set_block_size (nframes);
1384 set_worst_io_latencies ();
1389 Session::set_default_fade (float steepness, float fade_msecs)
1392 nframes_t fade_frames;
1394 /* Don't allow fade of less 1 frame */
1396 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1403 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1407 default_fade_msecs = fade_msecs;
1408 default_fade_steepness = steepness;
1411 // jlc, WTF is this!
1412 Glib::RWLock::ReaderLock lm (route_lock);
1413 AudioRegion::set_default_fade (steepness, fade_frames);
1418 /* XXX have to do this at some point */
1419 /* foreach region using default fade, reset, then
1420 refill_all_diskstream_buffers ();
1425 struct RouteSorter {
1426 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1427 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1429 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1432 if (r1->fed_by.empty()) {
1433 if (r2->fed_by.empty()) {
1434 /* no ardour-based connections inbound to either route. just use signal order */
1435 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1437 /* r2 has connections, r1 does not; run r1 early */
1441 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1448 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1450 shared_ptr<Route> r2;
1452 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1453 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1457 /* make a copy of the existing list of routes that feed r1 */
1459 set<shared_ptr<Route> > existing = r1->fed_by;
1461 /* for each route that feeds r1, recurse, marking it as feeding
1465 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1468 /* r2 is a route that feeds r1 which somehow feeds base. mark
1469 base as being fed by r2
1472 rbase->fed_by.insert (r2);
1476 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1480 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1484 /* now recurse, so that we can mark base as being fed by
1485 all routes that feed r2
1488 trace_terminal (r2, rbase);
1495 Session::resort_routes ()
1497 /* don't do anything here with signals emitted
1498 by Routes while we are being destroyed.
1501 if (_state_of_the_state & Deletion) {
1508 RCUWriter<RouteList> writer (routes);
1509 shared_ptr<RouteList> r = writer.get_copy ();
1510 resort_routes_using (r);
1511 /* writer goes out of scope and forces update */
1516 Session::resort_routes_using (shared_ptr<RouteList> r)
1518 RouteList::iterator i, j;
1520 for (i = r->begin(); i != r->end(); ++i) {
1522 (*i)->fed_by.clear ();
1524 for (j = r->begin(); j != r->end(); ++j) {
1526 /* although routes can feed themselves, it will
1527 cause an endless recursive descent if we
1528 detect it. so don't bother checking for
1536 if ((*j)->feeds (*i)) {
1537 (*i)->fed_by.insert (*j);
1542 for (i = r->begin(); i != r->end(); ++i) {
1543 trace_terminal (*i, *i);
1550 cerr << "finished route resort\n";
1552 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1553 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1560 list<boost::shared_ptr<AudioTrack> >
1561 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1563 char track_name[32];
1564 uint32_t track_id = 0;
1566 uint32_t channels_used = 0;
1568 RouteList new_routes;
1569 list<boost::shared_ptr<AudioTrack> > ret;
1571 /* count existing audio tracks */
1574 shared_ptr<RouteList> r = routes.reader ();
1576 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1577 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1578 if (!(*i)->hidden()) {
1580 channels_used += (*i)->n_inputs();
1586 vector<string> physinputs;
1587 vector<string> physoutputs;
1588 uint32_t nphysical_in;
1589 uint32_t nphysical_out;
1591 _engine.get_physical_outputs (physoutputs);
1592 _engine.get_physical_inputs (physinputs);
1596 /* check for duplicate route names, since we might have pre-existing
1597 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1598 save, close,restart,add new route - first named route is now
1606 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1608 if (route_by_name (track_name) == 0) {
1612 } while (track_id < (UINT_MAX-1));
1614 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1615 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1620 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1621 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1627 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1629 if (track->ensure_io (input_channels, output_channels, false, this)) {
1630 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1631 input_channels, output_channels)
1636 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1640 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1641 port = physinputs[(channels_used+x)%nphysical_in];
1644 if (port.length() && track->connect_input (track->input (x), port, this)) {
1650 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1654 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1655 port = physoutputs[(channels_used+x)%nphysical_out];
1656 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1658 port = _master_out->input (x%_master_out->n_inputs())->name();
1662 if (port.length() && track->connect_output (track->output (x), port, this)) {
1667 channels_used += track->n_inputs ();
1670 vector<string> cports;
1671 uint32_t ni = _control_out->n_inputs();
1673 for (n = 0; n < ni; ++n) {
1674 cports.push_back (_control_out->input(n)->name());
1677 track->set_control_outs (cports);
1680 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1681 track->set_remote_control_id (ntracks());
1683 new_routes.push_back (track);
1684 ret.push_back (track);
1687 catch (failed_constructor &err) {
1688 error << _("Session: could not create new audio track.") << endmsg;
1689 // XXX should we delete the tracks already created?
1697 if (!new_routes.empty()) {
1698 add_routes (new_routes, false);
1699 save_state (_current_snapshot_name);
1706 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1709 uint32_t bus_id = 1;
1714 /* count existing audio busses */
1717 shared_ptr<RouteList> r = routes.reader ();
1719 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1720 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1721 if (!(*i)->hidden()) {
1728 vector<string> physinputs;
1729 vector<string> physoutputs;
1731 _engine.get_physical_outputs (physoutputs);
1732 _engine.get_physical_inputs (physinputs);
1739 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1741 if (route_by_name (bus_name) == 0) {
1745 } while (bus_id < (UINT_MAX-1));
1748 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1750 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1751 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1752 input_channels, output_channels)
1756 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1760 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1761 port = physinputs[((n+x)%n_physical_inputs)];
1764 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1769 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1773 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1774 port = physoutputs[((n+x)%n_physical_outputs)];
1775 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1777 port = _master_out->input (x%_master_out->n_inputs())->name();
1781 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1787 vector<string> cports;
1788 uint32_t ni = _control_out->n_inputs();
1790 for (uint32_t n = 0; n < ni; ++n) {
1791 cports.push_back (_control_out->input(n)->name());
1793 bus->set_control_outs (cports);
1796 ret.push_back (bus);
1800 catch (failed_constructor &err) {
1801 error << _("Session: could not create new audio route.") << endmsg;
1810 add_routes (ret, false);
1811 save_state (_current_snapshot_name);
1819 Session::add_routes (RouteList& new_routes, bool save)
1822 RCUWriter<RouteList> writer (routes);
1823 shared_ptr<RouteList> r = writer.get_copy ();
1824 r->insert (r->end(), new_routes.begin(), new_routes.end());
1825 resort_routes_using (r);
1828 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1830 boost::weak_ptr<Route> wpr (*x);
1832 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1833 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1834 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1835 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1837 if ((*x)->master()) {
1841 if ((*x)->control()) {
1842 _control_out = (*x);
1849 save_state (_current_snapshot_name);
1852 RouteAdded (new_routes); /* EMIT SIGNAL */
1856 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1858 /* need to do this in case we're rolling at the time, to prevent false underruns */
1859 dstream->do_refill_with_alloc();
1862 RCUWriter<DiskstreamList> writer (diskstreams);
1863 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1864 ds->push_back (dstream);
1867 dstream->set_block_size (current_block_size);
1869 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1870 /* this will connect to future changes, and check the current length */
1871 diskstream_playlist_changed (dstream);
1873 dstream->prepare ();
1877 Session::remove_route (shared_ptr<Route> route)
1880 RCUWriter<RouteList> writer (routes);
1881 shared_ptr<RouteList> rs = writer.get_copy ();
1884 /* deleting the master out seems like a dumb
1885 idea, but its more of a UI policy issue
1889 if (route == _master_out) {
1890 _master_out = shared_ptr<Route> ();
1893 if (route == _control_out) {
1894 _control_out = shared_ptr<Route> ();
1896 /* cancel control outs for all routes */
1898 vector<string> empty;
1900 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1901 (*r)->set_control_outs (empty);
1905 update_route_solo_state ();
1907 /* writer goes out of scope, forces route list update */
1910 // FIXME: audio specific
1912 boost::shared_ptr<AudioDiskstream> ds;
1914 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1915 ds = at->audio_diskstream();
1921 RCUWriter<DiskstreamList> dsl (diskstreams);
1922 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1927 find_current_end ();
1929 update_latency_compensation (false, false);
1932 /* get rid of it from the dead wood collection in the route list manager */
1934 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1938 /* try to cause everyone to drop their references */
1940 route->drop_references ();
1942 /* save the new state of the world */
1944 if (save_state (_current_snapshot_name)) {
1945 save_history (_current_snapshot_name);
1950 Session::route_mute_changed (void* src)
1956 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1958 if (solo_update_disabled) {
1964 boost::shared_ptr<Route> route = wpr.lock ();
1967 /* should not happen */
1968 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1972 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1974 shared_ptr<RouteList> r = routes.reader ();
1976 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1978 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1982 /* don't mess with busses */
1984 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1990 /* don't mess with tracks */
1992 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1997 if ((*i) != route &&
1998 ((*i)->mix_group () == 0 ||
1999 (*i)->mix_group () != route->mix_group () ||
2000 !route->mix_group ()->is_active())) {
2002 if ((*i)->soloed()) {
2004 /* if its already soloed, and solo latching is enabled,
2005 then leave it as it is.
2008 if (Config->get_solo_latched()) {
2015 solo_update_disabled = true;
2016 (*i)->set_solo (false, src);
2017 solo_update_disabled = false;
2021 bool something_soloed = false;
2022 bool same_thing_soloed = false;
2023 bool signal = false;
2025 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2026 if ((*i)->soloed()) {
2027 something_soloed = true;
2028 if (dynamic_cast<AudioTrack*>((*i).get())) {
2030 same_thing_soloed = true;
2035 same_thing_soloed = true;
2043 if (something_soloed != currently_soloing) {
2045 currently_soloing = something_soloed;
2048 modify_solo_mute (is_track, same_thing_soloed);
2051 SoloActive (currently_soloing);
2058 Session::update_route_solo_state ()
2061 bool is_track = false;
2062 bool signal = false;
2064 /* caller must hold RouteLock */
2066 /* this is where we actually implement solo by changing
2067 the solo mute setting of each track.
2070 shared_ptr<RouteList> r = routes.reader ();
2072 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2073 if ((*i)->soloed()) {
2075 if (dynamic_cast<AudioTrack*>((*i).get())) {
2082 if (mute != currently_soloing) {
2084 currently_soloing = mute;
2087 if (!is_track && !mute) {
2089 /* nothing is soloed */
2091 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2092 (*i)->set_solo_mute (false);
2102 modify_solo_mute (is_track, mute);
2105 SoloActive (currently_soloing);
2110 Session::modify_solo_mute (bool is_track, bool mute)
2112 shared_ptr<RouteList> r = routes.reader ();
2114 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2118 /* only alter track solo mute */
2120 if (dynamic_cast<AudioTrack*>((*i).get())) {
2121 if ((*i)->soloed()) {
2122 (*i)->set_solo_mute (!mute);
2124 (*i)->set_solo_mute (mute);
2130 /* only alter bus solo mute */
2132 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2134 if ((*i)->soloed()) {
2136 (*i)->set_solo_mute (false);
2140 /* don't mute master or control outs
2141 in response to another bus solo
2144 if ((*i) != _master_out &&
2145 (*i) != _control_out) {
2146 (*i)->set_solo_mute (mute);
2157 Session::catch_up_on_solo ()
2159 /* this is called after set_state() to catch the full solo
2160 state, which can't be correctly determined on a per-route
2161 basis, but needs the global overview that only the session
2164 update_route_solo_state();
2168 Session::route_by_name (string name)
2170 shared_ptr<RouteList> r = routes.reader ();
2172 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2173 if ((*i)->name() == name) {
2178 return shared_ptr<Route> ((Route*) 0);
2182 Session::route_by_id (PBD::ID id)
2184 shared_ptr<RouteList> r = routes.reader ();
2186 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2187 if ((*i)->id() == id) {
2192 return shared_ptr<Route> ((Route*) 0);
2196 Session::route_by_remote_id (uint32_t id)
2198 shared_ptr<RouteList> r = routes.reader ();
2200 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2201 if ((*i)->remote_control_id() == id) {
2206 return shared_ptr<Route> ((Route*) 0);
2210 Session::find_current_end ()
2212 if (_state_of_the_state & Loading) {
2216 nframes_t max = get_maximum_extent ();
2218 if (max > end_location->end()) {
2219 end_location->set_end (max);
2221 DurationChanged(); /* EMIT SIGNAL */
2226 Session::get_maximum_extent () const
2231 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2233 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2234 Playlist* pl = (*i)->playlist();
2235 if ((me = pl->get_maximum_extent()) > max) {
2243 boost::shared_ptr<Diskstream>
2244 Session::diskstream_by_name (string name)
2246 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2248 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2249 if ((*i)->name() == name) {
2254 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2257 boost::shared_ptr<Diskstream>
2258 Session::diskstream_by_id (const PBD::ID& id)
2260 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2262 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2263 if ((*i)->id() == id) {
2268 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2271 /* AudioRegion management */
2274 Session::new_region_name (string old)
2276 string::size_type last_period;
2278 string::size_type len = old.length() + 64;
2281 if ((last_period = old.find_last_of ('.')) == string::npos) {
2283 /* no period present - add one explicitly */
2286 last_period = old.length() - 1;
2291 number = atoi (old.substr (last_period+1).c_str());
2295 while (number < (UINT_MAX-1)) {
2297 AudioRegionList::const_iterator i;
2302 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2305 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2306 if (i->second->name() == sbuf) {
2311 if (i == audio_regions.end()) {
2316 if (number != (UINT_MAX-1)) {
2320 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2325 Session::region_name (string& result, string base, bool newlevel) const
2332 Glib::Mutex::Lock lm (region_lock);
2334 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2342 /* XXX this is going to be slow. optimize me later */
2347 string::size_type pos;
2349 pos = base.find_last_of ('.');
2351 /* pos may be npos, but then we just use entire base */
2353 subbase = base.substr (0, pos);
2357 bool name_taken = true;
2360 Glib::Mutex::Lock lm (region_lock);
2362 for (int n = 1; n < 5000; ++n) {
2365 snprintf (buf, sizeof (buf), ".%d", n);
2370 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2371 if (i->second->name() == result) {
2384 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2392 Session::add_region (boost::shared_ptr<Region> region)
2394 boost::shared_ptr<AudioRegion> ar;
2395 boost::shared_ptr<AudioRegion> oar;
2399 Glib::Mutex::Lock lm (region_lock);
2401 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2403 AudioRegionList::iterator x;
2405 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2407 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2409 if (ar->region_list_equivalent (oar)) {
2414 if (x == audio_regions.end()) {
2416 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2418 entry.first = region->id();
2421 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2433 fatal << _("programming error: ")
2434 << X_("unknown region type passed to Session::add_region()")
2441 /* mark dirty because something has changed even if we didn't
2442 add the region to the region list.
2448 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2449 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2450 AudioRegionAdded (ar); /* EMIT SIGNAL */
2455 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2457 if (what_changed & Region::HiddenChanged) {
2458 /* relay hidden changes */
2459 RegionHiddenChange (region);
2464 Session::region_renamed (boost::shared_ptr<Region> region)
2466 add_region (region);
2470 Session::remove_region (boost::shared_ptr<Region> region)
2472 AudioRegionList::iterator i;
2473 boost::shared_ptr<AudioRegion> ar;
2474 bool removed = false;
2477 Glib::Mutex::Lock lm (region_lock);
2479 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2480 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2481 audio_regions.erase (i);
2487 fatal << _("programming error: ")
2488 << X_("unknown region type passed to Session::remove_region()")
2494 /* mark dirty because something has changed even if we didn't
2495 remove the region from the region list.
2501 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2505 boost::shared_ptr<AudioRegion>
2506 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2508 AudioRegionList::iterator i;
2509 boost::shared_ptr<AudioRegion> region;
2510 Glib::Mutex::Lock lm (region_lock);
2512 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2516 if (region->whole_file()) {
2518 if (child->source_equivalent (region)) {
2524 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2528 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2530 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2531 (*i)->get_region_list_equivalent_regions (region, result);
2535 Session::destroy_region (boost::shared_ptr<Region> region)
2537 boost::shared_ptr<AudioRegion> aregion;
2539 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2543 if (aregion->playlist()) {
2544 aregion->playlist()->destroy_region (region);
2547 vector<boost::shared_ptr<Source> > srcs;
2549 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2550 srcs.push_back (aregion->source (n));
2553 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2555 if ((*i).use_count() == 1) {
2556 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2559 (afs)->mark_for_remove ();
2562 (*i)->drop_references ();
2570 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2572 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2573 destroy_region (*i);
2579 Session::remove_last_capture ()
2581 list<boost::shared_ptr<Region> > r;
2583 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2585 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2586 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2589 r.insert (r.end(), l.begin(), l.end());
2594 destroy_regions (r);
2599 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2605 /* Source Management */
2608 Session::add_source (boost::shared_ptr<Source> source)
2610 boost::shared_ptr<AudioFileSource> afs;
2612 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2614 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2615 pair<AudioSourceList::iterator,bool> result;
2617 entry.first = source->id();
2621 Glib::Mutex::Lock lm (audio_source_lock);
2622 result = audio_sources.insert (entry);
2625 if (!result.second) {
2626 cerr << "\tNOT inserted ? " << result.second << endl;
2629 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2632 SourceAdded (source); /* EMIT SIGNAL */
2634 cerr << "\tNOT AUDIO FILE\n";
2639 Session::remove_source (boost::weak_ptr<Source> src)
2641 AudioSourceList::iterator i;
2642 boost::shared_ptr<Source> source = src.lock();
2645 cerr << "removing a source DEAD\n";
2647 cerr << "removing a source " << source->name () << endl;
2650 Glib::Mutex::Lock lm (audio_source_lock);
2652 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2653 audio_sources.erase (i);
2657 if (!_state_of_the_state & InCleanup) {
2659 /* save state so we don't end up with a session file
2660 referring to non-existent sources.
2663 save_state (_current_snapshot_name);
2666 SourceRemoved(source); /* EMIT SIGNAL */
2670 boost::shared_ptr<Source>
2671 Session::source_by_id (const PBD::ID& id)
2673 Glib::Mutex::Lock lm (audio_source_lock);
2674 AudioSourceList::iterator i;
2675 boost::shared_ptr<Source> source;
2677 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2681 /* XXX search MIDI or other searches here */
2687 Session::peak_path_from_audio_path (string audio_path) const
2692 res += PBD::basename_nosuffix (audio_path);
2699 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2702 string old_basename = PBD::basename_nosuffix (oldname);
2703 string new_legalized = legalize_for_path (newname);
2705 /* note: we know (or assume) the old path is already valid */
2709 /* destructive file sources have a name of the form:
2711 /path/to/Tnnnn-NAME(%[LR])?.wav
2713 the task here is to replace NAME with the new name.
2716 /* find last slash */
2720 string::size_type slash;
2721 string::size_type dash;
2723 if ((slash = path.find_last_of ('/')) == string::npos) {
2727 dir = path.substr (0, slash+1);
2729 /* '-' is not a legal character for the NAME part of the path */
2731 if ((dash = path.find_last_of ('-')) == string::npos) {
2735 prefix = path.substr (slash+1, dash-(slash+1));
2740 path += new_legalized;
2741 path += ".wav"; /* XXX gag me with a spoon */
2745 /* non-destructive file sources have a name of the form:
2747 /path/to/NAME-nnnnn(%[LR])?.wav
2749 the task here is to replace NAME with the new name.
2754 string::size_type slash;
2755 string::size_type dash;
2756 string::size_type postfix;
2758 /* find last slash */
2760 if ((slash = path.find_last_of ('/')) == string::npos) {
2764 dir = path.substr (0, slash+1);
2766 /* '-' is not a legal character for the NAME part of the path */
2768 if ((dash = path.find_last_of ('-')) == string::npos) {
2772 suffix = path.substr (dash+1);
2774 // Suffix is now everything after the dash. Now we need to eliminate
2775 // the nnnnn part, which is done by either finding a '%' or a '.'
2777 postfix = suffix.find_last_of ("%");
2778 if (postfix == string::npos) {
2779 postfix = suffix.find_last_of ('.');
2782 if (postfix != string::npos) {
2783 suffix = suffix.substr (postfix);
2785 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2789 const uint32_t limit = 10000;
2790 char buf[PATH_MAX+1];
2792 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2794 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2796 if (access (buf, F_OK) != 0) {
2804 error << "FATAL ERROR! Could not find a " << endl;
2813 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2817 char buf[PATH_MAX+1];
2818 const uint32_t limit = 10000;
2822 legalized = legalize_for_path (name);
2824 /* find a "version" of the file name that doesn't exist in
2825 any of the possible directories.
2828 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2830 vector<space_and_path>::iterator i;
2831 uint32_t existing = 0;
2833 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2837 spath += sound_dir (false);
2841 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2842 } else if (nchan == 2) {
2844 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2846 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2848 } else if (nchan < 26) {
2849 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2851 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2859 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2860 } else if (nchan == 2) {
2862 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2864 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2866 } else if (nchan < 26) {
2867 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2869 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2873 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2879 if (existing == 0) {
2884 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2885 throw failed_constructor();
2889 /* we now have a unique name for the file, but figure out where to
2895 spath = discover_best_sound_dir ();
2897 string::size_type pos = foo.find_last_of ('/');
2899 if (pos == string::npos) {
2902 spath += foo.substr (pos + 1);
2908 boost::shared_ptr<AudioFileSource>
2909 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2911 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2912 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2915 /* Playlist management */
2918 Session::playlist_by_name (string name)
2920 Glib::Mutex::Lock lm (playlist_lock);
2921 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2922 if ((*i)->name() == name) {
2926 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2927 if ((*i)->name() == name) {
2935 Session::add_playlist (Playlist* playlist)
2937 if (playlist->hidden()) {
2942 Glib::Mutex::Lock lm (playlist_lock);
2943 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2944 playlists.insert (playlists.begin(), playlist);
2946 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2947 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2953 PlaylistAdded (playlist); /* EMIT SIGNAL */
2957 Session::track_playlist (Playlist* pl, bool inuse)
2959 PlaylistList::iterator x;
2962 Glib::Mutex::Lock lm (playlist_lock);
2965 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2967 unused_playlists.insert (pl);
2969 if ((x = playlists.find (pl)) != playlists.end()) {
2970 playlists.erase (x);
2975 //cerr << "shifting playlist to used: " << pl->name() << endl;
2977 playlists.insert (pl);
2979 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2980 unused_playlists.erase (x);
2987 Session::remove_playlist (Playlist* playlist)
2989 if (_state_of_the_state & Deletion) {
2994 Glib::Mutex::Lock lm (playlist_lock);
2995 // cerr << "removing playlist: " << playlist->name() << endl;
2997 PlaylistList::iterator i;
2999 i = find (playlists.begin(), playlists.end(), playlist);
3001 if (i != playlists.end()) {
3002 playlists.erase (i);
3005 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3006 if (i != unused_playlists.end()) {
3007 unused_playlists.erase (i);
3014 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3018 Session::set_audition (boost::shared_ptr<Region> r)
3020 pending_audition_region = r;
3021 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3022 schedule_butler_transport_work ();
3026 Session::audition_playlist ()
3028 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3029 ev->region.reset ();
3034 Session::non_realtime_set_audition ()
3036 if (!pending_audition_region) {
3037 auditioner->audition_current_playlist ();
3039 auditioner->audition_region (pending_audition_region);
3040 pending_audition_region.reset ();
3042 AuditionActive (true); /* EMIT SIGNAL */
3046 Session::audition_region (boost::shared_ptr<Region> r)
3048 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3054 Session::cancel_audition ()
3056 if (auditioner->active()) {
3057 auditioner->cancel_audition ();
3058 AuditionActive (false); /* EMIT SIGNAL */
3063 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3065 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3069 Session::remove_empty_sounds ()
3071 PathScanner scanner;
3073 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3075 Glib::Mutex::Lock lm (audio_source_lock);
3077 regex_t compiled_tape_track_pattern;
3080 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3084 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3086 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3090 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3092 /* never remove files that appear to be a tape track */
3094 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3099 if (AudioFileSource::is_empty (*this, *(*i))) {
3101 unlink ((*i)->c_str());
3103 string peak_path = peak_path_from_audio_path (**i);
3104 unlink (peak_path.c_str());
3110 delete possible_audiofiles;
3114 Session::is_auditioning () const
3116 /* can be called before we have an auditioner object */
3118 return auditioner->active();
3125 Session::set_all_solo (bool yn)
3127 shared_ptr<RouteList> r = routes.reader ();
3129 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3130 if (!(*i)->hidden()) {
3131 (*i)->set_solo (yn, this);
3139 Session::set_all_mute (bool yn)
3141 shared_ptr<RouteList> r = routes.reader ();
3143 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3144 if (!(*i)->hidden()) {
3145 (*i)->set_mute (yn, this);
3153 Session::n_diskstreams () const
3157 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3159 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3160 if (!(*i)->hidden()) {
3168 Session::graph_reordered ()
3170 /* don't do this stuff if we are setting up connections
3171 from a set_state() call.
3174 if (_state_of_the_state & InitialConnecting) {
3180 /* force all diskstreams to update their capture offset values to
3181 reflect any changes in latencies within the graph.
3184 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3186 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3187 (*i)->set_capture_offset ();
3192 Session::record_disenable_all ()
3194 record_enable_change_all (false);
3198 Session::record_enable_all ()
3200 record_enable_change_all (true);
3204 Session::record_enable_change_all (bool yn)
3206 shared_ptr<RouteList> r = routes.reader ();
3208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3211 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3212 at->set_record_enable (yn, this);
3216 /* since we don't keep rec-enable state, don't mark session dirty */
3220 Session::add_redirect (Redirect* redirect)
3224 PortInsert* port_insert;
3225 PluginInsert* plugin_insert;
3227 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3228 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3229 _port_inserts.insert (_port_inserts.begin(), port_insert);
3230 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3231 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3233 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3236 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3237 _sends.insert (_sends.begin(), send);
3239 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3243 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3249 Session::remove_redirect (Redirect* redirect)
3253 PortInsert* port_insert;
3254 PluginInsert* plugin_insert;
3256 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3257 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3258 _port_inserts.remove (port_insert);
3259 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3260 _plugin_inserts.remove (plugin_insert);
3262 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3265 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3266 _sends.remove (send);
3268 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3276 Session::available_capture_duration ()
3278 const double scale = 4096.0 / sizeof (Sample);
3280 if (_total_free_4k_blocks * scale > (double) max_frames) {
3284 return (nframes_t) floor (_total_free_4k_blocks * scale);
3288 Session::add_connection (ARDOUR::Connection* connection)
3291 Glib::Mutex::Lock guard (connection_lock);
3292 _connections.push_back (connection);
3295 ConnectionAdded (connection); /* EMIT SIGNAL */
3301 Session::remove_connection (ARDOUR::Connection* connection)
3303 bool removed = false;
3306 Glib::Mutex::Lock guard (connection_lock);
3307 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3309 if (i != _connections.end()) {
3310 _connections.erase (i);
3316 ConnectionRemoved (connection); /* EMIT SIGNAL */
3322 ARDOUR::Connection *
3323 Session::connection_by_name (string name) const
3325 Glib::Mutex::Lock lm (connection_lock);
3327 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3328 if ((*i)->name() == name) {
3337 Session::tempo_map_changed (Change ignored)
3344 Session::ensure_passthru_buffers (uint32_t howmany)
3346 while (howmany > _passthru_buffers.size()) {
3348 #ifdef NO_POSIX_MEMALIGN
3349 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3351 posix_memalign((void **)&p,16,current_block_size * 4);
3353 _passthru_buffers.push_back (p);
3357 #ifdef NO_POSIX_MEMALIGN
3358 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3360 posix_memalign((void **)&p,16,current_block_size * 4);
3362 memset (p, 0, sizeof (Sample) * current_block_size);
3363 _silent_buffers.push_back (p);
3367 #ifdef NO_POSIX_MEMALIGN
3368 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3370 posix_memalign((void **)&p,16,current_block_size * 4);
3372 memset (p, 0, sizeof (Sample) * current_block_size);
3373 _send_buffers.push_back (p);
3376 allocate_pan_automation_buffers (current_block_size, howmany, false);
3380 Session::next_send_name ()
3383 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3388 Session::next_insert_name ()
3391 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3395 /* Named Selection management */
3398 Session::named_selection_by_name (string name)
3400 Glib::Mutex::Lock lm (named_selection_lock);
3401 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3402 if ((*i)->name == name) {
3410 Session::add_named_selection (NamedSelection* named_selection)
3413 Glib::Mutex::Lock lm (named_selection_lock);
3414 named_selections.insert (named_selections.begin(), named_selection);
3419 NamedSelectionAdded (); /* EMIT SIGNAL */
3423 Session::remove_named_selection (NamedSelection* named_selection)
3425 bool removed = false;
3428 Glib::Mutex::Lock lm (named_selection_lock);
3430 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3432 if (i != named_selections.end()) {
3434 named_selections.erase (i);
3441 NamedSelectionRemoved (); /* EMIT SIGNAL */
3446 Session::reset_native_file_format ()
3448 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3450 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3451 (*i)->reset_write_sources (false);
3456 Session::route_name_unique (string n) const
3458 shared_ptr<RouteList> r = routes.reader ();
3460 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3461 if ((*i)->name() == n) {
3470 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3472 return fs->move_to_trash (dead_sound_dir_name);
3476 Session::n_playlists () const
3478 Glib::Mutex::Lock lm (playlist_lock);
3479 return playlists.size();
3483 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3485 if (!force && howmany <= _npan_buffers) {
3489 if (_pan_automation_buffer) {
3491 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3492 delete [] _pan_automation_buffer[i];
3495 delete [] _pan_automation_buffer;
3498 _pan_automation_buffer = new pan_t*[howmany];
3500 for (uint32_t i = 0; i < howmany; ++i) {
3501 _pan_automation_buffer[i] = new pan_t[nframes];
3504 _npan_buffers = howmany;
3508 Session::freeze (InterThreadInfo& itt)
3510 shared_ptr<RouteList> r = routes.reader ();
3512 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3516 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3517 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3528 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3529 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3533 boost::shared_ptr<AudioFileSource> fsource;
3535 char buf[PATH_MAX+1];
3539 nframes_t this_chunk;
3541 vector<Sample*> buffers;
3543 // any bigger than this seems to cause stack overflows in called functions
3544 const nframes_t chunk_size = (128 * 1024)/4;
3546 g_atomic_int_set (&processing_prohibited, 1);
3548 /* call tree *MUST* hold route_lock */
3550 if ((playlist = track.diskstream()->playlist()) == 0) {
3554 /* external redirects will be a problem */
3556 if (track.has_external_redirects()) {
3560 nchans = track.audio_diskstream()->n_channels();
3562 dir = discover_best_sound_dir ();
3564 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3566 for (x = 0; x < 99999; ++x) {
3567 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3568 if (access (buf, F_OK) != 0) {
3574 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3579 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3582 catch (failed_constructor& err) {
3583 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3587 srcs.push_back (fsource);
3590 /* XXX need to flush all redirects */
3595 /* create a set of reasonably-sized buffers */
3597 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3599 #ifdef NO_POSIX_MEMALIGN
3600 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3602 posix_memalign((void **)&b,16,chunk_size * 4);
3604 buffers.push_back (b);
3607 while (to_do && !itt.cancel) {
3609 this_chunk = min (to_do, chunk_size);
3611 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3616 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3617 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3620 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3626 start += this_chunk;
3627 to_do -= this_chunk;
3629 itt.progress = (float) (1.0 - ((double) to_do / len));
3638 xnow = localtime (&now);
3640 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3641 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3644 afs->update_header (position, *xnow, now);
3648 /* build peakfile for new source */
3650 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3651 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3653 afs->build_peaks ();
3657 /* construct a region to represent the bounced material */
3659 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3660 region_name_from_path (srcs.front()->name()));
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->mark_for_remove ();
3674 (*src)->drop_references ();
3678 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3682 g_atomic_int_set (&processing_prohibited, 0);
3690 Session::get_silent_buffers (uint32_t howmany)
3692 for (uint32_t i = 0; i < howmany; ++i) {
3693 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3695 return _silent_buffers;
3699 Session::ntracks () const
3702 shared_ptr<RouteList> r = routes.reader ();
3704 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3705 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3714 Session::nbusses () const
3717 shared_ptr<RouteList> r = routes.reader ();
3719 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3720 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3729 Session::add_curve(Curve *curve)
3731 curves[curve->id()] = curve;
3735 Session::add_automation_list(AutomationList *al)
3737 automation_lists[al->id()] = al;