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 /* get rid of it from the dead wood collection in the route list manager */
1932 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1936 /* try to cause everyone to drop their references */
1938 route->drop_references ();
1940 /* save the new state of the world */
1942 if (save_state (_current_snapshot_name)) {
1943 save_history (_current_snapshot_name);
1948 Session::route_mute_changed (void* src)
1954 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1956 if (solo_update_disabled) {
1962 boost::shared_ptr<Route> route = wpr.lock ();
1965 /* should not happen */
1966 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1970 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1972 shared_ptr<RouteList> r = routes.reader ();
1974 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1976 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1980 /* don't mess with busses */
1982 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1988 /* don't mess with tracks */
1990 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1995 if ((*i) != route &&
1996 ((*i)->mix_group () == 0 ||
1997 (*i)->mix_group () != route->mix_group () ||
1998 !route->mix_group ()->is_active())) {
2000 if ((*i)->soloed()) {
2002 /* if its already soloed, and solo latching is enabled,
2003 then leave it as it is.
2006 if (Config->get_solo_latched()) {
2013 solo_update_disabled = true;
2014 (*i)->set_solo (false, src);
2015 solo_update_disabled = false;
2019 bool something_soloed = false;
2020 bool same_thing_soloed = false;
2021 bool signal = false;
2023 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2024 if ((*i)->soloed()) {
2025 something_soloed = true;
2026 if (dynamic_cast<AudioTrack*>((*i).get())) {
2028 same_thing_soloed = true;
2033 same_thing_soloed = true;
2041 if (something_soloed != currently_soloing) {
2043 currently_soloing = something_soloed;
2046 modify_solo_mute (is_track, same_thing_soloed);
2049 SoloActive (currently_soloing);
2056 Session::update_route_solo_state ()
2059 bool is_track = false;
2060 bool signal = false;
2062 /* caller must hold RouteLock */
2064 /* this is where we actually implement solo by changing
2065 the solo mute setting of each track.
2068 shared_ptr<RouteList> r = routes.reader ();
2070 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2071 if ((*i)->soloed()) {
2073 if (dynamic_cast<AudioTrack*>((*i).get())) {
2080 if (mute != currently_soloing) {
2082 currently_soloing = mute;
2085 if (!is_track && !mute) {
2087 /* nothing is soloed */
2089 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2090 (*i)->set_solo_mute (false);
2100 modify_solo_mute (is_track, mute);
2103 SoloActive (currently_soloing);
2108 Session::modify_solo_mute (bool is_track, bool mute)
2110 shared_ptr<RouteList> r = routes.reader ();
2112 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2116 /* only alter track solo mute */
2118 if (dynamic_cast<AudioTrack*>((*i).get())) {
2119 if ((*i)->soloed()) {
2120 (*i)->set_solo_mute (!mute);
2122 (*i)->set_solo_mute (mute);
2128 /* only alter bus solo mute */
2130 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2132 if ((*i)->soloed()) {
2134 (*i)->set_solo_mute (false);
2138 /* don't mute master or control outs
2139 in response to another bus solo
2142 if ((*i) != _master_out &&
2143 (*i) != _control_out) {
2144 (*i)->set_solo_mute (mute);
2155 Session::catch_up_on_solo ()
2157 /* this is called after set_state() to catch the full solo
2158 state, which can't be correctly determined on a per-route
2159 basis, but needs the global overview that only the session
2162 update_route_solo_state();
2166 Session::route_by_name (string name)
2168 shared_ptr<RouteList> r = routes.reader ();
2170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2171 if ((*i)->name() == name) {
2176 return shared_ptr<Route> ((Route*) 0);
2180 Session::route_by_id (PBD::ID id)
2182 shared_ptr<RouteList> r = routes.reader ();
2184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2185 if ((*i)->id() == id) {
2190 return shared_ptr<Route> ((Route*) 0);
2194 Session::route_by_remote_id (uint32_t id)
2196 shared_ptr<RouteList> r = routes.reader ();
2198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2199 if ((*i)->remote_control_id() == id) {
2204 return shared_ptr<Route> ((Route*) 0);
2208 Session::find_current_end ()
2210 if (_state_of_the_state & Loading) {
2214 nframes_t max = get_maximum_extent ();
2216 if (max > end_location->end()) {
2217 end_location->set_end (max);
2219 DurationChanged(); /* EMIT SIGNAL */
2224 Session::get_maximum_extent () const
2229 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2231 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2232 Playlist* pl = (*i)->playlist();
2233 if ((me = pl->get_maximum_extent()) > max) {
2241 boost::shared_ptr<Diskstream>
2242 Session::diskstream_by_name (string name)
2244 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2246 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2247 if ((*i)->name() == name) {
2252 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2255 boost::shared_ptr<Diskstream>
2256 Session::diskstream_by_id (const PBD::ID& id)
2258 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2260 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2261 if ((*i)->id() == id) {
2266 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2269 /* AudioRegion management */
2272 Session::new_region_name (string old)
2274 string::size_type last_period;
2276 string::size_type len = old.length() + 64;
2279 if ((last_period = old.find_last_of ('.')) == string::npos) {
2281 /* no period present - add one explicitly */
2284 last_period = old.length() - 1;
2289 number = atoi (old.substr (last_period+1).c_str());
2293 while (number < (UINT_MAX-1)) {
2295 AudioRegionList::const_iterator i;
2300 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2303 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2304 if (i->second->name() == sbuf) {
2309 if (i == audio_regions.end()) {
2314 if (number != (UINT_MAX-1)) {
2318 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2323 Session::region_name (string& result, string base, bool newlevel) const
2330 Glib::Mutex::Lock lm (region_lock);
2332 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2340 /* XXX this is going to be slow. optimize me later */
2345 string::size_type pos;
2347 pos = base.find_last_of ('.');
2349 /* pos may be npos, but then we just use entire base */
2351 subbase = base.substr (0, pos);
2355 bool name_taken = true;
2358 Glib::Mutex::Lock lm (region_lock);
2360 for (int n = 1; n < 5000; ++n) {
2363 snprintf (buf, sizeof (buf), ".%d", n);
2368 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2369 if (i->second->name() == result) {
2382 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2390 Session::add_region (boost::shared_ptr<Region> region)
2392 boost::shared_ptr<AudioRegion> ar;
2393 boost::shared_ptr<AudioRegion> oar;
2397 Glib::Mutex::Lock lm (region_lock);
2399 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2401 AudioRegionList::iterator x;
2403 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2405 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2407 if (ar->region_list_equivalent (oar)) {
2412 if (x == audio_regions.end()) {
2414 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2416 entry.first = region->id();
2419 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2431 fatal << _("programming error: ")
2432 << X_("unknown region type passed to Session::add_region()")
2439 /* mark dirty because something has changed even if we didn't
2440 add the region to the region list.
2446 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2447 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2448 AudioRegionAdded (ar); /* EMIT SIGNAL */
2453 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2455 if (what_changed & Region::HiddenChanged) {
2456 /* relay hidden changes */
2457 RegionHiddenChange (region);
2462 Session::region_renamed (boost::shared_ptr<Region> region)
2464 add_region (region);
2468 Session::remove_region (boost::shared_ptr<Region> region)
2470 AudioRegionList::iterator i;
2471 boost::shared_ptr<AudioRegion> ar;
2472 bool removed = false;
2475 Glib::Mutex::Lock lm (region_lock);
2477 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2478 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2479 audio_regions.erase (i);
2486 fatal << _("programming error: ")
2487 << X_("unknown region type passed to Session::remove_region()")
2493 /* mark dirty because something has changed even if we didn't
2494 remove the region from the region list.
2500 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2504 boost::shared_ptr<AudioRegion>
2505 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2507 AudioRegionList::iterator i;
2508 boost::shared_ptr<AudioRegion> region;
2509 Glib::Mutex::Lock lm (region_lock);
2511 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2515 if (region->whole_file()) {
2517 if (child->source_equivalent (region)) {
2523 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2527 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2529 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2530 (*i)->get_region_list_equivalent_regions (region, result);
2534 Session::destroy_region (boost::shared_ptr<Region> region)
2536 boost::shared_ptr<AudioRegion> aregion;
2538 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2542 if (aregion->playlist()) {
2543 aregion->playlist()->destroy_region (region);
2546 vector<boost::shared_ptr<Source> > srcs;
2548 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2549 srcs.push_back (aregion->source (n));
2552 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2554 if ((*i).use_count() == 1) {
2555 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2558 (afs)->mark_for_remove ();
2561 (*i)->drop_references ();
2569 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2571 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2572 destroy_region (*i);
2578 Session::remove_last_capture ()
2580 list<boost::shared_ptr<Region> > r;
2582 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2584 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2585 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2588 r.insert (r.end(), l.begin(), l.end());
2593 destroy_regions (r);
2598 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2604 /* Source Management */
2607 Session::add_source (boost::shared_ptr<Source> source)
2609 boost::shared_ptr<AudioFileSource> afs;
2611 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2613 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2614 pair<AudioSourceList::iterator,bool> result;
2616 entry.first = source->id();
2620 Glib::Mutex::Lock lm (audio_source_lock);
2621 result = audio_sources.insert (entry);
2624 if (!result.second) {
2625 cerr << "\tNOT inserted ? " << result.second << endl;
2628 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2631 SourceAdded (source); /* EMIT SIGNAL */
2633 cerr << "\tNOT AUDIO FILE\n";
2638 Session::remove_source (boost::weak_ptr<Source> src)
2640 AudioSourceList::iterator i;
2641 boost::shared_ptr<Source> source = src.lock();
2648 Glib::Mutex::Lock lm (audio_source_lock);
2650 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2651 audio_sources.erase (i);
2655 if (!_state_of_the_state & InCleanup) {
2657 /* save state so we don't end up with a session file
2658 referring to non-existent sources.
2661 save_state (_current_snapshot_name);
2664 SourceRemoved(source); /* EMIT SIGNAL */
2667 boost::shared_ptr<Source>
2668 Session::source_by_id (const PBD::ID& id)
2670 Glib::Mutex::Lock lm (audio_source_lock);
2671 AudioSourceList::iterator i;
2672 boost::shared_ptr<Source> source;
2674 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2678 /* XXX search MIDI or other searches here */
2684 Session::peak_path_from_audio_path (string audio_path) const
2689 res += PBD::basename_nosuffix (audio_path);
2696 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2699 string old_basename = PBD::basename_nosuffix (oldname);
2700 string new_legalized = legalize_for_path (newname);
2702 /* note: we know (or assume) the old path is already valid */
2706 /* destructive file sources have a name of the form:
2708 /path/to/Tnnnn-NAME(%[LR])?.wav
2710 the task here is to replace NAME with the new name.
2713 /* find last slash */
2717 string::size_type slash;
2718 string::size_type dash;
2720 if ((slash = path.find_last_of ('/')) == string::npos) {
2724 dir = path.substr (0, slash+1);
2726 /* '-' is not a legal character for the NAME part of the path */
2728 if ((dash = path.find_last_of ('-')) == string::npos) {
2732 prefix = path.substr (slash+1, dash-(slash+1));
2737 path += new_legalized;
2738 path += ".wav"; /* XXX gag me with a spoon */
2742 /* non-destructive file sources have a name of the form:
2744 /path/to/NAME-nnnnn(%[LR])?.wav
2746 the task here is to replace NAME with the new name.
2751 string::size_type slash;
2752 string::size_type dash;
2753 string::size_type postfix;
2755 /* find last slash */
2757 if ((slash = path.find_last_of ('/')) == string::npos) {
2761 dir = path.substr (0, slash+1);
2763 /* '-' is not a legal character for the NAME part of the path */
2765 if ((dash = path.find_last_of ('-')) == string::npos) {
2769 suffix = path.substr (dash+1);
2771 // Suffix is now everything after the dash. Now we need to eliminate
2772 // the nnnnn part, which is done by either finding a '%' or a '.'
2774 postfix = suffix.find_last_of ("%");
2775 if (postfix == string::npos) {
2776 postfix = suffix.find_last_of ('.');
2779 if (postfix != string::npos) {
2780 suffix = suffix.substr (postfix);
2782 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2786 const uint32_t limit = 10000;
2787 char buf[PATH_MAX+1];
2789 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2791 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2793 if (access (buf, F_OK) != 0) {
2801 error << "FATAL ERROR! Could not find a " << endl;
2810 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2814 char buf[PATH_MAX+1];
2815 const uint32_t limit = 10000;
2819 legalized = legalize_for_path (name);
2821 /* find a "version" of the file name that doesn't exist in
2822 any of the possible directories.
2825 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2827 vector<space_and_path>::iterator i;
2828 uint32_t existing = 0;
2830 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2834 spath += sound_dir (false);
2838 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2839 } else if (nchan == 2) {
2841 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2843 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2845 } else if (nchan < 26) {
2846 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2848 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2856 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2857 } else if (nchan == 2) {
2859 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2861 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2863 } else if (nchan < 26) {
2864 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2866 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2870 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2876 if (existing == 0) {
2881 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2882 throw failed_constructor();
2886 /* we now have a unique name for the file, but figure out where to
2892 spath = discover_best_sound_dir ();
2894 string::size_type pos = foo.find_last_of ('/');
2896 if (pos == string::npos) {
2899 spath += foo.substr (pos + 1);
2905 boost::shared_ptr<AudioFileSource>
2906 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2908 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2909 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2912 /* Playlist management */
2915 Session::playlist_by_name (string name)
2917 Glib::Mutex::Lock lm (playlist_lock);
2918 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2919 if ((*i)->name() == name) {
2923 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2924 if ((*i)->name() == name) {
2932 Session::add_playlist (Playlist* playlist)
2934 if (playlist->hidden()) {
2939 Glib::Mutex::Lock lm (playlist_lock);
2940 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2941 playlists.insert (playlists.begin(), playlist);
2943 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2944 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2950 PlaylistAdded (playlist); /* EMIT SIGNAL */
2954 Session::track_playlist (Playlist* pl, bool inuse)
2956 PlaylistList::iterator x;
2959 Glib::Mutex::Lock lm (playlist_lock);
2962 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2964 unused_playlists.insert (pl);
2966 if ((x = playlists.find (pl)) != playlists.end()) {
2967 playlists.erase (x);
2972 //cerr << "shifting playlist to used: " << pl->name() << endl;
2974 playlists.insert (pl);
2976 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2977 unused_playlists.erase (x);
2984 Session::remove_playlist (Playlist* playlist)
2986 if (_state_of_the_state & Deletion) {
2991 Glib::Mutex::Lock lm (playlist_lock);
2992 // cerr << "removing playlist: " << playlist->name() << endl;
2994 PlaylistList::iterator i;
2996 i = find (playlists.begin(), playlists.end(), playlist);
2998 if (i != playlists.end()) {
2999 playlists.erase (i);
3002 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3003 if (i != unused_playlists.end()) {
3004 unused_playlists.erase (i);
3011 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3015 Session::set_audition (boost::shared_ptr<Region> r)
3017 pending_audition_region = r;
3018 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3019 schedule_butler_transport_work ();
3023 Session::audition_playlist ()
3025 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3026 ev->region.reset ();
3031 Session::non_realtime_set_audition ()
3033 if (!pending_audition_region) {
3034 auditioner->audition_current_playlist ();
3036 auditioner->audition_region (pending_audition_region);
3037 pending_audition_region.reset ();
3039 AuditionActive (true); /* EMIT SIGNAL */
3043 Session::audition_region (boost::shared_ptr<Region> r)
3045 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3051 Session::cancel_audition ()
3053 if (auditioner->active()) {
3054 auditioner->cancel_audition ();
3055 AuditionActive (false); /* EMIT SIGNAL */
3060 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3062 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3066 Session::remove_empty_sounds ()
3068 PathScanner scanner;
3070 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3072 Glib::Mutex::Lock lm (audio_source_lock);
3074 regex_t compiled_tape_track_pattern;
3077 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3081 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3083 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3087 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3089 /* never remove files that appear to be a tape track */
3091 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3096 if (AudioFileSource::is_empty (*this, *(*i))) {
3098 unlink ((*i)->c_str());
3100 string peak_path = peak_path_from_audio_path (**i);
3101 unlink (peak_path.c_str());
3107 delete possible_audiofiles;
3111 Session::is_auditioning () const
3113 /* can be called before we have an auditioner object */
3115 return auditioner->active();
3122 Session::set_all_solo (bool yn)
3124 shared_ptr<RouteList> r = routes.reader ();
3126 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3127 if (!(*i)->hidden()) {
3128 (*i)->set_solo (yn, this);
3136 Session::set_all_mute (bool yn)
3138 shared_ptr<RouteList> r = routes.reader ();
3140 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3141 if (!(*i)->hidden()) {
3142 (*i)->set_mute (yn, this);
3150 Session::n_diskstreams () const
3154 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3156 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3157 if (!(*i)->hidden()) {
3165 Session::graph_reordered ()
3167 /* don't do this stuff if we are setting up connections
3168 from a set_state() call.
3171 if (_state_of_the_state & InitialConnecting) {
3177 /* force all diskstreams to update their capture offset values to
3178 reflect any changes in latencies within the graph.
3181 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3183 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3184 (*i)->set_capture_offset ();
3189 Session::record_disenable_all ()
3191 record_enable_change_all (false);
3195 Session::record_enable_all ()
3197 record_enable_change_all (true);
3201 Session::record_enable_change_all (bool yn)
3203 shared_ptr<RouteList> r = routes.reader ();
3205 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3208 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3209 at->set_record_enable (yn, this);
3213 /* since we don't keep rec-enable state, don't mark session dirty */
3217 Session::add_redirect (Redirect* redirect)
3221 PortInsert* port_insert;
3222 PluginInsert* plugin_insert;
3224 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3225 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3226 _port_inserts.insert (_port_inserts.begin(), port_insert);
3227 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3228 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3230 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3233 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3234 _sends.insert (_sends.begin(), send);
3236 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3240 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3246 Session::remove_redirect (Redirect* redirect)
3250 PortInsert* port_insert;
3251 PluginInsert* plugin_insert;
3253 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3254 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3255 _port_inserts.remove (port_insert);
3256 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3257 _plugin_inserts.remove (plugin_insert);
3259 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3262 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3263 _sends.remove (send);
3265 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3273 Session::available_capture_duration ()
3275 const double scale = 4096.0 / sizeof (Sample);
3277 if (_total_free_4k_blocks * scale > (double) max_frames) {
3281 return (nframes_t) floor (_total_free_4k_blocks * scale);
3285 Session::add_connection (ARDOUR::Connection* connection)
3288 Glib::Mutex::Lock guard (connection_lock);
3289 _connections.push_back (connection);
3292 ConnectionAdded (connection); /* EMIT SIGNAL */
3298 Session::remove_connection (ARDOUR::Connection* connection)
3300 bool removed = false;
3303 Glib::Mutex::Lock guard (connection_lock);
3304 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3306 if (i != _connections.end()) {
3307 _connections.erase (i);
3313 ConnectionRemoved (connection); /* EMIT SIGNAL */
3319 ARDOUR::Connection *
3320 Session::connection_by_name (string name) const
3322 Glib::Mutex::Lock lm (connection_lock);
3324 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3325 if ((*i)->name() == name) {
3334 Session::tempo_map_changed (Change ignored)
3341 Session::ensure_passthru_buffers (uint32_t howmany)
3343 while (howmany > _passthru_buffers.size()) {
3345 #ifdef NO_POSIX_MEMALIGN
3346 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3348 posix_memalign((void **)&p,16,current_block_size * 4);
3350 _passthru_buffers.push_back (p);
3354 #ifdef NO_POSIX_MEMALIGN
3355 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3357 posix_memalign((void **)&p,16,current_block_size * 4);
3359 memset (p, 0, sizeof (Sample) * current_block_size);
3360 _silent_buffers.push_back (p);
3364 #ifdef NO_POSIX_MEMALIGN
3365 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3367 posix_memalign((void **)&p,16,current_block_size * 4);
3369 memset (p, 0, sizeof (Sample) * current_block_size);
3370 _send_buffers.push_back (p);
3373 allocate_pan_automation_buffers (current_block_size, howmany, false);
3377 Session::next_send_name ()
3380 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3385 Session::next_insert_name ()
3388 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3392 /* Named Selection management */
3395 Session::named_selection_by_name (string name)
3397 Glib::Mutex::Lock lm (named_selection_lock);
3398 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3399 if ((*i)->name == name) {
3407 Session::add_named_selection (NamedSelection* named_selection)
3410 Glib::Mutex::Lock lm (named_selection_lock);
3411 named_selections.insert (named_selections.begin(), named_selection);
3416 NamedSelectionAdded (); /* EMIT SIGNAL */
3420 Session::remove_named_selection (NamedSelection* named_selection)
3422 bool removed = false;
3425 Glib::Mutex::Lock lm (named_selection_lock);
3427 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3429 if (i != named_selections.end()) {
3431 named_selections.erase (i);
3438 NamedSelectionRemoved (); /* EMIT SIGNAL */
3443 Session::reset_native_file_format ()
3445 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3447 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3448 (*i)->reset_write_sources (false);
3453 Session::route_name_unique (string n) const
3455 shared_ptr<RouteList> r = routes.reader ();
3457 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3458 if ((*i)->name() == n) {
3467 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3469 return fs->move_to_trash (dead_sound_dir_name);
3473 Session::n_playlists () const
3475 Glib::Mutex::Lock lm (playlist_lock);
3476 return playlists.size();
3480 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3482 if (!force && howmany <= _npan_buffers) {
3486 if (_pan_automation_buffer) {
3488 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3489 delete [] _pan_automation_buffer[i];
3492 delete [] _pan_automation_buffer;
3495 _pan_automation_buffer = new pan_t*[howmany];
3497 for (uint32_t i = 0; i < howmany; ++i) {
3498 _pan_automation_buffer[i] = new pan_t[nframes];
3501 _npan_buffers = howmany;
3505 Session::freeze (InterThreadInfo& itt)
3507 shared_ptr<RouteList> r = routes.reader ();
3509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3513 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3514 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3525 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3526 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3530 boost::shared_ptr<AudioFileSource> fsource;
3532 char buf[PATH_MAX+1];
3536 nframes_t this_chunk;
3538 vector<Sample*> buffers;
3540 // any bigger than this seems to cause stack overflows in called functions
3541 const nframes_t chunk_size = (128 * 1024)/4;
3543 g_atomic_int_set (&processing_prohibited, 1);
3545 /* call tree *MUST* hold route_lock */
3547 if ((playlist = track.diskstream()->playlist()) == 0) {
3551 /* external redirects will be a problem */
3553 if (track.has_external_redirects()) {
3557 nchans = track.audio_diskstream()->n_channels();
3559 dir = discover_best_sound_dir ();
3561 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3563 for (x = 0; x < 99999; ++x) {
3564 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3565 if (access (buf, F_OK) != 0) {
3571 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3576 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3579 catch (failed_constructor& err) {
3580 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3584 srcs.push_back (fsource);
3587 /* XXX need to flush all redirects */
3592 /* create a set of reasonably-sized buffers */
3594 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3596 #ifdef NO_POSIX_MEMALIGN
3597 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3599 posix_memalign((void **)&b,16,chunk_size * 4);
3601 buffers.push_back (b);
3604 while (to_do && !itt.cancel) {
3606 this_chunk = min (to_do, chunk_size);
3608 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3613 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3614 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3617 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3623 start += this_chunk;
3624 to_do -= this_chunk;
3626 itt.progress = (float) (1.0 - ((double) to_do / len));
3635 xnow = localtime (&now);
3637 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3638 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3641 afs->update_header (position, *xnow, now);
3645 /* build peakfile for new source */
3647 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3648 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3650 afs->build_peaks ();
3654 /* construct a region to represent the bounced material */
3656 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3657 region_name_from_path (srcs.front()->name()));
3664 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3665 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3668 afs->mark_for_remove ();
3671 (*src)->drop_references ();
3675 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3679 g_atomic_int_set (&processing_prohibited, 0);
3687 Session::get_silent_buffers (uint32_t howmany)
3689 for (uint32_t i = 0; i < howmany; ++i) {
3690 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3692 return _silent_buffers;
3696 Session::ntracks () const
3699 shared_ptr<RouteList> r = routes.reader ();
3701 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3702 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3711 Session::nbusses () const
3714 shared_ptr<RouteList> r = routes.reader ();
3716 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3717 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3726 Session::add_curve(Curve *curve)
3728 curves[curve->id()] = curve;
3732 Session::add_automation_list(AutomationList *al)
3734 automation_lists[al->id()] = al;