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 /* this should cause deletion of the auditioner */
436 // auditioner.reset ();
438 #undef TRACK_DESTRUCTION
439 #ifdef TRACK_DESTRUCTION
440 cerr << "delete named selections\n";
441 #endif /* TRACK_DESTRUCTION */
442 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
443 NamedSelectionList::iterator tmp;
452 #ifdef TRACK_DESTRUCTION
453 cerr << "delete playlists\n";
454 #endif /* TRACK_DESTRUCTION */
455 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
456 PlaylistList::iterator tmp;
466 #ifdef TRACK_DESTRUCTION
467 cerr << "delete audio regions\n";
468 #endif /* TRACK_DESTRUCTION */
470 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
471 AudioRegionList::iterator tmp;
476 i->second->drop_references ();
481 audio_regions.clear ();
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete routes\n";
485 #endif /* TRACK_DESTRUCTION */
487 RCUWriter<RouteList> writer (routes);
488 boost::shared_ptr<RouteList> r = writer.get_copy ();
489 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
490 (*i)->drop_references ();
493 /* writer goes out of scope and updates master */
498 #ifdef TRACK_DESTRUCTION
499 cerr << "delete diskstreams\n";
500 #endif /* TRACK_DESTRUCTION */
502 RCUWriter<DiskstreamList> dwriter (diskstreams);
503 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
504 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
505 (*i)->drop_references ();
509 diskstreams.flush ();
511 #ifdef TRACK_DESTRUCTION
512 cerr << "delete audio sources\n";
513 #endif /* TRACK_DESTRUCTION */
514 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
515 AudioSourceList::iterator tmp;
520 i->second->drop_references ();
525 audio_sources.clear ();
527 #ifdef TRACK_DESTRUCTION
528 cerr << "delete mix groups\n";
529 #endif /* TRACK_DESTRUCTION */
530 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
531 list<RouteGroup*>::iterator tmp;
541 #ifdef TRACK_DESTRUCTION
542 cerr << "delete edit groups\n";
543 #endif /* TRACK_DESTRUCTION */
544 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
545 list<RouteGroup*>::iterator tmp;
555 #ifdef TRACK_DESTRUCTION
556 cerr << "delete connections\n";
557 #endif /* TRACK_DESTRUCTION */
558 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
559 ConnectionList::iterator tmp;
569 if (butler_mixdown_buffer) {
570 delete [] butler_mixdown_buffer;
573 if (butler_gain_buffer) {
574 delete [] butler_gain_buffer;
577 Crossfade::set_buffer_size (0);
585 Session::set_worst_io_latencies ()
587 _worst_output_latency = 0;
588 _worst_input_latency = 0;
590 if (!_engine.connected()) {
594 boost::shared_ptr<RouteList> r = routes.reader ();
596 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
597 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
598 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
603 Session::when_engine_running ()
605 string first_physical_output;
607 /* we don't want to run execute this again */
609 first_time_running.disconnect ();
611 set_block_size (_engine.frames_per_cycle());
612 set_frame_rate (_engine.frame_rate());
614 Config->map_parameters (mem_fun (*this, &Session::config_changed));
616 /* every time we reconnect, recompute worst case output latencies */
618 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
620 if (synced_to_jack()) {
621 _engine.transport_stop ();
624 if (Config->get_jack_time_master()) {
625 _engine.transport_locate (_transport_frame);
633 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
635 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
637 /* existing state for Click */
639 if (_click_io->set_state (*child->children().front()) == 0) {
641 _clicking = Config->get_clicking ();
645 error << _("could not setup Click I/O") << endmsg;
651 /* default state for Click */
653 first_physical_output = _engine.get_nth_physical_output (0);
655 if (first_physical_output.length()) {
656 if (_click_io->add_output_port (first_physical_output, this)) {
657 // relax, even though its an error
659 _clicking = Config->get_clicking ();
665 catch (failed_constructor& err) {
666 error << _("cannot setup Click I/O") << endmsg;
669 set_worst_io_latencies ();
672 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
675 if (auditioner == 0) {
677 /* we delay creating the auditioner till now because
678 it makes its own connections to ports named
679 in the ARDOUR_RC config file. the engine has
680 to be running for this to work.
684 auditioner.reset (new Auditioner (*this));
687 catch (failed_constructor& err) {
688 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
692 /* Create a set of Connection objects that map
693 to the physical outputs currently available
698 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
700 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
702 Connection* c = new OutputConnection (buf, true);
705 c->add_connection (0, _engine.get_nth_physical_output (np));
710 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
712 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
714 Connection* c = new InputConnection (buf, true);
717 c->add_connection (0, _engine.get_nth_physical_input (np));
724 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
726 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
728 Connection* c = new OutputConnection (buf, true);
732 c->add_connection (0, _engine.get_nth_physical_output (np));
733 c->add_connection (1, _engine.get_nth_physical_output (np+1));
738 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
740 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
742 Connection* c = new InputConnection (buf, true);
746 c->add_connection (0, _engine.get_nth_physical_input (np));
747 c->add_connection (1, _engine.get_nth_physical_input (np+1));
756 /* create master/control ports */
761 /* force the master to ignore any later call to this */
763 if (_master_out->pending_state_node) {
764 _master_out->ports_became_legal();
767 /* no panner resets till we are through */
769 _master_out->defer_pan_reset ();
771 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
772 if (_master_out->add_input_port ("", this)) {
773 error << _("cannot setup master inputs")
779 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
780 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
781 error << _("cannot setup master outputs")
788 _master_out->allow_pan_reset ();
792 Connection* c = new OutputConnection (_("Master Out"), true);
794 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
796 c->add_connection ((int) n, _master_out->input(n)->name());
803 /* catch up on send+insert cnts */
807 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
810 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
811 if (id > insert_cnt) {
819 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
822 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
829 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
831 /* hook us up to the engine */
833 _engine.set_session (this);
838 osc->set_session (*this);
841 _state_of_the_state = Clean;
843 DirtyChanged (); /* EMIT SIGNAL */
847 Session::hookup_io ()
849 /* stop graph reordering notifications from
850 causing resorts, etc.
853 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
855 /* Tell all IO objects to create their ports */
862 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
863 if (_control_out->add_input_port ("", this)) {
864 error << _("cannot setup control inputs")
870 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
871 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
872 error << _("cannot set up master outputs")
880 /* Tell all IO objects to connect themselves together */
882 IO::enable_connecting ();
884 /* Now reset all panners */
886 IO::reset_panners ();
888 /* Anyone who cares about input state, wake up and do something */
890 IOConnectionsComplete (); /* EMIT SIGNAL */
892 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
894 /* now handle the whole enchilada as if it was one
900 /* update mixer solo state */
906 Session::playlist_length_changed (Playlist* pl)
908 /* we can't just increase end_location->end() if pl->get_maximum_extent()
909 if larger. if the playlist used to be the longest playlist,
910 and its now shorter, we have to decrease end_location->end(). hence,
911 we have to iterate over all diskstreams and check the
912 playlists currently in use.
918 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
922 if ((playlist = dstream->playlist()) != 0) {
923 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
926 /* see comment in playlist_length_changed () */
931 Session::record_enabling_legal () const
933 /* this used to be in here, but survey says.... we don't need to restrict it */
934 // if (record_status() == Recording) {
938 if (Config->get_all_safe()) {
945 Session::reset_input_monitor_state ()
947 if (transport_rolling()) {
949 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
951 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
952 if ((*i)->record_enabled ()) {
953 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
954 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
958 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
960 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
961 if ((*i)->record_enabled ()) {
962 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
963 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
970 Session::auto_punch_start_changed (Location* location)
972 replace_event (Event::PunchIn, location->start());
974 if (get_record_enabled() && Config->get_punch_in()) {
975 /* capture start has been changed, so save new pending state */
976 save_state ("", true);
981 Session::auto_punch_end_changed (Location* location)
983 nframes_t when_to_stop = location->end();
984 // when_to_stop += _worst_output_latency + _worst_input_latency;
985 replace_event (Event::PunchOut, when_to_stop);
989 Session::auto_punch_changed (Location* location)
991 nframes_t when_to_stop = location->end();
993 replace_event (Event::PunchIn, location->start());
994 //when_to_stop += _worst_output_latency + _worst_input_latency;
995 replace_event (Event::PunchOut, when_to_stop);
999 Session::auto_loop_changed (Location* location)
1001 replace_event (Event::AutoLoop, location->end(), location->start());
1003 if (transport_rolling() && play_loop) {
1005 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1007 if (_transport_frame > location->end()) {
1008 // relocate to beginning of loop
1009 clear_events (Event::LocateRoll);
1011 request_locate (location->start(), true);
1014 else if (Config->get_seamless_loop() && !loop_changing) {
1016 // schedule a locate-roll to refill the diskstreams at the
1017 // previous loop end
1018 loop_changing = true;
1020 if (location->end() > last_loopend) {
1021 clear_events (Event::LocateRoll);
1022 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1029 last_loopend = location->end();
1034 Session::set_auto_punch_location (Location* location)
1038 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1039 auto_punch_start_changed_connection.disconnect();
1040 auto_punch_end_changed_connection.disconnect();
1041 auto_punch_changed_connection.disconnect();
1042 existing->set_auto_punch (false, this);
1043 remove_event (existing->start(), Event::PunchIn);
1044 clear_events (Event::PunchOut);
1045 auto_punch_location_changed (0);
1050 if (location == 0) {
1054 if (location->end() <= location->start()) {
1055 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1059 auto_punch_start_changed_connection.disconnect();
1060 auto_punch_end_changed_connection.disconnect();
1061 auto_punch_changed_connection.disconnect();
1063 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1064 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1065 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1067 location->set_auto_punch (true, this);
1068 auto_punch_location_changed (location);
1072 Session::set_auto_loop_location (Location* location)
1076 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1077 auto_loop_start_changed_connection.disconnect();
1078 auto_loop_end_changed_connection.disconnect();
1079 auto_loop_changed_connection.disconnect();
1080 existing->set_auto_loop (false, this);
1081 remove_event (existing->end(), Event::AutoLoop);
1082 auto_loop_location_changed (0);
1087 if (location == 0) {
1091 if (location->end() <= location->start()) {
1092 error << _("Session: you can't use a mark for auto loop") << endmsg;
1096 last_loopend = location->end();
1098 auto_loop_start_changed_connection.disconnect();
1099 auto_loop_end_changed_connection.disconnect();
1100 auto_loop_changed_connection.disconnect();
1102 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1103 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1104 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1106 location->set_auto_loop (true, this);
1107 auto_loop_location_changed (location);
1111 Session::locations_added (Location* ignored)
1117 Session::locations_changed ()
1119 _locations.apply (*this, &Session::handle_locations_changed);
1123 Session::handle_locations_changed (Locations::LocationList& locations)
1125 Locations::LocationList::iterator i;
1127 bool set_loop = false;
1128 bool set_punch = false;
1130 for (i = locations.begin(); i != locations.end(); ++i) {
1134 if (location->is_auto_punch()) {
1135 set_auto_punch_location (location);
1138 if (location->is_auto_loop()) {
1139 set_auto_loop_location (location);
1146 set_auto_loop_location (0);
1149 set_auto_punch_location (0);
1156 Session::enable_record ()
1158 /* XXX really atomic compare+swap here */
1159 if (g_atomic_int_get (&_record_status) != Recording) {
1160 g_atomic_int_set (&_record_status, Recording);
1161 _last_record_location = _transport_frame;
1162 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1164 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1165 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1166 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1167 if ((*i)->record_enabled ()) {
1168 (*i)->monitor_input (true);
1173 RecordStateChanged ();
1178 Session::disable_record (bool rt_context, bool force)
1182 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1184 if (!Config->get_latched_record_enable () || force) {
1185 g_atomic_int_set (&_record_status, Disabled);
1187 if (rs == Recording) {
1188 g_atomic_int_set (&_record_status, Enabled);
1192 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1194 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1195 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1197 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1198 if ((*i)->record_enabled ()) {
1199 (*i)->monitor_input (false);
1204 RecordStateChanged (); /* emit signal */
1207 remove_pending_capture_state ();
1213 Session::step_back_from_record ()
1215 g_atomic_int_set (&_record_status, Enabled);
1217 if (Config->get_monitoring_model() == HardwareMonitoring) {
1218 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1220 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1221 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1222 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1223 (*i)->monitor_input (false);
1230 Session::maybe_enable_record ()
1232 g_atomic_int_set (&_record_status, Enabled);
1234 /* this function is currently called from somewhere other than an RT thread.
1235 this save_state() call therefore doesn't impact anything.
1238 save_state ("", true);
1240 if (_transport_speed) {
1241 if (!Config->get_punch_in()) {
1245 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1246 RecordStateChanged (); /* EMIT SIGNAL */
1253 Session::audible_frame () const
1259 /* the first of these two possible settings for "offset"
1260 mean that the audible frame is stationary until
1261 audio emerges from the latency compensation
1264 the second means that the audible frame is stationary
1265 until audio would emerge from a physical port
1266 in the absence of any plugin latency compensation
1269 offset = _worst_output_latency;
1271 if (offset > current_block_size) {
1272 offset -= current_block_size;
1274 /* XXX is this correct? if we have no external
1275 physical connections and everything is internal
1276 then surely this is zero? still, how
1277 likely is that anyway?
1279 offset = current_block_size;
1282 if (synced_to_jack()) {
1283 tf = _engine.transport_frame();
1285 tf = _transport_frame;
1288 if (_transport_speed == 0) {
1298 if (!non_realtime_work_pending()) {
1302 /* take latency into account */
1311 Session::set_frame_rate (nframes_t frames_per_second)
1313 /** \fn void Session::set_frame_size(nframes_t)
1314 the AudioEngine object that calls this guarantees
1315 that it will not be called while we are also in
1316 ::process(). Its fine to do things that block
1320 _base_frame_rate = frames_per_second;
1324 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1326 // XXX we need some equivalent to this, somehow
1327 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1331 /* XXX need to reset/reinstantiate all LADSPA plugins */
1335 Session::set_block_size (nframes_t nframes)
1337 /* the AudioEngine guarantees
1338 that it will not be called while we are also in
1339 ::process(). It is therefore fine to do things that block
1344 vector<Sample*>::iterator i;
1347 current_block_size = nframes;
1349 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1353 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1357 _passthru_buffers.clear ();
1358 _silent_buffers.clear ();
1360 ensure_passthru_buffers (np);
1362 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1366 #ifdef NO_POSIX_MEMALIGN
1367 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1369 posix_memalign((void **)&buf,16,current_block_size * 4);
1373 memset (*i, 0, sizeof (Sample) * current_block_size);
1377 if (_gain_automation_buffer) {
1378 delete [] _gain_automation_buffer;
1380 _gain_automation_buffer = new gain_t[nframes];
1382 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1384 boost::shared_ptr<RouteList> r = routes.reader ();
1386 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1387 (*i)->set_block_size (nframes);
1390 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1391 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1392 (*i)->set_block_size (nframes);
1395 set_worst_io_latencies ();
1400 Session::set_default_fade (float steepness, float fade_msecs)
1403 nframes_t fade_frames;
1405 /* Don't allow fade of less 1 frame */
1407 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1414 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1418 default_fade_msecs = fade_msecs;
1419 default_fade_steepness = steepness;
1422 // jlc, WTF is this!
1423 Glib::RWLock::ReaderLock lm (route_lock);
1424 AudioRegion::set_default_fade (steepness, fade_frames);
1429 /* XXX have to do this at some point */
1430 /* foreach region using default fade, reset, then
1431 refill_all_diskstream_buffers ();
1436 struct RouteSorter {
1437 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1438 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1440 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1443 if (r1->fed_by.empty()) {
1444 if (r2->fed_by.empty()) {
1445 /* no ardour-based connections inbound to either route. just use signal order */
1446 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1448 /* r2 has connections, r1 does not; run r1 early */
1452 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1459 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1461 shared_ptr<Route> r2;
1463 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1464 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1468 /* make a copy of the existing list of routes that feed r1 */
1470 set<shared_ptr<Route> > existing = r1->fed_by;
1472 /* for each route that feeds r1, recurse, marking it as feeding
1476 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1479 /* r2 is a route that feeds r1 which somehow feeds base. mark
1480 base as being fed by r2
1483 rbase->fed_by.insert (r2);
1487 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1491 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1495 /* now recurse, so that we can mark base as being fed by
1496 all routes that feed r2
1499 trace_terminal (r2, rbase);
1506 Session::resort_routes ()
1508 /* don't do anything here with signals emitted
1509 by Routes while we are being destroyed.
1512 if (_state_of_the_state & Deletion) {
1519 RCUWriter<RouteList> writer (routes);
1520 shared_ptr<RouteList> r = writer.get_copy ();
1521 resort_routes_using (r);
1522 /* writer goes out of scope and forces update */
1527 Session::resort_routes_using (shared_ptr<RouteList> r)
1529 RouteList::iterator i, j;
1531 for (i = r->begin(); i != r->end(); ++i) {
1533 (*i)->fed_by.clear ();
1535 for (j = r->begin(); j != r->end(); ++j) {
1537 /* although routes can feed themselves, it will
1538 cause an endless recursive descent if we
1539 detect it. so don't bother checking for
1547 if ((*j)->feeds (*i)) {
1548 (*i)->fed_by.insert (*j);
1553 for (i = r->begin(); i != r->end(); ++i) {
1554 trace_terminal (*i, *i);
1560 /* don't leave dangling references to routes in Route::fed_by */
1562 for (i = r->begin(); i != r->end(); ++i) {
1563 (*i)->fed_by.clear ();
1567 cerr << "finished route resort\n";
1569 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1570 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1577 list<boost::shared_ptr<AudioTrack> >
1578 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1580 char track_name[32];
1581 uint32_t track_id = 0;
1583 uint32_t channels_used = 0;
1585 RouteList new_routes;
1586 list<boost::shared_ptr<AudioTrack> > ret;
1588 /* count existing audio tracks */
1591 shared_ptr<RouteList> r = routes.reader ();
1593 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1594 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1595 if (!(*i)->hidden()) {
1597 channels_used += (*i)->n_inputs();
1603 vector<string> physinputs;
1604 vector<string> physoutputs;
1605 uint32_t nphysical_in;
1606 uint32_t nphysical_out;
1608 _engine.get_physical_outputs (physoutputs);
1609 _engine.get_physical_inputs (physinputs);
1613 /* check for duplicate route names, since we might have pre-existing
1614 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1615 save, close,restart,add new route - first named route is now
1623 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1625 if (route_by_name (track_name) == 0) {
1629 } while (track_id < (UINT_MAX-1));
1631 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1632 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1637 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1638 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1644 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1646 if (track->ensure_io (input_channels, output_channels, false, this)) {
1647 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1648 input_channels, output_channels)
1653 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1657 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1658 port = physinputs[(channels_used+x)%nphysical_in];
1661 if (port.length() && track->connect_input (track->input (x), port, this)) {
1667 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1671 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1672 port = physoutputs[(channels_used+x)%nphysical_out];
1673 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1675 port = _master_out->input (x%_master_out->n_inputs())->name();
1679 if (port.length() && track->connect_output (track->output (x), port, this)) {
1684 channels_used += track->n_inputs ();
1687 vector<string> cports;
1688 uint32_t ni = _control_out->n_inputs();
1690 for (n = 0; n < ni; ++n) {
1691 cports.push_back (_control_out->input(n)->name());
1694 track->set_control_outs (cports);
1697 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1698 track->set_remote_control_id (ntracks());
1700 new_routes.push_back (track);
1701 ret.push_back (track);
1704 catch (failed_constructor &err) {
1705 error << _("Session: could not create new audio track.") << endmsg;
1706 // XXX should we delete the tracks already created?
1714 if (!new_routes.empty()) {
1715 add_routes (new_routes, false);
1716 save_state (_current_snapshot_name);
1723 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1726 uint32_t bus_id = 1;
1731 /* count existing audio busses */
1734 shared_ptr<RouteList> r = routes.reader ();
1736 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1737 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1738 if (!(*i)->hidden()) {
1745 vector<string> physinputs;
1746 vector<string> physoutputs;
1748 _engine.get_physical_outputs (physoutputs);
1749 _engine.get_physical_inputs (physinputs);
1756 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1758 if (route_by_name (bus_name) == 0) {
1762 } while (bus_id < (UINT_MAX-1));
1765 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1767 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1768 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1769 input_channels, output_channels)
1773 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1777 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1778 port = physinputs[((n+x)%n_physical_inputs)];
1781 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1786 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1790 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1791 port = physoutputs[((n+x)%n_physical_outputs)];
1792 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1794 port = _master_out->input (x%_master_out->n_inputs())->name();
1798 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1804 vector<string> cports;
1805 uint32_t ni = _control_out->n_inputs();
1807 for (uint32_t n = 0; n < ni; ++n) {
1808 cports.push_back (_control_out->input(n)->name());
1810 bus->set_control_outs (cports);
1813 ret.push_back (bus);
1817 catch (failed_constructor &err) {
1818 error << _("Session: could not create new audio route.") << endmsg;
1827 add_routes (ret, false);
1828 save_state (_current_snapshot_name);
1836 Session::add_routes (RouteList& new_routes, bool save)
1839 RCUWriter<RouteList> writer (routes);
1840 shared_ptr<RouteList> r = writer.get_copy ();
1841 r->insert (r->end(), new_routes.begin(), new_routes.end());
1842 resort_routes_using (r);
1845 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1847 boost::weak_ptr<Route> wpr (*x);
1849 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1850 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1851 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1852 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1854 if ((*x)->master()) {
1858 if ((*x)->control()) {
1859 _control_out = (*x);
1866 save_state (_current_snapshot_name);
1869 RouteAdded (new_routes); /* EMIT SIGNAL */
1873 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1875 /* need to do this in case we're rolling at the time, to prevent false underruns */
1876 dstream->do_refill_with_alloc();
1879 RCUWriter<DiskstreamList> writer (diskstreams);
1880 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1881 ds->push_back (dstream);
1884 dstream->set_block_size (current_block_size);
1886 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1887 /* this will connect to future changes, and check the current length */
1888 diskstream_playlist_changed (dstream);
1890 dstream->prepare ();
1894 Session::remove_route (shared_ptr<Route> route)
1897 RCUWriter<RouteList> writer (routes);
1898 shared_ptr<RouteList> rs = writer.get_copy ();
1901 /* deleting the master out seems like a dumb
1902 idea, but its more of a UI policy issue
1906 if (route == _master_out) {
1907 _master_out = shared_ptr<Route> ();
1910 if (route == _control_out) {
1911 _control_out = shared_ptr<Route> ();
1913 /* cancel control outs for all routes */
1915 vector<string> empty;
1917 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1918 (*r)->set_control_outs (empty);
1922 update_route_solo_state ();
1924 /* writer goes out of scope, forces route list update */
1927 // FIXME: audio specific
1929 boost::shared_ptr<AudioDiskstream> ds;
1931 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1932 ds = at->audio_diskstream();
1938 RCUWriter<DiskstreamList> dsl (diskstreams);
1939 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1944 find_current_end ();
1946 update_latency_compensation (false, false);
1949 // We need to disconnect the routes inputs and outputs
1950 route->disconnect_inputs(NULL);
1951 route->disconnect_outputs(NULL);
1953 /* get rid of it from the dead wood collection in the route list manager */
1955 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1959 /* try to cause everyone to drop their references */
1961 route->drop_references ();
1963 /* save the new state of the world */
1965 if (save_state (_current_snapshot_name)) {
1966 save_history (_current_snapshot_name);
1971 Session::route_mute_changed (void* src)
1977 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1979 if (solo_update_disabled) {
1985 boost::shared_ptr<Route> route = wpr.lock ();
1988 /* should not happen */
1989 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1993 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1995 shared_ptr<RouteList> r = routes.reader ();
1997 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1999 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2003 /* don't mess with busses */
2005 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2011 /* don't mess with tracks */
2013 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2018 if ((*i) != route &&
2019 ((*i)->mix_group () == 0 ||
2020 (*i)->mix_group () != route->mix_group () ||
2021 !route->mix_group ()->is_active())) {
2023 if ((*i)->soloed()) {
2025 /* if its already soloed, and solo latching is enabled,
2026 then leave it as it is.
2029 if (Config->get_solo_latched()) {
2036 solo_update_disabled = true;
2037 (*i)->set_solo (false, src);
2038 solo_update_disabled = false;
2042 bool something_soloed = false;
2043 bool same_thing_soloed = false;
2044 bool signal = false;
2046 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2047 if ((*i)->soloed()) {
2048 something_soloed = true;
2049 if (dynamic_cast<AudioTrack*>((*i).get())) {
2051 same_thing_soloed = true;
2056 same_thing_soloed = true;
2064 if (something_soloed != currently_soloing) {
2066 currently_soloing = something_soloed;
2069 modify_solo_mute (is_track, same_thing_soloed);
2072 SoloActive (currently_soloing);
2079 Session::update_route_solo_state ()
2082 bool is_track = false;
2083 bool signal = false;
2085 /* caller must hold RouteLock */
2087 /* this is where we actually implement solo by changing
2088 the solo mute setting of each track.
2091 shared_ptr<RouteList> r = routes.reader ();
2093 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2094 if ((*i)->soloed()) {
2096 if (dynamic_cast<AudioTrack*>((*i).get())) {
2103 if (mute != currently_soloing) {
2105 currently_soloing = mute;
2108 if (!is_track && !mute) {
2110 /* nothing is soloed */
2112 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2113 (*i)->set_solo_mute (false);
2123 modify_solo_mute (is_track, mute);
2126 SoloActive (currently_soloing);
2131 Session::modify_solo_mute (bool is_track, bool mute)
2133 shared_ptr<RouteList> r = routes.reader ();
2135 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2139 /* only alter track solo mute */
2141 if (dynamic_cast<AudioTrack*>((*i).get())) {
2142 if ((*i)->soloed()) {
2143 (*i)->set_solo_mute (!mute);
2145 (*i)->set_solo_mute (mute);
2151 /* only alter bus solo mute */
2153 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2155 if ((*i)->soloed()) {
2157 (*i)->set_solo_mute (false);
2161 /* don't mute master or control outs
2162 in response to another bus solo
2165 if ((*i) != _master_out &&
2166 (*i) != _control_out) {
2167 (*i)->set_solo_mute (mute);
2178 Session::catch_up_on_solo ()
2180 /* this is called after set_state() to catch the full solo
2181 state, which can't be correctly determined on a per-route
2182 basis, but needs the global overview that only the session
2185 update_route_solo_state();
2189 Session::route_by_name (string name)
2191 shared_ptr<RouteList> r = routes.reader ();
2193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2194 if ((*i)->name() == name) {
2199 return shared_ptr<Route> ((Route*) 0);
2203 Session::route_by_id (PBD::ID id)
2205 shared_ptr<RouteList> r = routes.reader ();
2207 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2208 if ((*i)->id() == id) {
2213 return shared_ptr<Route> ((Route*) 0);
2217 Session::route_by_remote_id (uint32_t id)
2219 shared_ptr<RouteList> r = routes.reader ();
2221 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2222 if ((*i)->remote_control_id() == id) {
2227 return shared_ptr<Route> ((Route*) 0);
2231 Session::find_current_end ()
2233 if (_state_of_the_state & Loading) {
2237 nframes_t max = get_maximum_extent ();
2239 if (max > end_location->end()) {
2240 end_location->set_end (max);
2242 DurationChanged(); /* EMIT SIGNAL */
2247 Session::get_maximum_extent () const
2252 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2254 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2255 Playlist* pl = (*i)->playlist();
2256 if ((me = pl->get_maximum_extent()) > max) {
2264 boost::shared_ptr<Diskstream>
2265 Session::diskstream_by_name (string name)
2267 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2269 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2270 if ((*i)->name() == name) {
2275 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2278 boost::shared_ptr<Diskstream>
2279 Session::diskstream_by_id (const PBD::ID& id)
2281 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2283 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2284 if ((*i)->id() == id) {
2289 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2292 /* AudioRegion management */
2295 Session::new_region_name (string old)
2297 string::size_type last_period;
2299 string::size_type len = old.length() + 64;
2302 if ((last_period = old.find_last_of ('.')) == string::npos) {
2304 /* no period present - add one explicitly */
2307 last_period = old.length() - 1;
2312 number = atoi (old.substr (last_period+1).c_str());
2316 while (number < (UINT_MAX-1)) {
2318 AudioRegionList::const_iterator i;
2323 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2326 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2327 if (i->second->name() == sbuf) {
2332 if (i == audio_regions.end()) {
2337 if (number != (UINT_MAX-1)) {
2341 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2346 Session::region_name (string& result, string base, bool newlevel) const
2353 Glib::Mutex::Lock lm (region_lock);
2355 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2363 /* XXX this is going to be slow. optimize me later */
2368 string::size_type pos;
2370 pos = base.find_last_of ('.');
2372 /* pos may be npos, but then we just use entire base */
2374 subbase = base.substr (0, pos);
2378 bool name_taken = true;
2381 Glib::Mutex::Lock lm (region_lock);
2383 for (int n = 1; n < 5000; ++n) {
2386 snprintf (buf, sizeof (buf), ".%d", n);
2391 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2392 if (i->second->name() == result) {
2405 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2413 Session::add_region (boost::shared_ptr<Region> region)
2415 boost::shared_ptr<AudioRegion> ar;
2416 boost::shared_ptr<AudioRegion> oar;
2420 Glib::Mutex::Lock lm (region_lock);
2422 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2424 AudioRegionList::iterator x;
2426 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2428 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2430 if (ar->region_list_equivalent (oar)) {
2435 if (x == audio_regions.end()) {
2437 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2439 entry.first = region->id();
2442 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2454 fatal << _("programming error: ")
2455 << X_("unknown region type passed to Session::add_region()")
2462 /* mark dirty because something has changed even if we didn't
2463 add the region to the region list.
2469 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2470 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2471 AudioRegionAdded (ar); /* EMIT SIGNAL */
2476 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2478 boost::shared_ptr<Region> region (weak_region.lock ());
2484 if (what_changed & Region::HiddenChanged) {
2485 /* relay hidden changes */
2486 RegionHiddenChange (region);
2491 Session::remove_region (boost::weak_ptr<Region> weak_region)
2493 AudioRegionList::iterator i;
2494 boost::shared_ptr<Region> region (weak_region.lock ());
2500 boost::shared_ptr<AudioRegion> ar;
2501 bool removed = false;
2504 Glib::Mutex::Lock lm (region_lock);
2506 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2507 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2508 audio_regions.erase (i);
2514 fatal << _("programming error: ")
2515 << X_("unknown region type passed to Session::remove_region()")
2521 /* mark dirty because something has changed even if we didn't
2522 remove the region from the region list.
2528 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2532 boost::shared_ptr<AudioRegion>
2533 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2535 AudioRegionList::iterator i;
2536 boost::shared_ptr<AudioRegion> region;
2537 Glib::Mutex::Lock lm (region_lock);
2539 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2543 if (region->whole_file()) {
2545 if (child->source_equivalent (region)) {
2551 return boost::shared_ptr<AudioRegion> ();
2555 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2557 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2558 (*i)->get_region_list_equivalent_regions (region, result);
2562 Session::destroy_region (boost::shared_ptr<Region> region)
2564 boost::shared_ptr<AudioRegion> aregion;
2566 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2570 if (aregion->playlist()) {
2571 aregion->playlist()->destroy_region (region);
2574 vector<boost::shared_ptr<Source> > srcs;
2576 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2577 srcs.push_back (aregion->source (n));
2580 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2582 if ((*i).use_count() == 1) {
2583 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2586 (afs)->mark_for_remove ();
2589 (*i)->drop_references ();
2597 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2599 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2600 destroy_region (*i);
2606 Session::remove_last_capture ()
2608 list<boost::shared_ptr<Region> > r;
2610 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2612 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2613 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2616 r.insert (r.end(), l.begin(), l.end());
2621 destroy_regions (r);
2626 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2632 /* Source Management */
2635 Session::add_source (boost::shared_ptr<Source> source)
2637 boost::shared_ptr<AudioFileSource> afs;
2639 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2641 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2642 pair<AudioSourceList::iterator,bool> result;
2644 entry.first = source->id();
2648 Glib::Mutex::Lock lm (audio_source_lock);
2649 result = audio_sources.insert (entry);
2652 if (!result.second) {
2653 cerr << "\tNOT inserted ? " << result.second << endl;
2656 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2659 SourceAdded (source); /* EMIT SIGNAL */
2661 cerr << "\tNOT AUDIO FILE\n";
2666 Session::remove_source (boost::weak_ptr<Source> src)
2668 AudioSourceList::iterator i;
2669 boost::shared_ptr<Source> source = src.lock();
2676 Glib::Mutex::Lock lm (audio_source_lock);
2678 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2679 audio_sources.erase (i);
2683 if (!_state_of_the_state & InCleanup) {
2685 /* save state so we don't end up with a session file
2686 referring to non-existent sources.
2689 save_state (_current_snapshot_name);
2692 SourceRemoved(source); /* EMIT SIGNAL */
2695 boost::shared_ptr<Source>
2696 Session::source_by_id (const PBD::ID& id)
2698 Glib::Mutex::Lock lm (audio_source_lock);
2699 AudioSourceList::iterator i;
2700 boost::shared_ptr<Source> source;
2702 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2706 /* XXX search MIDI or other searches here */
2712 Session::peak_path_from_audio_path (string audio_path) const
2717 res += PBD::basename_nosuffix (audio_path);
2724 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2727 string old_basename = PBD::basename_nosuffix (oldname);
2728 string new_legalized = legalize_for_path (newname);
2730 /* note: we know (or assume) the old path is already valid */
2734 /* destructive file sources have a name of the form:
2736 /path/to/Tnnnn-NAME(%[LR])?.wav
2738 the task here is to replace NAME with the new name.
2741 /* find last slash */
2745 string::size_type slash;
2746 string::size_type dash;
2748 if ((slash = path.find_last_of ('/')) == string::npos) {
2752 dir = path.substr (0, slash+1);
2754 /* '-' is not a legal character for the NAME part of the path */
2756 if ((dash = path.find_last_of ('-')) == string::npos) {
2760 prefix = path.substr (slash+1, dash-(slash+1));
2765 path += new_legalized;
2766 path += ".wav"; /* XXX gag me with a spoon */
2770 /* non-destructive file sources have a name of the form:
2772 /path/to/NAME-nnnnn(%[LR])?.wav
2774 the task here is to replace NAME with the new name.
2779 string::size_type slash;
2780 string::size_type dash;
2781 string::size_type postfix;
2783 /* find last slash */
2785 if ((slash = path.find_last_of ('/')) == string::npos) {
2789 dir = path.substr (0, slash+1);
2791 /* '-' is not a legal character for the NAME part of the path */
2793 if ((dash = path.find_last_of ('-')) == string::npos) {
2797 suffix = path.substr (dash+1);
2799 // Suffix is now everything after the dash. Now we need to eliminate
2800 // the nnnnn part, which is done by either finding a '%' or a '.'
2802 postfix = suffix.find_last_of ("%");
2803 if (postfix == string::npos) {
2804 postfix = suffix.find_last_of ('.');
2807 if (postfix != string::npos) {
2808 suffix = suffix.substr (postfix);
2810 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2814 const uint32_t limit = 10000;
2815 char buf[PATH_MAX+1];
2817 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2819 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2821 if (access (buf, F_OK) != 0) {
2829 error << "FATAL ERROR! Could not find a " << endl;
2838 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2842 char buf[PATH_MAX+1];
2843 const uint32_t limit = 10000;
2847 legalized = legalize_for_path (name);
2849 /* find a "version" of the file name that doesn't exist in
2850 any of the possible directories.
2853 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2855 vector<space_and_path>::iterator i;
2856 uint32_t existing = 0;
2858 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2862 spath += sound_dir (false);
2866 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2867 } else if (nchan == 2) {
2869 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2871 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2873 } else if (nchan < 26) {
2874 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2876 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2884 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2885 } else if (nchan == 2) {
2887 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2889 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2891 } else if (nchan < 26) {
2892 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2894 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2898 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2904 if (existing == 0) {
2909 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2910 throw failed_constructor();
2914 /* we now have a unique name for the file, but figure out where to
2920 spath = discover_best_sound_dir ();
2922 string::size_type pos = foo.find_last_of ('/');
2924 if (pos == string::npos) {
2927 spath += foo.substr (pos + 1);
2933 boost::shared_ptr<AudioFileSource>
2934 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2936 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2937 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2940 /* Playlist management */
2943 Session::playlist_by_name (string name)
2945 Glib::Mutex::Lock lm (playlist_lock);
2946 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2947 if ((*i)->name() == name) {
2951 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2952 if ((*i)->name() == name) {
2960 Session::add_playlist (Playlist* playlist)
2962 if (playlist->hidden()) {
2967 Glib::Mutex::Lock lm (playlist_lock);
2968 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2969 playlists.insert (playlists.begin(), playlist);
2971 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2972 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2978 PlaylistAdded (playlist); /* EMIT SIGNAL */
2982 Session::track_playlist (Playlist* pl, bool inuse)
2984 PlaylistList::iterator x;
2987 Glib::Mutex::Lock lm (playlist_lock);
2990 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2992 unused_playlists.insert (pl);
2994 if ((x = playlists.find (pl)) != playlists.end()) {
2995 playlists.erase (x);
3000 //cerr << "shifting playlist to used: " << pl->name() << endl;
3002 playlists.insert (pl);
3004 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3005 unused_playlists.erase (x);
3012 Session::remove_playlist (Playlist* playlist)
3014 if (_state_of_the_state & Deletion) {
3019 Glib::Mutex::Lock lm (playlist_lock);
3020 // cerr << "removing playlist: " << playlist->name() << endl;
3022 PlaylistList::iterator i;
3024 i = find (playlists.begin(), playlists.end(), playlist);
3026 if (i != playlists.end()) {
3027 playlists.erase (i);
3030 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3031 if (i != unused_playlists.end()) {
3032 unused_playlists.erase (i);
3039 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3043 Session::set_audition (boost::shared_ptr<Region> r)
3045 pending_audition_region = r;
3046 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3047 schedule_butler_transport_work ();
3051 Session::audition_playlist ()
3053 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3054 ev->region.reset ();
3059 Session::non_realtime_set_audition ()
3061 if (!pending_audition_region) {
3062 auditioner->audition_current_playlist ();
3064 auditioner->audition_region (pending_audition_region);
3065 pending_audition_region.reset ();
3067 AuditionActive (true); /* EMIT SIGNAL */
3071 Session::audition_region (boost::shared_ptr<Region> r)
3073 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3079 Session::cancel_audition ()
3081 if (auditioner->active()) {
3082 auditioner->cancel_audition ();
3083 AuditionActive (false); /* EMIT SIGNAL */
3088 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3090 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3094 Session::remove_empty_sounds ()
3096 PathScanner scanner;
3098 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3100 Glib::Mutex::Lock lm (audio_source_lock);
3102 regex_t compiled_tape_track_pattern;
3105 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3109 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3111 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3115 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3117 /* never remove files that appear to be a tape track */
3119 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3124 if (AudioFileSource::is_empty (*this, *(*i))) {
3126 unlink ((*i)->c_str());
3128 string peak_path = peak_path_from_audio_path (**i);
3129 unlink (peak_path.c_str());
3135 delete possible_audiofiles;
3139 Session::is_auditioning () const
3141 /* can be called before we have an auditioner object */
3143 return auditioner->active();
3150 Session::set_all_solo (bool yn)
3152 shared_ptr<RouteList> r = routes.reader ();
3154 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3155 if (!(*i)->hidden()) {
3156 (*i)->set_solo (yn, this);
3164 Session::set_all_mute (bool yn)
3166 shared_ptr<RouteList> r = routes.reader ();
3168 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3169 if (!(*i)->hidden()) {
3170 (*i)->set_mute (yn, this);
3178 Session::n_diskstreams () const
3182 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3184 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3185 if (!(*i)->hidden()) {
3193 Session::graph_reordered ()
3195 /* don't do this stuff if we are setting up connections
3196 from a set_state() call.
3199 if (_state_of_the_state & InitialConnecting) {
3205 /* force all diskstreams to update their capture offset values to
3206 reflect any changes in latencies within the graph.
3209 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3211 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3212 (*i)->set_capture_offset ();
3217 Session::record_disenable_all ()
3219 record_enable_change_all (false);
3223 Session::record_enable_all ()
3225 record_enable_change_all (true);
3229 Session::record_enable_change_all (bool yn)
3231 shared_ptr<RouteList> r = routes.reader ();
3233 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3236 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3237 at->set_record_enable (yn, this);
3241 /* since we don't keep rec-enable state, don't mark session dirty */
3245 Session::add_redirect (Redirect* redirect)
3249 PortInsert* port_insert;
3250 PluginInsert* plugin_insert;
3252 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3253 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3254 _port_inserts.insert (_port_inserts.begin(), port_insert);
3255 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3256 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3258 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3261 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3262 _sends.insert (_sends.begin(), send);
3264 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3268 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3274 Session::remove_redirect (Redirect* redirect)
3278 PortInsert* port_insert;
3279 PluginInsert* plugin_insert;
3281 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3282 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3283 _port_inserts.remove (port_insert);
3284 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3285 _plugin_inserts.remove (plugin_insert);
3287 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3290 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3291 _sends.remove (send);
3293 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3301 Session::available_capture_duration ()
3303 float sample_bytes_on_disk;
3305 switch (Config->get_native_file_data_format()) {
3307 sample_bytes_on_disk = 4;
3311 sample_bytes_on_disk = 3;
3315 double scale = 4096.0 / sample_bytes_on_disk;
3317 if (_total_free_4k_blocks * scale > (double) max_frames) {
3321 return (nframes_t) floor (_total_free_4k_blocks * scale);
3325 Session::add_connection (ARDOUR::Connection* connection)
3328 Glib::Mutex::Lock guard (connection_lock);
3329 _connections.push_back (connection);
3332 ConnectionAdded (connection); /* EMIT SIGNAL */
3338 Session::remove_connection (ARDOUR::Connection* connection)
3340 bool removed = false;
3343 Glib::Mutex::Lock guard (connection_lock);
3344 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3346 if (i != _connections.end()) {
3347 _connections.erase (i);
3353 ConnectionRemoved (connection); /* EMIT SIGNAL */
3359 ARDOUR::Connection *
3360 Session::connection_by_name (string name) const
3362 Glib::Mutex::Lock lm (connection_lock);
3364 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3365 if ((*i)->name() == name) {
3374 Session::tempo_map_changed (Change ignored)
3381 Session::ensure_passthru_buffers (uint32_t howmany)
3383 while (howmany > _passthru_buffers.size()) {
3385 #ifdef NO_POSIX_MEMALIGN
3386 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3388 posix_memalign((void **)&p,16,current_block_size * 4);
3390 _passthru_buffers.push_back (p);
3394 #ifdef NO_POSIX_MEMALIGN
3395 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3397 posix_memalign((void **)&p,16,current_block_size * 4);
3399 memset (p, 0, sizeof (Sample) * current_block_size);
3400 _silent_buffers.push_back (p);
3404 #ifdef NO_POSIX_MEMALIGN
3405 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3407 posix_memalign((void **)&p,16,current_block_size * 4);
3409 memset (p, 0, sizeof (Sample) * current_block_size);
3410 _send_buffers.push_back (p);
3413 allocate_pan_automation_buffers (current_block_size, howmany, false);
3417 Session::next_send_name ()
3420 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3425 Session::next_insert_name ()
3428 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3432 /* Named Selection management */
3435 Session::named_selection_by_name (string name)
3437 Glib::Mutex::Lock lm (named_selection_lock);
3438 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3439 if ((*i)->name == name) {
3447 Session::add_named_selection (NamedSelection* named_selection)
3450 Glib::Mutex::Lock lm (named_selection_lock);
3451 named_selections.insert (named_selections.begin(), named_selection);
3456 NamedSelectionAdded (); /* EMIT SIGNAL */
3460 Session::remove_named_selection (NamedSelection* named_selection)
3462 bool removed = false;
3465 Glib::Mutex::Lock lm (named_selection_lock);
3467 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3469 if (i != named_selections.end()) {
3471 named_selections.erase (i);
3478 NamedSelectionRemoved (); /* EMIT SIGNAL */
3483 Session::reset_native_file_format ()
3485 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3487 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3488 (*i)->reset_write_sources (false);
3493 Session::route_name_unique (string n) const
3495 shared_ptr<RouteList> r = routes.reader ();
3497 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3498 if ((*i)->name() == n) {
3507 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3509 return fs->move_to_trash (dead_sound_dir_name);
3513 Session::n_playlists () const
3515 Glib::Mutex::Lock lm (playlist_lock);
3516 return playlists.size();
3520 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3522 if (!force && howmany <= _npan_buffers) {
3526 if (_pan_automation_buffer) {
3528 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3529 delete [] _pan_automation_buffer[i];
3532 delete [] _pan_automation_buffer;
3535 _pan_automation_buffer = new pan_t*[howmany];
3537 for (uint32_t i = 0; i < howmany; ++i) {
3538 _pan_automation_buffer[i] = new pan_t[nframes];
3541 _npan_buffers = howmany;
3545 Session::freeze (InterThreadInfo& itt)
3547 shared_ptr<RouteList> r = routes.reader ();
3549 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3553 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3554 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3565 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3566 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3570 boost::shared_ptr<AudioFileSource> fsource;
3572 char buf[PATH_MAX+1];
3576 nframes_t this_chunk;
3578 vector<Sample*> buffers;
3580 // any bigger than this seems to cause stack overflows in called functions
3581 const nframes_t chunk_size = (128 * 1024)/4;
3583 g_atomic_int_set (&processing_prohibited, 1);
3585 /* call tree *MUST* hold route_lock */
3587 if ((playlist = track.diskstream()->playlist()) == 0) {
3591 /* external redirects will be a problem */
3593 if (track.has_external_redirects()) {
3597 nchans = track.audio_diskstream()->n_channels();
3599 dir = discover_best_sound_dir ();
3601 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3603 for (x = 0; x < 99999; ++x) {
3604 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3605 if (access (buf, F_OK) != 0) {
3611 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3616 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3619 catch (failed_constructor& err) {
3620 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3624 srcs.push_back (fsource);
3627 /* XXX need to flush all redirects */
3632 /* create a set of reasonably-sized buffers */
3634 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3636 #ifdef NO_POSIX_MEMALIGN
3637 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3639 posix_memalign((void **)&b,16,chunk_size * 4);
3641 buffers.push_back (b);
3644 while (to_do && !itt.cancel) {
3646 this_chunk = min (to_do, chunk_size);
3648 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3653 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3654 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3657 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3663 start += this_chunk;
3664 to_do -= this_chunk;
3666 itt.progress = (float) (1.0 - ((double) to_do / len));
3675 xnow = localtime (&now);
3677 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3678 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3681 afs->update_header (position, *xnow, now);
3685 /* build peakfile for new source */
3687 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3688 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3690 afs->build_peaks ();
3694 /* construct a region to represent the bounced material */
3696 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3697 region_name_from_path (srcs.front()->name()));
3704 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3705 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3708 afs->mark_for_remove ();
3711 (*src)->drop_references ();
3715 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3719 g_atomic_int_set (&processing_prohibited, 0);
3727 Session::get_silent_buffers (uint32_t howmany)
3729 for (uint32_t i = 0; i < howmany; ++i) {
3730 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3732 return _silent_buffers;
3736 Session::ntracks () const
3739 shared_ptr<RouteList> r = routes.reader ();
3741 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3742 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3751 Session::nbusses () const
3754 shared_ptr<RouteList> r = routes.reader ();
3756 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3757 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3766 Session::add_automation_list(AutomationList *al)
3768 automation_lists[al->id()] = al;