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 /* this function is currently called from somewhere other than an RT thread.
1224 this save_state() call therefore doesn't impact anything.
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 // XXX we need some equivalent to this, somehow
1314 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1318 /* XXX need to reset/reinstantiate all LADSPA plugins */
1322 Session::set_block_size (nframes_t nframes)
1324 /* the AudioEngine guarantees
1325 that it will not be called while we are also in
1326 ::process(). It is therefore fine to do things that block
1331 vector<Sample*>::iterator i;
1334 current_block_size = nframes;
1336 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1340 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1344 _passthru_buffers.clear ();
1345 _silent_buffers.clear ();
1347 ensure_passthru_buffers (np);
1349 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1353 #ifdef NO_POSIX_MEMALIGN
1354 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1356 posix_memalign((void **)&buf,16,current_block_size * 4);
1360 memset (*i, 0, sizeof (Sample) * current_block_size);
1364 if (_gain_automation_buffer) {
1365 delete [] _gain_automation_buffer;
1367 _gain_automation_buffer = new gain_t[nframes];
1369 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1371 boost::shared_ptr<RouteList> r = routes.reader ();
1373 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1374 (*i)->set_block_size (nframes);
1377 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1378 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1379 (*i)->set_block_size (nframes);
1382 set_worst_io_latencies ();
1387 Session::set_default_fade (float steepness, float fade_msecs)
1390 nframes_t fade_frames;
1392 /* Don't allow fade of less 1 frame */
1394 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1401 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1405 default_fade_msecs = fade_msecs;
1406 default_fade_steepness = steepness;
1409 // jlc, WTF is this!
1410 Glib::RWLock::ReaderLock lm (route_lock);
1411 AudioRegion::set_default_fade (steepness, fade_frames);
1416 /* XXX have to do this at some point */
1417 /* foreach region using default fade, reset, then
1418 refill_all_diskstream_buffers ();
1423 struct RouteSorter {
1424 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1425 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1427 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1430 if (r1->fed_by.empty()) {
1431 if (r2->fed_by.empty()) {
1432 /* no ardour-based connections inbound to either route. just use signal order */
1433 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1435 /* r2 has connections, r1 does not; run r1 early */
1439 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1446 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1448 shared_ptr<Route> r2;
1450 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1451 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1455 /* make a copy of the existing list of routes that feed r1 */
1457 set<shared_ptr<Route> > existing = r1->fed_by;
1459 /* for each route that feeds r1, recurse, marking it as feeding
1463 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1466 /* r2 is a route that feeds r1 which somehow feeds base. mark
1467 base as being fed by r2
1470 rbase->fed_by.insert (r2);
1474 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1478 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1482 /* now recurse, so that we can mark base as being fed by
1483 all routes that feed r2
1486 trace_terminal (r2, rbase);
1493 Session::resort_routes ()
1495 /* don't do anything here with signals emitted
1496 by Routes while we are being destroyed.
1499 if (_state_of_the_state & Deletion) {
1506 RCUWriter<RouteList> writer (routes);
1507 shared_ptr<RouteList> r = writer.get_copy ();
1508 resort_routes_using (r);
1509 /* writer goes out of scope and forces update */
1514 Session::resort_routes_using (shared_ptr<RouteList> r)
1516 RouteList::iterator i, j;
1518 for (i = r->begin(); i != r->end(); ++i) {
1520 (*i)->fed_by.clear ();
1522 for (j = r->begin(); j != r->end(); ++j) {
1524 /* although routes can feed themselves, it will
1525 cause an endless recursive descent if we
1526 detect it. so don't bother checking for
1534 if ((*j)->feeds (*i)) {
1535 (*i)->fed_by.insert (*j);
1540 for (i = r->begin(); i != r->end(); ++i) {
1541 trace_terminal (*i, *i);
1548 cerr << "finished route resort\n";
1550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1551 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1558 list<boost::shared_ptr<AudioTrack> >
1559 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1561 char track_name[32];
1562 uint32_t track_id = 0;
1564 uint32_t channels_used = 0;
1566 RouteList new_routes;
1567 list<boost::shared_ptr<AudioTrack> > ret;
1569 /* count existing audio tracks */
1572 shared_ptr<RouteList> r = routes.reader ();
1574 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1575 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1576 if (!(*i)->hidden()) {
1578 channels_used += (*i)->n_inputs();
1584 vector<string> physinputs;
1585 vector<string> physoutputs;
1586 uint32_t nphysical_in;
1587 uint32_t nphysical_out;
1589 _engine.get_physical_outputs (physoutputs);
1590 _engine.get_physical_inputs (physinputs);
1594 /* check for duplicate route names, since we might have pre-existing
1595 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1596 save, close,restart,add new route - first named route is now
1604 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1606 if (route_by_name (track_name) == 0) {
1610 } while (track_id < (UINT_MAX-1));
1612 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1613 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1618 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1619 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1625 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1627 if (track->ensure_io (input_channels, output_channels, false, this)) {
1628 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1629 input_channels, output_channels)
1634 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1638 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1639 port = physinputs[(channels_used+x)%nphysical_in];
1642 if (port.length() && track->connect_input (track->input (x), port, this)) {
1648 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1652 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1653 port = physoutputs[(channels_used+x)%nphysical_out];
1654 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1656 port = _master_out->input (x%_master_out->n_inputs())->name();
1660 if (port.length() && track->connect_output (track->output (x), port, this)) {
1665 channels_used += track->n_inputs ();
1668 vector<string> cports;
1669 uint32_t ni = _control_out->n_inputs();
1671 for (n = 0; n < ni; ++n) {
1672 cports.push_back (_control_out->input(n)->name());
1675 track->set_control_outs (cports);
1678 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1679 track->set_remote_control_id (ntracks());
1681 new_routes.push_back (track);
1682 ret.push_back (track);
1685 catch (failed_constructor &err) {
1686 error << _("Session: could not create new audio track.") << endmsg;
1687 // XXX should we delete the tracks already created?
1695 if (!new_routes.empty()) {
1696 add_routes (new_routes, false);
1697 save_state (_current_snapshot_name);
1704 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1707 uint32_t bus_id = 1;
1712 /* count existing audio busses */
1715 shared_ptr<RouteList> r = routes.reader ();
1717 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1718 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1719 if (!(*i)->hidden()) {
1726 vector<string> physinputs;
1727 vector<string> physoutputs;
1729 _engine.get_physical_outputs (physoutputs);
1730 _engine.get_physical_inputs (physinputs);
1737 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1739 if (route_by_name (bus_name) == 0) {
1743 } while (bus_id < (UINT_MAX-1));
1746 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1748 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1749 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1750 input_channels, output_channels)
1754 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1758 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1759 port = physinputs[((n+x)%n_physical_inputs)];
1762 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1767 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1771 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1772 port = physoutputs[((n+x)%n_physical_outputs)];
1773 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1775 port = _master_out->input (x%_master_out->n_inputs())->name();
1779 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1785 vector<string> cports;
1786 uint32_t ni = _control_out->n_inputs();
1788 for (uint32_t n = 0; n < ni; ++n) {
1789 cports.push_back (_control_out->input(n)->name());
1791 bus->set_control_outs (cports);
1794 ret.push_back (bus);
1798 catch (failed_constructor &err) {
1799 error << _("Session: could not create new audio route.") << endmsg;
1808 add_routes (ret, false);
1809 save_state (_current_snapshot_name);
1817 Session::add_routes (RouteList& new_routes, bool save)
1820 RCUWriter<RouteList> writer (routes);
1821 shared_ptr<RouteList> r = writer.get_copy ();
1822 r->insert (r->end(), new_routes.begin(), new_routes.end());
1823 resort_routes_using (r);
1826 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1828 boost::weak_ptr<Route> wpr (*x);
1830 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1831 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1832 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1833 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1835 if ((*x)->master()) {
1839 if ((*x)->control()) {
1840 _control_out = (*x);
1847 save_state (_current_snapshot_name);
1850 RouteAdded (new_routes); /* EMIT SIGNAL */
1854 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1856 /* need to do this in case we're rolling at the time, to prevent false underruns */
1857 dstream->do_refill_with_alloc();
1860 RCUWriter<DiskstreamList> writer (diskstreams);
1861 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1862 ds->push_back (dstream);
1865 dstream->set_block_size (current_block_size);
1867 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1868 /* this will connect to future changes, and check the current length */
1869 diskstream_playlist_changed (dstream);
1871 dstream->prepare ();
1875 Session::remove_route (shared_ptr<Route> route)
1878 RCUWriter<RouteList> writer (routes);
1879 shared_ptr<RouteList> rs = writer.get_copy ();
1882 /* deleting the master out seems like a dumb
1883 idea, but its more of a UI policy issue
1887 if (route == _master_out) {
1888 _master_out = shared_ptr<Route> ();
1891 if (route == _control_out) {
1892 _control_out = shared_ptr<Route> ();
1894 /* cancel control outs for all routes */
1896 vector<string> empty;
1898 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1899 (*r)->set_control_outs (empty);
1903 update_route_solo_state ();
1905 /* writer goes out of scope, forces route list update */
1908 // FIXME: audio specific
1910 boost::shared_ptr<AudioDiskstream> ds;
1912 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1913 ds = at->audio_diskstream();
1919 RCUWriter<DiskstreamList> dsl (diskstreams);
1920 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1925 find_current_end ();
1927 update_latency_compensation (false, false);
1930 // We need to disconnect the routes inputs and outputs
1931 route->disconnect_inputs(NULL);
1932 route->disconnect_outputs(NULL);
1934 /* get rid of it from the dead wood collection in the route list manager */
1936 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1940 /* try to cause everyone to drop their references */
1942 route->drop_references ();
1944 /* save the new state of the world */
1946 if (save_state (_current_snapshot_name)) {
1947 save_history (_current_snapshot_name);
1952 Session::route_mute_changed (void* src)
1958 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1960 if (solo_update_disabled) {
1966 boost::shared_ptr<Route> route = wpr.lock ();
1969 /* should not happen */
1970 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1974 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1976 shared_ptr<RouteList> r = routes.reader ();
1978 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1980 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1984 /* don't mess with busses */
1986 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1992 /* don't mess with tracks */
1994 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1999 if ((*i) != route &&
2000 ((*i)->mix_group () == 0 ||
2001 (*i)->mix_group () != route->mix_group () ||
2002 !route->mix_group ()->is_active())) {
2004 if ((*i)->soloed()) {
2006 /* if its already soloed, and solo latching is enabled,
2007 then leave it as it is.
2010 if (Config->get_solo_latched()) {
2017 solo_update_disabled = true;
2018 (*i)->set_solo (false, src);
2019 solo_update_disabled = false;
2023 bool something_soloed = false;
2024 bool same_thing_soloed = false;
2025 bool signal = false;
2027 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2028 if ((*i)->soloed()) {
2029 something_soloed = true;
2030 if (dynamic_cast<AudioTrack*>((*i).get())) {
2032 same_thing_soloed = true;
2037 same_thing_soloed = true;
2045 if (something_soloed != currently_soloing) {
2047 currently_soloing = something_soloed;
2050 modify_solo_mute (is_track, same_thing_soloed);
2053 SoloActive (currently_soloing);
2060 Session::update_route_solo_state ()
2063 bool is_track = false;
2064 bool signal = false;
2066 /* caller must hold RouteLock */
2068 /* this is where we actually implement solo by changing
2069 the solo mute setting of each track.
2072 shared_ptr<RouteList> r = routes.reader ();
2074 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2075 if ((*i)->soloed()) {
2077 if (dynamic_cast<AudioTrack*>((*i).get())) {
2084 if (mute != currently_soloing) {
2086 currently_soloing = mute;
2089 if (!is_track && !mute) {
2091 /* nothing is soloed */
2093 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2094 (*i)->set_solo_mute (false);
2104 modify_solo_mute (is_track, mute);
2107 SoloActive (currently_soloing);
2112 Session::modify_solo_mute (bool is_track, bool mute)
2114 shared_ptr<RouteList> r = routes.reader ();
2116 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2120 /* only alter track solo mute */
2122 if (dynamic_cast<AudioTrack*>((*i).get())) {
2123 if ((*i)->soloed()) {
2124 (*i)->set_solo_mute (!mute);
2126 (*i)->set_solo_mute (mute);
2132 /* only alter bus solo mute */
2134 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2136 if ((*i)->soloed()) {
2138 (*i)->set_solo_mute (false);
2142 /* don't mute master or control outs
2143 in response to another bus solo
2146 if ((*i) != _master_out &&
2147 (*i) != _control_out) {
2148 (*i)->set_solo_mute (mute);
2159 Session::catch_up_on_solo ()
2161 /* this is called after set_state() to catch the full solo
2162 state, which can't be correctly determined on a per-route
2163 basis, but needs the global overview that only the session
2166 update_route_solo_state();
2170 Session::route_by_name (string name)
2172 shared_ptr<RouteList> r = routes.reader ();
2174 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2175 if ((*i)->name() == name) {
2180 return shared_ptr<Route> ((Route*) 0);
2184 Session::route_by_id (PBD::ID id)
2186 shared_ptr<RouteList> r = routes.reader ();
2188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2189 if ((*i)->id() == id) {
2194 return shared_ptr<Route> ((Route*) 0);
2198 Session::route_by_remote_id (uint32_t id)
2200 shared_ptr<RouteList> r = routes.reader ();
2202 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2203 if ((*i)->remote_control_id() == id) {
2208 return shared_ptr<Route> ((Route*) 0);
2212 Session::find_current_end ()
2214 if (_state_of_the_state & Loading) {
2218 nframes_t max = get_maximum_extent ();
2220 if (max > end_location->end()) {
2221 end_location->set_end (max);
2223 DurationChanged(); /* EMIT SIGNAL */
2228 Session::get_maximum_extent () const
2233 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2235 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2236 Playlist* pl = (*i)->playlist();
2237 if ((me = pl->get_maximum_extent()) > max) {
2245 boost::shared_ptr<Diskstream>
2246 Session::diskstream_by_name (string name)
2248 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2250 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2251 if ((*i)->name() == name) {
2256 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2259 boost::shared_ptr<Diskstream>
2260 Session::diskstream_by_id (const PBD::ID& id)
2262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2264 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2265 if ((*i)->id() == id) {
2270 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2273 /* AudioRegion management */
2276 Session::new_region_name (string old)
2278 string::size_type last_period;
2280 string::size_type len = old.length() + 64;
2283 if ((last_period = old.find_last_of ('.')) == string::npos) {
2285 /* no period present - add one explicitly */
2288 last_period = old.length() - 1;
2293 number = atoi (old.substr (last_period+1).c_str());
2297 while (number < (UINT_MAX-1)) {
2299 AudioRegionList::const_iterator i;
2304 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2307 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2308 if (i->second->name() == sbuf) {
2313 if (i == audio_regions.end()) {
2318 if (number != (UINT_MAX-1)) {
2322 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2327 Session::region_name (string& result, string base, bool newlevel) const
2334 Glib::Mutex::Lock lm (region_lock);
2336 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2344 /* XXX this is going to be slow. optimize me later */
2349 string::size_type pos;
2351 pos = base.find_last_of ('.');
2353 /* pos may be npos, but then we just use entire base */
2355 subbase = base.substr (0, pos);
2359 bool name_taken = true;
2362 Glib::Mutex::Lock lm (region_lock);
2364 for (int n = 1; n < 5000; ++n) {
2367 snprintf (buf, sizeof (buf), ".%d", n);
2372 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2373 if (i->second->name() == result) {
2386 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2394 Session::add_region (boost::shared_ptr<Region> region)
2396 boost::shared_ptr<AudioRegion> ar;
2397 boost::shared_ptr<AudioRegion> oar;
2401 Glib::Mutex::Lock lm (region_lock);
2403 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2405 AudioRegionList::iterator x;
2407 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2409 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2411 if (ar->region_list_equivalent (oar)) {
2416 if (x == audio_regions.end()) {
2418 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2420 entry.first = region->id();
2423 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2435 fatal << _("programming error: ")
2436 << X_("unknown region type passed to Session::add_region()")
2443 /* mark dirty because something has changed even if we didn't
2444 add the region to the region list.
2450 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2451 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2452 AudioRegionAdded (ar); /* EMIT SIGNAL */
2457 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2459 if (what_changed & Region::HiddenChanged) {
2460 /* relay hidden changes */
2461 RegionHiddenChange (region);
2466 Session::region_renamed (boost::shared_ptr<Region> region)
2468 add_region (region);
2472 Session::remove_region (boost::shared_ptr<Region> region)
2474 AudioRegionList::iterator i;
2475 boost::shared_ptr<AudioRegion> ar;
2476 bool removed = false;
2479 Glib::Mutex::Lock lm (region_lock);
2481 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2482 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2483 audio_regions.erase (i);
2490 fatal << _("programming error: ")
2491 << X_("unknown region type passed to Session::remove_region()")
2497 /* mark dirty because something has changed even if we didn't
2498 remove the region from the region list.
2504 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2508 boost::shared_ptr<AudioRegion>
2509 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2511 AudioRegionList::iterator i;
2512 boost::shared_ptr<AudioRegion> region;
2513 Glib::Mutex::Lock lm (region_lock);
2515 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2519 if (region->whole_file()) {
2521 if (child->source_equivalent (region)) {
2527 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2531 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2533 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2534 (*i)->get_region_list_equivalent_regions (region, result);
2538 Session::destroy_region (boost::shared_ptr<Region> region)
2540 boost::shared_ptr<AudioRegion> aregion;
2542 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2546 if (aregion->playlist()) {
2547 aregion->playlist()->destroy_region (region);
2550 vector<boost::shared_ptr<Source> > srcs;
2552 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2553 srcs.push_back (aregion->source (n));
2556 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2558 if ((*i).use_count() == 1) {
2559 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2562 (afs)->mark_for_remove ();
2565 (*i)->drop_references ();
2573 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2575 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2576 destroy_region (*i);
2582 Session::remove_last_capture ()
2584 list<boost::shared_ptr<Region> > r;
2586 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2588 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2589 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2592 r.insert (r.end(), l.begin(), l.end());
2597 destroy_regions (r);
2602 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2608 /* Source Management */
2611 Session::add_source (boost::shared_ptr<Source> source)
2613 boost::shared_ptr<AudioFileSource> afs;
2615 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2617 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2618 pair<AudioSourceList::iterator,bool> result;
2620 entry.first = source->id();
2624 Glib::Mutex::Lock lm (audio_source_lock);
2625 result = audio_sources.insert (entry);
2628 if (!result.second) {
2629 cerr << "\tNOT inserted ? " << result.second << endl;
2632 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2635 SourceAdded (source); /* EMIT SIGNAL */
2637 cerr << "\tNOT AUDIO FILE\n";
2642 Session::remove_source (boost::weak_ptr<Source> src)
2644 AudioSourceList::iterator i;
2645 boost::shared_ptr<Source> source = src.lock();
2652 Glib::Mutex::Lock lm (audio_source_lock);
2654 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2655 audio_sources.erase (i);
2659 if (!_state_of_the_state & InCleanup) {
2661 /* save state so we don't end up with a session file
2662 referring to non-existent sources.
2665 save_state (_current_snapshot_name);
2668 SourceRemoved(source); /* EMIT SIGNAL */
2671 boost::shared_ptr<Source>
2672 Session::source_by_id (const PBD::ID& id)
2674 Glib::Mutex::Lock lm (audio_source_lock);
2675 AudioSourceList::iterator i;
2676 boost::shared_ptr<Source> source;
2678 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2682 /* XXX search MIDI or other searches here */
2688 Session::peak_path_from_audio_path (string audio_path) const
2693 res += PBD::basename_nosuffix (audio_path);
2700 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2703 string old_basename = PBD::basename_nosuffix (oldname);
2704 string new_legalized = legalize_for_path (newname);
2706 /* note: we know (or assume) the old path is already valid */
2710 /* destructive file sources have a name of the form:
2712 /path/to/Tnnnn-NAME(%[LR])?.wav
2714 the task here is to replace NAME with the new name.
2717 /* find last slash */
2721 string::size_type slash;
2722 string::size_type dash;
2724 if ((slash = path.find_last_of ('/')) == string::npos) {
2728 dir = path.substr (0, slash+1);
2730 /* '-' is not a legal character for the NAME part of the path */
2732 if ((dash = path.find_last_of ('-')) == string::npos) {
2736 prefix = path.substr (slash+1, dash-(slash+1));
2741 path += new_legalized;
2742 path += ".wav"; /* XXX gag me with a spoon */
2746 /* non-destructive file sources have a name of the form:
2748 /path/to/NAME-nnnnn(%[LR])?.wav
2750 the task here is to replace NAME with the new name.
2755 string::size_type slash;
2756 string::size_type dash;
2757 string::size_type postfix;
2759 /* find last slash */
2761 if ((slash = path.find_last_of ('/')) == string::npos) {
2765 dir = path.substr (0, slash+1);
2767 /* '-' is not a legal character for the NAME part of the path */
2769 if ((dash = path.find_last_of ('-')) == string::npos) {
2773 suffix = path.substr (dash+1);
2775 // Suffix is now everything after the dash. Now we need to eliminate
2776 // the nnnnn part, which is done by either finding a '%' or a '.'
2778 postfix = suffix.find_last_of ("%");
2779 if (postfix == string::npos) {
2780 postfix = suffix.find_last_of ('.');
2783 if (postfix != string::npos) {
2784 suffix = suffix.substr (postfix);
2786 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2790 const uint32_t limit = 10000;
2791 char buf[PATH_MAX+1];
2793 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2795 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2797 if (access (buf, F_OK) != 0) {
2805 error << "FATAL ERROR! Could not find a " << endl;
2814 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2818 char buf[PATH_MAX+1];
2819 const uint32_t limit = 10000;
2823 legalized = legalize_for_path (name);
2825 /* find a "version" of the file name that doesn't exist in
2826 any of the possible directories.
2829 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2831 vector<space_and_path>::iterator i;
2832 uint32_t existing = 0;
2834 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2838 spath += sound_dir (false);
2842 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2843 } else if (nchan == 2) {
2845 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2847 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2849 } else if (nchan < 26) {
2850 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2852 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2860 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2861 } else if (nchan == 2) {
2863 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2865 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2867 } else if (nchan < 26) {
2868 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2870 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2874 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2880 if (existing == 0) {
2885 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2886 throw failed_constructor();
2890 /* we now have a unique name for the file, but figure out where to
2896 spath = discover_best_sound_dir ();
2898 string::size_type pos = foo.find_last_of ('/');
2900 if (pos == string::npos) {
2903 spath += foo.substr (pos + 1);
2909 boost::shared_ptr<AudioFileSource>
2910 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2912 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2913 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2916 /* Playlist management */
2919 Session::playlist_by_name (string name)
2921 Glib::Mutex::Lock lm (playlist_lock);
2922 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2923 if ((*i)->name() == name) {
2927 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2928 if ((*i)->name() == name) {
2936 Session::add_playlist (Playlist* playlist)
2938 if (playlist->hidden()) {
2943 Glib::Mutex::Lock lm (playlist_lock);
2944 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2945 playlists.insert (playlists.begin(), playlist);
2947 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2948 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2954 PlaylistAdded (playlist); /* EMIT SIGNAL */
2958 Session::track_playlist (Playlist* pl, bool inuse)
2960 PlaylistList::iterator x;
2963 Glib::Mutex::Lock lm (playlist_lock);
2966 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2968 unused_playlists.insert (pl);
2970 if ((x = playlists.find (pl)) != playlists.end()) {
2971 playlists.erase (x);
2976 //cerr << "shifting playlist to used: " << pl->name() << endl;
2978 playlists.insert (pl);
2980 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2981 unused_playlists.erase (x);
2988 Session::remove_playlist (Playlist* playlist)
2990 if (_state_of_the_state & Deletion) {
2995 Glib::Mutex::Lock lm (playlist_lock);
2996 // cerr << "removing playlist: " << playlist->name() << endl;
2998 PlaylistList::iterator i;
3000 i = find (playlists.begin(), playlists.end(), playlist);
3002 if (i != playlists.end()) {
3003 playlists.erase (i);
3006 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3007 if (i != unused_playlists.end()) {
3008 unused_playlists.erase (i);
3015 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3019 Session::set_audition (boost::shared_ptr<Region> r)
3021 pending_audition_region = r;
3022 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3023 schedule_butler_transport_work ();
3027 Session::audition_playlist ()
3029 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3030 ev->region.reset ();
3035 Session::non_realtime_set_audition ()
3037 if (!pending_audition_region) {
3038 auditioner->audition_current_playlist ();
3040 auditioner->audition_region (pending_audition_region);
3041 pending_audition_region.reset ();
3043 AuditionActive (true); /* EMIT SIGNAL */
3047 Session::audition_region (boost::shared_ptr<Region> r)
3049 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3055 Session::cancel_audition ()
3057 if (auditioner->active()) {
3058 auditioner->cancel_audition ();
3059 AuditionActive (false); /* EMIT SIGNAL */
3064 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3066 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3070 Session::remove_empty_sounds ()
3072 PathScanner scanner;
3074 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3076 Glib::Mutex::Lock lm (audio_source_lock);
3078 regex_t compiled_tape_track_pattern;
3081 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3085 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3087 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3091 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3093 /* never remove files that appear to be a tape track */
3095 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3100 if (AudioFileSource::is_empty (*this, *(*i))) {
3102 unlink ((*i)->c_str());
3104 string peak_path = peak_path_from_audio_path (**i);
3105 unlink (peak_path.c_str());
3111 delete possible_audiofiles;
3115 Session::is_auditioning () const
3117 /* can be called before we have an auditioner object */
3119 return auditioner->active();
3126 Session::set_all_solo (bool yn)
3128 shared_ptr<RouteList> r = routes.reader ();
3130 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3131 if (!(*i)->hidden()) {
3132 (*i)->set_solo (yn, this);
3140 Session::set_all_mute (bool yn)
3142 shared_ptr<RouteList> r = routes.reader ();
3144 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3145 if (!(*i)->hidden()) {
3146 (*i)->set_mute (yn, this);
3154 Session::n_diskstreams () const
3158 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3160 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3161 if (!(*i)->hidden()) {
3169 Session::graph_reordered ()
3171 /* don't do this stuff if we are setting up connections
3172 from a set_state() call.
3175 if (_state_of_the_state & InitialConnecting) {
3181 /* force all diskstreams to update their capture offset values to
3182 reflect any changes in latencies within the graph.
3185 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3187 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3188 (*i)->set_capture_offset ();
3193 Session::record_disenable_all ()
3195 record_enable_change_all (false);
3199 Session::record_enable_all ()
3201 record_enable_change_all (true);
3205 Session::record_enable_change_all (bool yn)
3207 shared_ptr<RouteList> r = routes.reader ();
3209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3212 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3213 at->set_record_enable (yn, this);
3217 /* since we don't keep rec-enable state, don't mark session dirty */
3221 Session::add_redirect (Redirect* redirect)
3225 PortInsert* port_insert;
3226 PluginInsert* plugin_insert;
3228 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3229 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3230 _port_inserts.insert (_port_inserts.begin(), port_insert);
3231 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3232 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3234 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3237 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3238 _sends.insert (_sends.begin(), send);
3240 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3244 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3250 Session::remove_redirect (Redirect* redirect)
3254 PortInsert* port_insert;
3255 PluginInsert* plugin_insert;
3257 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3258 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3259 _port_inserts.remove (port_insert);
3260 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3261 _plugin_inserts.remove (plugin_insert);
3263 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3266 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3267 _sends.remove (send);
3269 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3277 Session::available_capture_duration ()
3279 const double scale = 4096.0 / sizeof (Sample);
3281 if (_total_free_4k_blocks * scale > (double) max_frames) {
3285 return (nframes_t) floor (_total_free_4k_blocks * scale);
3289 Session::add_connection (ARDOUR::Connection* connection)
3292 Glib::Mutex::Lock guard (connection_lock);
3293 _connections.push_back (connection);
3296 ConnectionAdded (connection); /* EMIT SIGNAL */
3302 Session::remove_connection (ARDOUR::Connection* connection)
3304 bool removed = false;
3307 Glib::Mutex::Lock guard (connection_lock);
3308 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3310 if (i != _connections.end()) {
3311 _connections.erase (i);
3317 ConnectionRemoved (connection); /* EMIT SIGNAL */
3323 ARDOUR::Connection *
3324 Session::connection_by_name (string name) const
3326 Glib::Mutex::Lock lm (connection_lock);
3328 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3329 if ((*i)->name() == name) {
3338 Session::tempo_map_changed (Change ignored)
3345 Session::ensure_passthru_buffers (uint32_t howmany)
3347 while (howmany > _passthru_buffers.size()) {
3349 #ifdef NO_POSIX_MEMALIGN
3350 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3352 posix_memalign((void **)&p,16,current_block_size * 4);
3354 _passthru_buffers.push_back (p);
3358 #ifdef NO_POSIX_MEMALIGN
3359 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3361 posix_memalign((void **)&p,16,current_block_size * 4);
3363 memset (p, 0, sizeof (Sample) * current_block_size);
3364 _silent_buffers.push_back (p);
3368 #ifdef NO_POSIX_MEMALIGN
3369 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3371 posix_memalign((void **)&p,16,current_block_size * 4);
3373 memset (p, 0, sizeof (Sample) * current_block_size);
3374 _send_buffers.push_back (p);
3377 allocate_pan_automation_buffers (current_block_size, howmany, false);
3381 Session::next_send_name ()
3384 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3389 Session::next_insert_name ()
3392 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3396 /* Named Selection management */
3399 Session::named_selection_by_name (string name)
3401 Glib::Mutex::Lock lm (named_selection_lock);
3402 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3403 if ((*i)->name == name) {
3411 Session::add_named_selection (NamedSelection* named_selection)
3414 Glib::Mutex::Lock lm (named_selection_lock);
3415 named_selections.insert (named_selections.begin(), named_selection);
3420 NamedSelectionAdded (); /* EMIT SIGNAL */
3424 Session::remove_named_selection (NamedSelection* named_selection)
3426 bool removed = false;
3429 Glib::Mutex::Lock lm (named_selection_lock);
3431 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3433 if (i != named_selections.end()) {
3435 named_selections.erase (i);
3442 NamedSelectionRemoved (); /* EMIT SIGNAL */
3447 Session::reset_native_file_format ()
3449 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3451 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3452 (*i)->reset_write_sources (false);
3457 Session::route_name_unique (string n) const
3459 shared_ptr<RouteList> r = routes.reader ();
3461 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3462 if ((*i)->name() == n) {
3471 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3473 return fs->move_to_trash (dead_sound_dir_name);
3477 Session::n_playlists () const
3479 Glib::Mutex::Lock lm (playlist_lock);
3480 return playlists.size();
3484 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3486 if (!force && howmany <= _npan_buffers) {
3490 if (_pan_automation_buffer) {
3492 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3493 delete [] _pan_automation_buffer[i];
3496 delete [] _pan_automation_buffer;
3499 _pan_automation_buffer = new pan_t*[howmany];
3501 for (uint32_t i = 0; i < howmany; ++i) {
3502 _pan_automation_buffer[i] = new pan_t[nframes];
3505 _npan_buffers = howmany;
3509 Session::freeze (InterThreadInfo& itt)
3511 shared_ptr<RouteList> r = routes.reader ();
3513 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3517 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3518 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3529 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3530 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3534 boost::shared_ptr<AudioFileSource> fsource;
3536 char buf[PATH_MAX+1];
3540 nframes_t this_chunk;
3542 vector<Sample*> buffers;
3544 // any bigger than this seems to cause stack overflows in called functions
3545 const nframes_t chunk_size = (128 * 1024)/4;
3547 g_atomic_int_set (&processing_prohibited, 1);
3549 /* call tree *MUST* hold route_lock */
3551 if ((playlist = track.diskstream()->playlist()) == 0) {
3555 /* external redirects will be a problem */
3557 if (track.has_external_redirects()) {
3561 nchans = track.audio_diskstream()->n_channels();
3563 dir = discover_best_sound_dir ();
3565 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3567 for (x = 0; x < 99999; ++x) {
3568 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3569 if (access (buf, F_OK) != 0) {
3575 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3580 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3583 catch (failed_constructor& err) {
3584 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3588 srcs.push_back (fsource);
3591 /* XXX need to flush all redirects */
3596 /* create a set of reasonably-sized buffers */
3598 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3600 #ifdef NO_POSIX_MEMALIGN
3601 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3603 posix_memalign((void **)&b,16,chunk_size * 4);
3605 buffers.push_back (b);
3608 while (to_do && !itt.cancel) {
3610 this_chunk = min (to_do, chunk_size);
3612 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3617 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3618 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3621 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3627 start += this_chunk;
3628 to_do -= this_chunk;
3630 itt.progress = (float) (1.0 - ((double) to_do / len));
3639 xnow = localtime (&now);
3641 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3642 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3645 afs->update_header (position, *xnow, now);
3649 /* build peakfile for new source */
3651 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3652 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3654 afs->build_peaks ();
3658 /* construct a region to represent the bounced material */
3660 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3661 region_name_from_path (srcs.front()->name()));
3668 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3669 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3672 afs->mark_for_remove ();
3675 (*src)->drop_references ();
3679 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3683 g_atomic_int_set (&processing_prohibited, 0);
3691 Session::get_silent_buffers (uint32_t howmany)
3693 for (uint32_t i = 0; i < howmany; ++i) {
3694 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3696 return _silent_buffers;
3700 Session::ntracks () const
3703 shared_ptr<RouteList> r = routes.reader ();
3705 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3706 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3715 Session::nbusses () const
3718 shared_ptr<RouteList> r = routes.reader ();
3720 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3721 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3730 Session::add_curve(Curve *curve)
3732 curves[curve->id()] = curve;
3736 Session::add_automation_list(AutomationList *al)
3738 automation_lists[al->id()] = al;