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, compute_initial_length())) {
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));
339 if (create (new_session, 0, initial_length)) {
340 throw failed_constructor ();
344 if (control_out_channels) {
345 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
352 if (master_out_channels) {
353 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
359 /* prohibit auto-connect to master, because there isn't one */
360 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
363 Config->set_input_auto_connect (input_ac);
364 Config->set_output_auto_connect (output_ac);
366 if (second_stage_init (new_session)) {
367 throw failed_constructor ();
370 store_recent_sessions(_name, _path);
372 bool was_dirty = dirty ();
374 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
377 DirtyChanged (); /* EMIT SIGNAL */
383 /* if we got to here, leaving pending capture state around
387 remove_pending_capture_state ();
389 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
390 _engine.remove_session ();
392 GoingAway (); /* EMIT SIGNAL */
398 /* clear history so that no references to objects are held any more */
402 /* clear state tree so that no references to objects are held any more */
408 terminate_butler_thread ();
409 terminate_midi_thread ();
411 if (click_data && click_data != default_click) {
412 delete [] click_data;
415 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
416 delete [] click_emphasis_data;
421 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
425 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
429 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
433 AudioDiskstream::free_working_buffers();
435 /* this should cause deletion of the auditioner */
437 // auditioner.reset ();
439 #undef TRACK_DESTRUCTION
440 #ifdef TRACK_DESTRUCTION
441 cerr << "delete named selections\n";
442 #endif /* TRACK_DESTRUCTION */
443 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
444 NamedSelectionList::iterator tmp;
453 #ifdef TRACK_DESTRUCTION
454 cerr << "delete playlists\n";
455 #endif /* TRACK_DESTRUCTION */
456 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
457 PlaylistList::iterator tmp;
467 #ifdef TRACK_DESTRUCTION
468 cerr << "delete audio regions\n";
469 #endif /* TRACK_DESTRUCTION */
471 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
472 AudioRegionList::iterator tmp;
477 i->second->drop_references ();
482 audio_regions.clear ();
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete routes\n";
486 #endif /* TRACK_DESTRUCTION */
488 RCUWriter<RouteList> writer (routes);
489 boost::shared_ptr<RouteList> r = writer.get_copy ();
490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
491 (*i)->drop_references ();
494 /* writer goes out of scope and updates master */
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete diskstreams\n";
501 #endif /* TRACK_DESTRUCTION */
503 RCUWriter<DiskstreamList> dwriter (diskstreams);
504 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
505 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
506 (*i)->drop_references ();
510 diskstreams.flush ();
512 #ifdef TRACK_DESTRUCTION
513 cerr << "delete audio sources\n";
514 #endif /* TRACK_DESTRUCTION */
515 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
516 AudioSourceList::iterator tmp;
521 i->second->drop_references ();
526 audio_sources.clear ();
528 #ifdef TRACK_DESTRUCTION
529 cerr << "delete mix groups\n";
530 #endif /* TRACK_DESTRUCTION */
531 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
532 list<RouteGroup*>::iterator tmp;
542 #ifdef TRACK_DESTRUCTION
543 cerr << "delete edit groups\n";
544 #endif /* TRACK_DESTRUCTION */
545 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
546 list<RouteGroup*>::iterator tmp;
556 #ifdef TRACK_DESTRUCTION
557 cerr << "delete connections\n";
558 #endif /* TRACK_DESTRUCTION */
559 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
560 ConnectionList::iterator tmp;
570 if (butler_mixdown_buffer) {
571 delete [] butler_mixdown_buffer;
574 if (butler_gain_buffer) {
575 delete [] butler_gain_buffer;
578 Crossfade::set_buffer_size (0);
586 Session::set_worst_io_latencies ()
588 _worst_output_latency = 0;
589 _worst_input_latency = 0;
591 if (!_engine.connected()) {
595 boost::shared_ptr<RouteList> r = routes.reader ();
597 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
598 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
599 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
604 Session::when_engine_running ()
606 string first_physical_output;
608 /* we don't want to run execute this again */
610 first_time_running.disconnect ();
612 set_block_size (_engine.frames_per_cycle());
613 set_frame_rate (_engine.frame_rate());
615 Config->map_parameters (mem_fun (*this, &Session::config_changed));
617 /* every time we reconnect, recompute worst case output latencies */
619 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
621 if (synced_to_jack()) {
622 _engine.transport_stop ();
625 if (Config->get_jack_time_master()) {
626 _engine.transport_locate (_transport_frame);
634 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
636 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
638 /* existing state for Click */
640 if (_click_io->set_state (*child->children().front()) == 0) {
642 _clicking = Config->get_clicking ();
646 error << _("could not setup Click I/O") << endmsg;
652 /* default state for Click */
654 first_physical_output = _engine.get_nth_physical_output (0);
656 if (first_physical_output.length()) {
657 if (_click_io->add_output_port (first_physical_output, this)) {
658 // relax, even though its an error
660 _clicking = Config->get_clicking ();
666 catch (failed_constructor& err) {
667 error << _("cannot setup Click I/O") << endmsg;
670 set_worst_io_latencies ();
673 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
676 if (auditioner == 0) {
678 /* we delay creating the auditioner till now because
679 it makes its own connections to ports named
680 in the ARDOUR_RC config file. the engine has
681 to be running for this to work.
685 auditioner.reset (new Auditioner (*this));
688 catch (failed_constructor& err) {
689 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
693 /* Create a set of Connection objects that map
694 to the physical outputs currently available
699 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
701 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
703 Connection* c = new OutputConnection (buf, true);
706 c->add_connection (0, _engine.get_nth_physical_output (np));
711 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
713 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
715 Connection* c = new InputConnection (buf, true);
718 c->add_connection (0, _engine.get_nth_physical_input (np));
725 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
727 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
729 Connection* c = new OutputConnection (buf, true);
733 c->add_connection (0, _engine.get_nth_physical_output (np));
734 c->add_connection (1, _engine.get_nth_physical_output (np+1));
739 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
741 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
743 Connection* c = new InputConnection (buf, true);
747 c->add_connection (0, _engine.get_nth_physical_input (np));
748 c->add_connection (1, _engine.get_nth_physical_input (np+1));
757 /* create master/control ports */
762 /* force the master to ignore any later call to this */
764 if (_master_out->pending_state_node) {
765 _master_out->ports_became_legal();
768 /* no panner resets till we are through */
770 _master_out->defer_pan_reset ();
772 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
773 if (_master_out->add_input_port ("", this)) {
774 error << _("cannot setup master inputs")
780 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
781 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
782 error << _("cannot setup master outputs")
789 _master_out->allow_pan_reset ();
793 Connection* c = new OutputConnection (_("Master Out"), true);
795 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
797 c->add_connection ((int) n, _master_out->input(n)->name());
804 /* catch up on send+insert cnts */
808 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
811 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
812 if (id > insert_cnt) {
820 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
823 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
830 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
832 /* hook us up to the engine */
834 _engine.set_session (this);
839 osc->set_session (*this);
842 _state_of_the_state = Clean;
844 DirtyChanged (); /* EMIT SIGNAL */
848 Session::hookup_io ()
850 /* stop graph reordering notifications from
851 causing resorts, etc.
854 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
856 /* Tell all IO objects to create their ports */
863 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
864 if (_control_out->add_input_port ("", this)) {
865 error << _("cannot setup control inputs")
871 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
872 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
873 error << _("cannot set up master outputs")
881 /* Tell all IO objects to connect themselves together */
883 IO::enable_connecting ();
885 /* Now reset all panners */
887 IO::reset_panners ();
889 /* Anyone who cares about input state, wake up and do something */
891 IOConnectionsComplete (); /* EMIT SIGNAL */
893 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
895 /* now handle the whole enchilada as if it was one
901 /* update mixer solo state */
907 Session::playlist_length_changed (Playlist* pl)
909 /* we can't just increase end_location->end() if pl->get_maximum_extent()
910 if larger. if the playlist used to be the longest playlist,
911 and its now shorter, we have to decrease end_location->end(). hence,
912 we have to iterate over all diskstreams and check the
913 playlists currently in use.
919 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
923 if ((playlist = dstream->playlist()) != 0) {
924 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
927 /* see comment in playlist_length_changed () */
932 Session::record_enabling_legal () const
934 /* this used to be in here, but survey says.... we don't need to restrict it */
935 // if (record_status() == Recording) {
939 if (Config->get_all_safe()) {
946 Session::reset_input_monitor_state ()
948 if (transport_rolling()) {
950 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
952 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
953 if ((*i)->record_enabled ()) {
954 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
955 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
959 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
961 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
962 if ((*i)->record_enabled ()) {
963 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
964 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
971 Session::auto_punch_start_changed (Location* location)
973 replace_event (Event::PunchIn, location->start());
975 if (get_record_enabled() && Config->get_punch_in()) {
976 /* capture start has been changed, so save new pending state */
977 save_state ("", true);
982 Session::auto_punch_end_changed (Location* location)
984 nframes_t when_to_stop = location->end();
985 // when_to_stop += _worst_output_latency + _worst_input_latency;
986 replace_event (Event::PunchOut, when_to_stop);
990 Session::auto_punch_changed (Location* location)
992 nframes_t when_to_stop = location->end();
994 replace_event (Event::PunchIn, location->start());
995 //when_to_stop += _worst_output_latency + _worst_input_latency;
996 replace_event (Event::PunchOut, when_to_stop);
1000 Session::auto_loop_changed (Location* location)
1002 replace_event (Event::AutoLoop, location->end(), location->start());
1004 if (transport_rolling() && play_loop) {
1006 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1008 if (_transport_frame > location->end()) {
1009 // relocate to beginning of loop
1010 clear_events (Event::LocateRoll);
1012 request_locate (location->start(), true);
1015 else if (Config->get_seamless_loop() && !loop_changing) {
1017 // schedule a locate-roll to refill the diskstreams at the
1018 // previous loop end
1019 loop_changing = true;
1021 if (location->end() > last_loopend) {
1022 clear_events (Event::LocateRoll);
1023 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1030 last_loopend = location->end();
1035 Session::set_auto_punch_location (Location* location)
1039 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1040 auto_punch_start_changed_connection.disconnect();
1041 auto_punch_end_changed_connection.disconnect();
1042 auto_punch_changed_connection.disconnect();
1043 existing->set_auto_punch (false, this);
1044 remove_event (existing->start(), Event::PunchIn);
1045 clear_events (Event::PunchOut);
1046 auto_punch_location_changed (0);
1051 if (location == 0) {
1055 if (location->end() <= location->start()) {
1056 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1060 auto_punch_start_changed_connection.disconnect();
1061 auto_punch_end_changed_connection.disconnect();
1062 auto_punch_changed_connection.disconnect();
1064 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1065 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1066 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1068 location->set_auto_punch (true, this);
1069 auto_punch_location_changed (location);
1073 Session::set_auto_loop_location (Location* location)
1077 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1078 auto_loop_start_changed_connection.disconnect();
1079 auto_loop_end_changed_connection.disconnect();
1080 auto_loop_changed_connection.disconnect();
1081 existing->set_auto_loop (false, this);
1082 remove_event (existing->end(), Event::AutoLoop);
1083 auto_loop_location_changed (0);
1088 if (location == 0) {
1092 if (location->end() <= location->start()) {
1093 error << _("Session: you can't use a mark for auto loop") << endmsg;
1097 last_loopend = location->end();
1099 auto_loop_start_changed_connection.disconnect();
1100 auto_loop_end_changed_connection.disconnect();
1101 auto_loop_changed_connection.disconnect();
1103 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1104 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1105 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1107 location->set_auto_loop (true, this);
1108 auto_loop_location_changed (location);
1112 Session::locations_added (Location* ignored)
1118 Session::locations_changed ()
1120 _locations.apply (*this, &Session::handle_locations_changed);
1124 Session::handle_locations_changed (Locations::LocationList& locations)
1126 Locations::LocationList::iterator i;
1128 bool set_loop = false;
1129 bool set_punch = false;
1131 for (i = locations.begin(); i != locations.end(); ++i) {
1135 if (location->is_auto_punch()) {
1136 set_auto_punch_location (location);
1139 if (location->is_auto_loop()) {
1140 set_auto_loop_location (location);
1147 set_auto_loop_location (0);
1150 set_auto_punch_location (0);
1157 Session::enable_record ()
1159 /* XXX really atomic compare+swap here */
1160 if (g_atomic_int_get (&_record_status) != Recording) {
1161 g_atomic_int_set (&_record_status, Recording);
1162 _last_record_location = _transport_frame;
1163 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1165 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1166 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1167 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1168 if ((*i)->record_enabled ()) {
1169 (*i)->monitor_input (true);
1174 RecordStateChanged ();
1179 Session::disable_record (bool rt_context, bool force)
1183 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1185 if (!Config->get_latched_record_enable () || force) {
1186 g_atomic_int_set (&_record_status, Disabled);
1188 if (rs == Recording) {
1189 g_atomic_int_set (&_record_status, Enabled);
1193 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1195 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1196 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1198 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1199 if ((*i)->record_enabled ()) {
1200 (*i)->monitor_input (false);
1205 RecordStateChanged (); /* emit signal */
1208 remove_pending_capture_state ();
1214 Session::step_back_from_record ()
1216 g_atomic_int_set (&_record_status, Enabled);
1218 if (Config->get_monitoring_model() == HardwareMonitoring) {
1219 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1221 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1222 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1223 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1224 (*i)->monitor_input (false);
1231 Session::maybe_enable_record ()
1233 g_atomic_int_set (&_record_status, Enabled);
1235 /* this function is currently called from somewhere other than an RT thread.
1236 this save_state() call therefore doesn't impact anything.
1239 save_state ("", true);
1241 if (_transport_speed) {
1242 if (!Config->get_punch_in()) {
1246 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1247 RecordStateChanged (); /* EMIT SIGNAL */
1254 Session::audible_frame () const
1260 /* the first of these two possible settings for "offset"
1261 mean that the audible frame is stationary until
1262 audio emerges from the latency compensation
1265 the second means that the audible frame is stationary
1266 until audio would emerge from a physical port
1267 in the absence of any plugin latency compensation
1270 offset = _worst_output_latency;
1272 if (offset > current_block_size) {
1273 offset -= current_block_size;
1275 /* XXX is this correct? if we have no external
1276 physical connections and everything is internal
1277 then surely this is zero? still, how
1278 likely is that anyway?
1280 offset = current_block_size;
1283 if (synced_to_jack()) {
1284 tf = _engine.transport_frame();
1286 tf = _transport_frame;
1289 if (_transport_speed == 0) {
1299 if (!non_realtime_work_pending()) {
1303 /* take latency into account */
1312 Session::set_frame_rate (nframes_t frames_per_second)
1314 /** \fn void Session::set_frame_size(nframes_t)
1315 the AudioEngine object that calls this guarantees
1316 that it will not be called while we are also in
1317 ::process(). Its fine to do things that block
1321 _base_frame_rate = frames_per_second;
1325 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1327 // XXX we need some equivalent to this, somehow
1328 // SndFileSource::setup_standard_crossfades (frames_per_second);
1332 /* XXX need to reset/reinstantiate all LADSPA plugins */
1336 Session::set_block_size (nframes_t nframes)
1338 /* the AudioEngine guarantees
1339 that it will not be called while we are also in
1340 ::process(). It is therefore fine to do things that block
1345 vector<Sample*>::iterator i;
1348 current_block_size = nframes;
1350 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1354 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1358 _passthru_buffers.clear ();
1359 _silent_buffers.clear ();
1361 ensure_passthru_buffers (np);
1363 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1367 #ifdef NO_POSIX_MEMALIGN
1368 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1370 posix_memalign((void **)&buf,16,current_block_size * 4);
1374 memset (*i, 0, sizeof (Sample) * current_block_size);
1378 if (_gain_automation_buffer) {
1379 delete [] _gain_automation_buffer;
1381 _gain_automation_buffer = new gain_t[nframes];
1383 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1385 boost::shared_ptr<RouteList> r = routes.reader ();
1387 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1388 (*i)->set_block_size (nframes);
1391 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1392 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1393 (*i)->set_block_size (nframes);
1396 set_worst_io_latencies ();
1401 Session::set_default_fade (float steepness, float fade_msecs)
1404 nframes_t fade_frames;
1406 /* Don't allow fade of less 1 frame */
1408 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1415 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1419 default_fade_msecs = fade_msecs;
1420 default_fade_steepness = steepness;
1423 // jlc, WTF is this!
1424 Glib::RWLock::ReaderLock lm (route_lock);
1425 AudioRegion::set_default_fade (steepness, fade_frames);
1430 /* XXX have to do this at some point */
1431 /* foreach region using default fade, reset, then
1432 refill_all_diskstream_buffers ();
1437 struct RouteSorter {
1438 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1439 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1441 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1444 if (r1->fed_by.empty()) {
1445 if (r2->fed_by.empty()) {
1446 /* no ardour-based connections inbound to either route. just use signal order */
1447 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1449 /* r2 has connections, r1 does not; run r1 early */
1453 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1460 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1462 shared_ptr<Route> r2;
1464 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1465 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1469 /* make a copy of the existing list of routes that feed r1 */
1471 set<shared_ptr<Route> > existing = r1->fed_by;
1473 /* for each route that feeds r1, recurse, marking it as feeding
1477 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1480 /* r2 is a route that feeds r1 which somehow feeds base. mark
1481 base as being fed by r2
1484 rbase->fed_by.insert (r2);
1488 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1492 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1496 /* now recurse, so that we can mark base as being fed by
1497 all routes that feed r2
1500 trace_terminal (r2, rbase);
1507 Session::resort_routes ()
1509 /* don't do anything here with signals emitted
1510 by Routes while we are being destroyed.
1513 if (_state_of_the_state & Deletion) {
1520 RCUWriter<RouteList> writer (routes);
1521 shared_ptr<RouteList> r = writer.get_copy ();
1522 resort_routes_using (r);
1523 /* writer goes out of scope and forces update */
1528 Session::resort_routes_using (shared_ptr<RouteList> r)
1530 RouteList::iterator i, j;
1532 for (i = r->begin(); i != r->end(); ++i) {
1534 (*i)->fed_by.clear ();
1536 for (j = r->begin(); j != r->end(); ++j) {
1538 /* although routes can feed themselves, it will
1539 cause an endless recursive descent if we
1540 detect it. so don't bother checking for
1548 if ((*j)->feeds (*i)) {
1549 (*i)->fed_by.insert (*j);
1554 for (i = r->begin(); i != r->end(); ++i) {
1555 trace_terminal (*i, *i);
1561 /* don't leave dangling references to routes in Route::fed_by */
1563 for (i = r->begin(); i != r->end(); ++i) {
1564 (*i)->fed_by.clear ();
1568 cerr << "finished route resort\n";
1570 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1571 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1578 list<boost::shared_ptr<AudioTrack> >
1579 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1581 char track_name[32];
1582 uint32_t track_id = 0;
1584 uint32_t channels_used = 0;
1586 RouteList new_routes;
1587 list<boost::shared_ptr<AudioTrack> > ret;
1589 /* count existing audio tracks */
1592 shared_ptr<RouteList> r = routes.reader ();
1594 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1595 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1596 if (!(*i)->hidden()) {
1598 channels_used += (*i)->n_inputs();
1604 vector<string> physinputs;
1605 vector<string> physoutputs;
1606 uint32_t nphysical_in;
1607 uint32_t nphysical_out;
1609 _engine.get_physical_outputs (physoutputs);
1610 _engine.get_physical_inputs (physinputs);
1614 /* check for duplicate route names, since we might have pre-existing
1615 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1616 save, close,restart,add new route - first named route is now
1624 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1626 if (route_by_name (track_name) == 0) {
1630 } while (track_id < (UINT_MAX-1));
1632 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1633 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1638 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1639 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1645 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1647 if (track->ensure_io (input_channels, output_channels, false, this)) {
1648 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1649 input_channels, output_channels)
1654 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1658 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1659 port = physinputs[(channels_used+x)%nphysical_in];
1662 if (port.length() && track->connect_input (track->input (x), port, this)) {
1668 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1672 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1673 port = physoutputs[(channels_used+x)%nphysical_out];
1674 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1676 port = _master_out->input (x%_master_out->n_inputs())->name();
1680 if (port.length() && track->connect_output (track->output (x), port, this)) {
1685 channels_used += track->n_inputs ();
1688 vector<string> cports;
1689 uint32_t ni = _control_out->n_inputs();
1691 for (n = 0; n < ni; ++n) {
1692 cports.push_back (_control_out->input(n)->name());
1695 track->set_control_outs (cports);
1698 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1699 track->set_remote_control_id (ntracks());
1701 new_routes.push_back (track);
1702 ret.push_back (track);
1705 catch (failed_constructor &err) {
1706 error << _("Session: could not create new audio track.") << endmsg;
1707 // XXX should we delete the tracks already created?
1715 if (!new_routes.empty()) {
1716 add_routes (new_routes, false);
1717 save_state (_current_snapshot_name);
1724 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1727 uint32_t bus_id = 1;
1732 /* count existing audio busses */
1735 shared_ptr<RouteList> r = routes.reader ();
1737 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1738 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1739 if (!(*i)->hidden()) {
1746 vector<string> physinputs;
1747 vector<string> physoutputs;
1749 _engine.get_physical_outputs (physoutputs);
1750 _engine.get_physical_inputs (physinputs);
1757 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1759 if (route_by_name (bus_name) == 0) {
1763 } while (bus_id < (UINT_MAX-1));
1766 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1768 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1769 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1770 input_channels, output_channels)
1774 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1778 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1779 port = physinputs[((n+x)%n_physical_inputs)];
1782 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1787 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1791 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1792 port = physoutputs[((n+x)%n_physical_outputs)];
1793 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1795 port = _master_out->input (x%_master_out->n_inputs())->name();
1799 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1805 vector<string> cports;
1806 uint32_t ni = _control_out->n_inputs();
1808 for (uint32_t n = 0; n < ni; ++n) {
1809 cports.push_back (_control_out->input(n)->name());
1811 bus->set_control_outs (cports);
1814 ret.push_back (bus);
1818 catch (failed_constructor &err) {
1819 error << _("Session: could not create new audio route.") << endmsg;
1828 add_routes (ret, false);
1829 save_state (_current_snapshot_name);
1837 Session::add_routes (RouteList& new_routes, bool save)
1840 RCUWriter<RouteList> writer (routes);
1841 shared_ptr<RouteList> r = writer.get_copy ();
1842 r->insert (r->end(), new_routes.begin(), new_routes.end());
1843 resort_routes_using (r);
1846 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1848 boost::weak_ptr<Route> wpr (*x);
1850 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1851 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1852 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1853 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1855 if ((*x)->master()) {
1859 if ((*x)->control()) {
1860 _control_out = (*x);
1867 save_state (_current_snapshot_name);
1870 RouteAdded (new_routes); /* EMIT SIGNAL */
1874 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1876 /* need to do this in case we're rolling at the time, to prevent false underruns */
1877 dstream->do_refill_with_alloc();
1880 RCUWriter<DiskstreamList> writer (diskstreams);
1881 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1882 ds->push_back (dstream);
1885 dstream->set_block_size (current_block_size);
1887 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1888 /* this will connect to future changes, and check the current length */
1889 diskstream_playlist_changed (dstream);
1891 dstream->prepare ();
1895 Session::remove_route (shared_ptr<Route> route)
1898 RCUWriter<RouteList> writer (routes);
1899 shared_ptr<RouteList> rs = writer.get_copy ();
1903 /* deleting the master out seems like a dumb
1904 idea, but its more of a UI policy issue
1908 if (route == _master_out) {
1909 _master_out = shared_ptr<Route> ();
1912 if (route == _control_out) {
1913 _control_out = shared_ptr<Route> ();
1915 /* cancel control outs for all routes */
1917 vector<string> empty;
1919 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1920 (*r)->set_control_outs (empty);
1924 update_route_solo_state ();
1926 /* writer goes out of scope, forces route list update */
1929 // FIXME: audio specific
1931 boost::shared_ptr<AudioDiskstream> ds;
1933 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1934 ds = at->audio_diskstream();
1940 RCUWriter<DiskstreamList> dsl (diskstreams);
1941 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1946 find_current_end ();
1948 update_latency_compensation (false, false);
1951 // We need to disconnect the routes inputs and outputs
1952 route->disconnect_inputs(NULL);
1953 route->disconnect_outputs(NULL);
1955 /* get rid of it from the dead wood collection in the route list manager */
1957 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1961 /* try to cause everyone to drop their references */
1963 route->drop_references ();
1965 /* save the new state of the world */
1967 if (save_state (_current_snapshot_name)) {
1968 save_history (_current_snapshot_name);
1973 Session::route_mute_changed (void* src)
1979 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1981 if (solo_update_disabled) {
1987 boost::shared_ptr<Route> route = wpr.lock ();
1990 /* should not happen */
1991 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1995 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1997 shared_ptr<RouteList> r = routes.reader ();
1999 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2001 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2005 /* don't mess with busses */
2007 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2013 /* don't mess with tracks */
2015 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2020 if ((*i) != route &&
2021 ((*i)->mix_group () == 0 ||
2022 (*i)->mix_group () != route->mix_group () ||
2023 !route->mix_group ()->is_active())) {
2025 if ((*i)->soloed()) {
2027 /* if its already soloed, and solo latching is enabled,
2028 then leave it as it is.
2031 if (Config->get_solo_latched()) {
2038 solo_update_disabled = true;
2039 (*i)->set_solo (false, src);
2040 solo_update_disabled = false;
2044 bool something_soloed = false;
2045 bool same_thing_soloed = false;
2046 bool signal = false;
2048 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2049 if ((*i)->soloed()) {
2050 something_soloed = true;
2051 if (dynamic_cast<AudioTrack*>((*i).get())) {
2053 same_thing_soloed = true;
2058 same_thing_soloed = true;
2066 if (something_soloed != currently_soloing) {
2068 currently_soloing = something_soloed;
2071 modify_solo_mute (is_track, same_thing_soloed);
2074 SoloActive (currently_soloing);
2081 Session::update_route_solo_state ()
2084 bool is_track = false;
2085 bool signal = false;
2087 /* caller must hold RouteLock */
2089 /* this is where we actually implement solo by changing
2090 the solo mute setting of each track.
2093 shared_ptr<RouteList> r = routes.reader ();
2095 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2096 if ((*i)->soloed()) {
2098 if (dynamic_cast<AudioTrack*>((*i).get())) {
2105 if (mute != currently_soloing) {
2107 currently_soloing = mute;
2110 if (!is_track && !mute) {
2112 /* nothing is soloed */
2114 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2115 (*i)->set_solo_mute (false);
2125 modify_solo_mute (is_track, mute);
2128 SoloActive (currently_soloing);
2133 Session::modify_solo_mute (bool is_track, bool mute)
2135 shared_ptr<RouteList> r = routes.reader ();
2137 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2141 /* only alter track solo mute */
2143 if (dynamic_cast<AudioTrack*>((*i).get())) {
2144 if ((*i)->soloed()) {
2145 (*i)->set_solo_mute (!mute);
2147 (*i)->set_solo_mute (mute);
2153 /* only alter bus solo mute */
2155 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2157 if ((*i)->soloed()) {
2159 (*i)->set_solo_mute (false);
2163 /* don't mute master or control outs
2164 in response to another bus solo
2167 if ((*i) != _master_out &&
2168 (*i) != _control_out) {
2169 (*i)->set_solo_mute (mute);
2180 Session::catch_up_on_solo ()
2182 /* this is called after set_state() to catch the full solo
2183 state, which can't be correctly determined on a per-route
2184 basis, but needs the global overview that only the session
2187 update_route_solo_state();
2191 Session::route_by_name (string name)
2193 shared_ptr<RouteList> r = routes.reader ();
2195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2196 if ((*i)->name() == name) {
2201 return shared_ptr<Route> ((Route*) 0);
2205 Session::route_by_id (PBD::ID id)
2207 shared_ptr<RouteList> r = routes.reader ();
2209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2210 if ((*i)->id() == id) {
2215 return shared_ptr<Route> ((Route*) 0);
2219 Session::route_by_remote_id (uint32_t id)
2221 shared_ptr<RouteList> r = routes.reader ();
2223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2224 if ((*i)->remote_control_id() == id) {
2229 return shared_ptr<Route> ((Route*) 0);
2233 Session::find_current_end ()
2235 if (_state_of_the_state & Loading) {
2239 nframes_t max = get_maximum_extent ();
2241 if (max > end_location->end()) {
2242 end_location->set_end (max);
2244 DurationChanged(); /* EMIT SIGNAL */
2249 Session::get_maximum_extent () const
2254 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2256 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2257 Playlist* pl = (*i)->playlist();
2258 if ((me = pl->get_maximum_extent()) > max) {
2266 boost::shared_ptr<Diskstream>
2267 Session::diskstream_by_name (string name)
2269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2272 if ((*i)->name() == name) {
2277 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2280 boost::shared_ptr<Diskstream>
2281 Session::diskstream_by_id (const PBD::ID& id)
2283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2286 if ((*i)->id() == id) {
2291 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2294 /* AudioRegion management */
2297 Session::new_region_name (string old)
2299 string::size_type last_period;
2301 string::size_type len = old.length() + 64;
2304 if ((last_period = old.find_last_of ('.')) == string::npos) {
2306 /* no period present - add one explicitly */
2309 last_period = old.length() - 1;
2314 number = atoi (old.substr (last_period+1).c_str());
2318 while (number < (UINT_MAX-1)) {
2320 AudioRegionList::const_iterator i;
2325 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2328 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2329 if (i->second->name() == sbuf) {
2334 if (i == audio_regions.end()) {
2339 if (number != (UINT_MAX-1)) {
2343 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2348 Session::region_name (string& result, string base, bool newlevel) const
2355 Glib::Mutex::Lock lm (region_lock);
2357 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2365 /* XXX this is going to be slow. optimize me later */
2370 string::size_type pos;
2372 pos = base.find_last_of ('.');
2374 /* pos may be npos, but then we just use entire base */
2376 subbase = base.substr (0, pos);
2380 bool name_taken = true;
2383 Glib::Mutex::Lock lm (region_lock);
2385 for (int n = 1; n < 5000; ++n) {
2388 snprintf (buf, sizeof (buf), ".%d", n);
2393 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2394 if (i->second->name() == result) {
2407 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2415 Session::add_region (boost::shared_ptr<Region> region)
2417 boost::shared_ptr<AudioRegion> ar;
2418 boost::shared_ptr<AudioRegion> oar;
2422 Glib::Mutex::Lock lm (region_lock);
2424 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2426 AudioRegionList::iterator x;
2428 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2430 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2432 if (ar->region_list_equivalent (oar)) {
2437 if (x == audio_regions.end()) {
2439 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2441 entry.first = region->id();
2444 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2456 fatal << _("programming error: ")
2457 << X_("unknown region type passed to Session::add_region()")
2464 /* mark dirty because something has changed even if we didn't
2465 add the region to the region list.
2471 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2472 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2473 AudioRegionAdded (ar); /* EMIT SIGNAL */
2478 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2480 boost::shared_ptr<Region> region (weak_region.lock ());
2486 if (what_changed & Region::HiddenChanged) {
2487 /* relay hidden changes */
2488 RegionHiddenChange (region);
2493 Session::remove_region (boost::weak_ptr<Region> weak_region)
2495 AudioRegionList::iterator i;
2496 boost::shared_ptr<Region> region (weak_region.lock ());
2502 boost::shared_ptr<AudioRegion> ar;
2503 bool removed = false;
2506 Glib::Mutex::Lock lm (region_lock);
2508 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2509 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2510 audio_regions.erase (i);
2516 fatal << _("programming error: ")
2517 << X_("unknown region type passed to Session::remove_region()")
2523 /* mark dirty because something has changed even if we didn't
2524 remove the region from the region list.
2530 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2534 boost::shared_ptr<AudioRegion>
2535 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2537 AudioRegionList::iterator i;
2538 boost::shared_ptr<AudioRegion> region;
2539 Glib::Mutex::Lock lm (region_lock);
2541 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2545 if (region->whole_file()) {
2547 if (child->source_equivalent (region)) {
2553 return boost::shared_ptr<AudioRegion> ();
2557 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2559 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2560 (*i)->get_region_list_equivalent_regions (region, result);
2564 Session::destroy_region (boost::shared_ptr<Region> region)
2566 boost::shared_ptr<AudioRegion> aregion;
2568 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2572 if (aregion->playlist()) {
2573 aregion->playlist()->destroy_region (region);
2576 vector<boost::shared_ptr<Source> > srcs;
2578 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2579 srcs.push_back (aregion->source (n));
2582 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2584 if ((*i).use_count() == 1) {
2585 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2588 (afs)->mark_for_remove ();
2591 (*i)->drop_references ();
2599 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2601 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2602 destroy_region (*i);
2608 Session::remove_last_capture ()
2610 list<boost::shared_ptr<Region> > r;
2612 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2614 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2615 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2618 r.insert (r.end(), l.begin(), l.end());
2623 destroy_regions (r);
2628 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2634 /* Source Management */
2637 Session::add_source (boost::shared_ptr<Source> source)
2639 boost::shared_ptr<AudioFileSource> afs;
2641 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2643 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2644 pair<AudioSourceList::iterator,bool> result;
2646 entry.first = source->id();
2650 Glib::Mutex::Lock lm (audio_source_lock);
2651 result = audio_sources.insert (entry);
2654 if (!result.second) {
2655 cerr << "\tNOT inserted ? " << result.second << endl;
2658 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2661 SourceAdded (source); /* EMIT SIGNAL */
2663 cerr << "\tNOT AUDIO FILE\n";
2668 Session::remove_source (boost::weak_ptr<Source> src)
2670 AudioSourceList::iterator i;
2671 boost::shared_ptr<Source> source = src.lock();
2678 Glib::Mutex::Lock lm (audio_source_lock);
2680 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2681 audio_sources.erase (i);
2685 if (!_state_of_the_state & InCleanup) {
2687 /* save state so we don't end up with a session file
2688 referring to non-existent sources.
2691 save_state (_current_snapshot_name);
2694 SourceRemoved(source); /* EMIT SIGNAL */
2697 boost::shared_ptr<Source>
2698 Session::source_by_id (const PBD::ID& id)
2700 Glib::Mutex::Lock lm (audio_source_lock);
2701 AudioSourceList::iterator i;
2702 boost::shared_ptr<Source> source;
2704 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2708 /* XXX search MIDI or other searches here */
2714 Session::peak_path_from_audio_path (string audio_path) const
2719 res += PBD::basename_nosuffix (audio_path);
2726 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2729 string old_basename = PBD::basename_nosuffix (oldname);
2730 string new_legalized = legalize_for_path (newname);
2732 /* note: we know (or assume) the old path is already valid */
2736 /* destructive file sources have a name of the form:
2738 /path/to/Tnnnn-NAME(%[LR])?.wav
2740 the task here is to replace NAME with the new name.
2743 /* find last slash */
2747 string::size_type slash;
2748 string::size_type dash;
2750 if ((slash = path.find_last_of ('/')) == string::npos) {
2754 dir = path.substr (0, slash+1);
2756 /* '-' is not a legal character for the NAME part of the path */
2758 if ((dash = path.find_last_of ('-')) == string::npos) {
2762 prefix = path.substr (slash+1, dash-(slash+1));
2767 path += new_legalized;
2768 path += ".wav"; /* XXX gag me with a spoon */
2772 /* non-destructive file sources have a name of the form:
2774 /path/to/NAME-nnnnn(%[LR])?.wav
2776 the task here is to replace NAME with the new name.
2781 string::size_type slash;
2782 string::size_type dash;
2783 string::size_type postfix;
2785 /* find last slash */
2787 if ((slash = path.find_last_of ('/')) == string::npos) {
2791 dir = path.substr (0, slash+1);
2793 /* '-' is not a legal character for the NAME part of the path */
2795 if ((dash = path.find_last_of ('-')) == string::npos) {
2799 suffix = path.substr (dash+1);
2801 // Suffix is now everything after the dash. Now we need to eliminate
2802 // the nnnnn part, which is done by either finding a '%' or a '.'
2804 postfix = suffix.find_last_of ("%");
2805 if (postfix == string::npos) {
2806 postfix = suffix.find_last_of ('.');
2809 if (postfix != string::npos) {
2810 suffix = suffix.substr (postfix);
2812 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2816 const uint32_t limit = 10000;
2817 char buf[PATH_MAX+1];
2819 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2821 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2823 if (access (buf, F_OK) != 0) {
2831 error << "FATAL ERROR! Could not find a " << endl;
2840 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2844 char buf[PATH_MAX+1];
2845 const uint32_t limit = 10000;
2849 legalized = legalize_for_path (name);
2851 /* find a "version" of the file name that doesn't exist in
2852 any of the possible directories.
2855 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2857 vector<space_and_path>::iterator i;
2858 uint32_t existing = 0;
2860 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2864 spath += sound_dir (false);
2868 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2869 } else if (nchan == 2) {
2871 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2873 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2875 } else if (nchan < 26) {
2876 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2878 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2886 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2887 } else if (nchan == 2) {
2889 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2891 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2893 } else if (nchan < 26) {
2894 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2896 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2900 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2906 if (existing == 0) {
2911 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2912 throw failed_constructor();
2916 /* we now have a unique name for the file, but figure out where to
2922 spath = discover_best_sound_dir ();
2924 string::size_type pos = foo.find_last_of ('/');
2926 if (pos == string::npos) {
2929 spath += foo.substr (pos + 1);
2935 boost::shared_ptr<AudioFileSource>
2936 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2938 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2939 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2942 /* Playlist management */
2945 Session::playlist_by_name (string name)
2947 Glib::Mutex::Lock lm (playlist_lock);
2948 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2949 if ((*i)->name() == name) {
2953 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2954 if ((*i)->name() == name) {
2962 Session::add_playlist (Playlist* playlist)
2964 if (playlist->hidden()) {
2969 Glib::Mutex::Lock lm (playlist_lock);
2970 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2971 playlists.insert (playlists.begin(), playlist);
2973 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2974 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2980 PlaylistAdded (playlist); /* EMIT SIGNAL */
2984 Session::track_playlist (Playlist* pl, bool inuse)
2986 PlaylistList::iterator x;
2989 Glib::Mutex::Lock lm (playlist_lock);
2992 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2994 unused_playlists.insert (pl);
2996 if ((x = playlists.find (pl)) != playlists.end()) {
2997 playlists.erase (x);
3002 //cerr << "shifting playlist to used: " << pl->name() << endl;
3004 playlists.insert (pl);
3006 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3007 unused_playlists.erase (x);
3014 Session::remove_playlist (Playlist* playlist)
3016 if (_state_of_the_state & Deletion) {
3021 Glib::Mutex::Lock lm (playlist_lock);
3022 // cerr << "removing playlist: " << playlist->name() << endl;
3024 PlaylistList::iterator i;
3026 i = find (playlists.begin(), playlists.end(), playlist);
3028 if (i != playlists.end()) {
3029 playlists.erase (i);
3032 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3033 if (i != unused_playlists.end()) {
3034 unused_playlists.erase (i);
3041 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3045 Session::set_audition (boost::shared_ptr<Region> r)
3047 pending_audition_region = r;
3048 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3049 schedule_butler_transport_work ();
3053 Session::audition_playlist ()
3055 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3056 ev->region.reset ();
3061 Session::non_realtime_set_audition ()
3063 if (!pending_audition_region) {
3064 auditioner->audition_current_playlist ();
3066 auditioner->audition_region (pending_audition_region);
3067 pending_audition_region.reset ();
3069 AuditionActive (true); /* EMIT SIGNAL */
3073 Session::audition_region (boost::shared_ptr<Region> r)
3075 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3081 Session::cancel_audition ()
3083 if (auditioner->active()) {
3084 auditioner->cancel_audition ();
3085 AuditionActive (false); /* EMIT SIGNAL */
3090 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3092 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3096 Session::remove_empty_sounds ()
3098 PathScanner scanner;
3100 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3102 Glib::Mutex::Lock lm (audio_source_lock);
3104 regex_t compiled_tape_track_pattern;
3107 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3111 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3113 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3117 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3119 /* never remove files that appear to be a tape track */
3121 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3126 if (AudioFileSource::is_empty (*this, *(*i))) {
3128 unlink ((*i)->c_str());
3130 string peak_path = peak_path_from_audio_path (**i);
3131 unlink (peak_path.c_str());
3137 delete possible_audiofiles;
3141 Session::is_auditioning () const
3143 /* can be called before we have an auditioner object */
3145 return auditioner->active();
3152 Session::set_all_solo (bool yn)
3154 shared_ptr<RouteList> r = routes.reader ();
3156 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3157 if (!(*i)->hidden()) {
3158 (*i)->set_solo (yn, this);
3166 Session::set_all_mute (bool yn)
3168 shared_ptr<RouteList> r = routes.reader ();
3170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3171 if (!(*i)->hidden()) {
3172 (*i)->set_mute (yn, this);
3180 Session::n_diskstreams () const
3184 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3186 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3187 if (!(*i)->hidden()) {
3195 Session::graph_reordered ()
3197 /* don't do this stuff if we are setting up connections
3198 from a set_state() call.
3201 if (_state_of_the_state & InitialConnecting) {
3207 /* force all diskstreams to update their capture offset values to
3208 reflect any changes in latencies within the graph.
3211 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3213 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3214 (*i)->set_capture_offset ();
3219 Session::record_disenable_all ()
3221 record_enable_change_all (false);
3225 Session::record_enable_all ()
3227 record_enable_change_all (true);
3231 Session::record_enable_change_all (bool yn)
3233 shared_ptr<RouteList> r = routes.reader ();
3235 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3238 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3239 at->set_record_enable (yn, this);
3243 /* since we don't keep rec-enable state, don't mark session dirty */
3247 Session::add_redirect (Redirect* redirect)
3251 PortInsert* port_insert;
3252 PluginInsert* plugin_insert;
3254 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3255 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3256 _port_inserts.insert (_port_inserts.begin(), port_insert);
3257 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3258 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3260 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3263 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3264 _sends.insert (_sends.begin(), send);
3266 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3270 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3276 Session::remove_redirect (Redirect* redirect)
3280 PortInsert* port_insert;
3281 PluginInsert* plugin_insert;
3283 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3284 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3285 _port_inserts.remove (port_insert);
3286 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3287 _plugin_inserts.remove (plugin_insert);
3289 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3292 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3293 _sends.remove (send);
3295 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3303 Session::available_capture_duration ()
3305 float sample_bytes_on_disk;
3307 switch (Config->get_native_file_data_format()) {
3309 sample_bytes_on_disk = 4;
3313 sample_bytes_on_disk = 3;
3317 double scale = 4096.0 / sample_bytes_on_disk;
3319 if (_total_free_4k_blocks * scale > (double) max_frames) {
3323 return (nframes_t) floor (_total_free_4k_blocks * scale);
3327 Session::add_connection (ARDOUR::Connection* connection)
3330 Glib::Mutex::Lock guard (connection_lock);
3331 _connections.push_back (connection);
3334 ConnectionAdded (connection); /* EMIT SIGNAL */
3340 Session::remove_connection (ARDOUR::Connection* connection)
3342 bool removed = false;
3345 Glib::Mutex::Lock guard (connection_lock);
3346 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3348 if (i != _connections.end()) {
3349 _connections.erase (i);
3355 ConnectionRemoved (connection); /* EMIT SIGNAL */
3361 ARDOUR::Connection *
3362 Session::connection_by_name (string name) const
3364 Glib::Mutex::Lock lm (connection_lock);
3366 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3367 if ((*i)->name() == name) {
3376 Session::tempo_map_changed (Change ignored)
3383 Session::ensure_passthru_buffers (uint32_t howmany)
3385 while (howmany > _passthru_buffers.size()) {
3387 #ifdef NO_POSIX_MEMALIGN
3388 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3390 posix_memalign((void **)&p,16,current_block_size * 4);
3392 _passthru_buffers.push_back (p);
3396 #ifdef NO_POSIX_MEMALIGN
3397 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3399 posix_memalign((void **)&p,16,current_block_size * 4);
3401 memset (p, 0, sizeof (Sample) * current_block_size);
3402 _silent_buffers.push_back (p);
3406 #ifdef NO_POSIX_MEMALIGN
3407 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3409 posix_memalign((void **)&p,16,current_block_size * 4);
3411 memset (p, 0, sizeof (Sample) * current_block_size);
3412 _send_buffers.push_back (p);
3415 allocate_pan_automation_buffers (current_block_size, howmany, false);
3419 Session::next_send_name ()
3422 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3427 Session::next_insert_name ()
3430 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3434 /* Named Selection management */
3437 Session::named_selection_by_name (string name)
3439 Glib::Mutex::Lock lm (named_selection_lock);
3440 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3441 if ((*i)->name == name) {
3449 Session::add_named_selection (NamedSelection* named_selection)
3452 Glib::Mutex::Lock lm (named_selection_lock);
3453 named_selections.insert (named_selections.begin(), named_selection);
3458 NamedSelectionAdded (); /* EMIT SIGNAL */
3462 Session::remove_named_selection (NamedSelection* named_selection)
3464 bool removed = false;
3467 Glib::Mutex::Lock lm (named_selection_lock);
3469 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3471 if (i != named_selections.end()) {
3473 named_selections.erase (i);
3480 NamedSelectionRemoved (); /* EMIT SIGNAL */
3485 Session::reset_native_file_format ()
3487 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3489 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3490 (*i)->reset_write_sources (false);
3495 Session::route_name_unique (string n) const
3497 shared_ptr<RouteList> r = routes.reader ();
3499 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3500 if ((*i)->name() == n) {
3509 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3511 return fs->move_to_trash (dead_sound_dir_name);
3515 Session::n_playlists () const
3517 Glib::Mutex::Lock lm (playlist_lock);
3518 return playlists.size();
3522 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3524 if (!force && howmany <= _npan_buffers) {
3528 if (_pan_automation_buffer) {
3530 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3531 delete [] _pan_automation_buffer[i];
3534 delete [] _pan_automation_buffer;
3537 _pan_automation_buffer = new pan_t*[howmany];
3539 for (uint32_t i = 0; i < howmany; ++i) {
3540 _pan_automation_buffer[i] = new pan_t[nframes];
3543 _npan_buffers = howmany;
3547 Session::freeze (InterThreadInfo& itt)
3549 shared_ptr<RouteList> r = routes.reader ();
3551 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3555 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3556 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3567 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3568 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3572 boost::shared_ptr<AudioFileSource> fsource;
3574 char buf[PATH_MAX+1];
3578 nframes_t this_chunk;
3580 vector<Sample*> buffers;
3582 // any bigger than this seems to cause stack overflows in called functions
3583 const nframes_t chunk_size = (128 * 1024)/4;
3585 g_atomic_int_set (&processing_prohibited, 1);
3587 /* call tree *MUST* hold route_lock */
3589 if ((playlist = track.diskstream()->playlist()) == 0) {
3593 /* external redirects will be a problem */
3595 if (track.has_external_redirects()) {
3599 nchans = track.audio_diskstream()->n_channels();
3601 dir = discover_best_sound_dir ();
3603 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3605 for (x = 0; x < 99999; ++x) {
3606 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3607 if (access (buf, F_OK) != 0) {
3613 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3618 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3621 catch (failed_constructor& err) {
3622 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3626 srcs.push_back (fsource);
3629 /* XXX need to flush all redirects */
3634 /* create a set of reasonably-sized buffers */
3636 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3638 #ifdef NO_POSIX_MEMALIGN
3639 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3641 posix_memalign((void **)&b,16,chunk_size * 4);
3643 buffers.push_back (b);
3646 while (to_do && !itt.cancel) {
3648 this_chunk = min (to_do, chunk_size);
3650 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3655 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3656 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3659 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3665 start += this_chunk;
3666 to_do -= this_chunk;
3668 itt.progress = (float) (1.0 - ((double) to_do / len));
3677 xnow = localtime (&now);
3679 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3680 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3683 afs->update_header (position, *xnow, now);
3687 /* build peakfile for new source */
3689 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3690 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3692 afs->build_peaks ();
3696 /* construct a region to represent the bounced material */
3698 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3699 region_name_from_path (srcs.front()->name()));
3706 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3707 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3710 afs->mark_for_remove ();
3713 (*src)->drop_references ();
3717 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3721 g_atomic_int_set (&processing_prohibited, 0);
3729 Session::get_silent_buffers (uint32_t howmany)
3731 for (uint32_t i = 0; i < howmany; ++i) {
3732 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3734 return _silent_buffers;
3738 Session::ntracks () const
3741 shared_ptr<RouteList> r = routes.reader ();
3743 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3744 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3753 Session::nbusses () const
3756 shared_ptr<RouteList> r = routes.reader ();
3758 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3759 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3768 Session::add_automation_list(AutomationList *al)
3770 automation_lists[al->id()] = al;
3774 Session::compute_initial_length ()
3776 return _engine.frame_rate() * 60 * 5;