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));
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 ();
1902 /* deleting the master out seems like a dumb
1903 idea, but its more of a UI policy issue
1907 if (route == _master_out) {
1908 _master_out = shared_ptr<Route> ();
1911 if (route == _control_out) {
1912 _control_out = shared_ptr<Route> ();
1914 /* cancel control outs for all routes */
1916 vector<string> empty;
1918 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1919 (*r)->set_control_outs (empty);
1923 update_route_solo_state ();
1925 /* writer goes out of scope, forces route list update */
1928 // FIXME: audio specific
1930 boost::shared_ptr<AudioDiskstream> ds;
1932 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1933 ds = at->audio_diskstream();
1939 RCUWriter<DiskstreamList> dsl (diskstreams);
1940 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1945 find_current_end ();
1947 update_latency_compensation (false, false);
1950 // We need to disconnect the routes inputs and outputs
1951 route->disconnect_inputs(NULL);
1952 route->disconnect_outputs(NULL);
1954 /* get rid of it from the dead wood collection in the route list manager */
1956 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1960 /* try to cause everyone to drop their references */
1962 route->drop_references ();
1964 /* save the new state of the world */
1966 if (save_state (_current_snapshot_name)) {
1967 save_history (_current_snapshot_name);
1972 Session::route_mute_changed (void* src)
1978 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1980 if (solo_update_disabled) {
1986 boost::shared_ptr<Route> route = wpr.lock ();
1989 /* should not happen */
1990 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
1994 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
1996 shared_ptr<RouteList> r = routes.reader ();
1998 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2000 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2004 /* don't mess with busses */
2006 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2012 /* don't mess with tracks */
2014 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2019 if ((*i) != route &&
2020 ((*i)->mix_group () == 0 ||
2021 (*i)->mix_group () != route->mix_group () ||
2022 !route->mix_group ()->is_active())) {
2024 if ((*i)->soloed()) {
2026 /* if its already soloed, and solo latching is enabled,
2027 then leave it as it is.
2030 if (Config->get_solo_latched()) {
2037 solo_update_disabled = true;
2038 (*i)->set_solo (false, src);
2039 solo_update_disabled = false;
2043 bool something_soloed = false;
2044 bool same_thing_soloed = false;
2045 bool signal = false;
2047 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2048 if ((*i)->soloed()) {
2049 something_soloed = true;
2050 if (dynamic_cast<AudioTrack*>((*i).get())) {
2052 same_thing_soloed = true;
2057 same_thing_soloed = true;
2065 if (something_soloed != currently_soloing) {
2067 currently_soloing = something_soloed;
2070 modify_solo_mute (is_track, same_thing_soloed);
2073 SoloActive (currently_soloing);
2080 Session::update_route_solo_state ()
2083 bool is_track = false;
2084 bool signal = false;
2086 /* caller must hold RouteLock */
2088 /* this is where we actually implement solo by changing
2089 the solo mute setting of each track.
2092 shared_ptr<RouteList> r = routes.reader ();
2094 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2095 if ((*i)->soloed()) {
2097 if (dynamic_cast<AudioTrack*>((*i).get())) {
2104 if (mute != currently_soloing) {
2106 currently_soloing = mute;
2109 if (!is_track && !mute) {
2111 /* nothing is soloed */
2113 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2114 (*i)->set_solo_mute (false);
2124 modify_solo_mute (is_track, mute);
2127 SoloActive (currently_soloing);
2132 Session::modify_solo_mute (bool is_track, bool mute)
2134 shared_ptr<RouteList> r = routes.reader ();
2136 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2140 /* only alter track solo mute */
2142 if (dynamic_cast<AudioTrack*>((*i).get())) {
2143 if ((*i)->soloed()) {
2144 (*i)->set_solo_mute (!mute);
2146 (*i)->set_solo_mute (mute);
2152 /* only alter bus solo mute */
2154 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2156 if ((*i)->soloed()) {
2158 (*i)->set_solo_mute (false);
2162 /* don't mute master or control outs
2163 in response to another bus solo
2166 if ((*i) != _master_out &&
2167 (*i) != _control_out) {
2168 (*i)->set_solo_mute (mute);
2179 Session::catch_up_on_solo ()
2181 /* this is called after set_state() to catch the full solo
2182 state, which can't be correctly determined on a per-route
2183 basis, but needs the global overview that only the session
2186 update_route_solo_state();
2190 Session::route_by_name (string name)
2192 shared_ptr<RouteList> r = routes.reader ();
2194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2195 if ((*i)->name() == name) {
2200 return shared_ptr<Route> ((Route*) 0);
2204 Session::route_by_id (PBD::ID id)
2206 shared_ptr<RouteList> r = routes.reader ();
2208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2209 if ((*i)->id() == id) {
2214 return shared_ptr<Route> ((Route*) 0);
2218 Session::route_by_remote_id (uint32_t id)
2220 shared_ptr<RouteList> r = routes.reader ();
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2223 if ((*i)->remote_control_id() == id) {
2228 return shared_ptr<Route> ((Route*) 0);
2232 Session::find_current_end ()
2234 if (_state_of_the_state & Loading) {
2238 nframes_t max = get_maximum_extent ();
2240 if (max > end_location->end()) {
2241 end_location->set_end (max);
2243 DurationChanged(); /* EMIT SIGNAL */
2248 Session::get_maximum_extent () const
2253 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2255 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2256 Playlist* pl = (*i)->playlist();
2257 if ((me = pl->get_maximum_extent()) > max) {
2265 boost::shared_ptr<Diskstream>
2266 Session::diskstream_by_name (string name)
2268 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2270 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2271 if ((*i)->name() == name) {
2276 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2279 boost::shared_ptr<Diskstream>
2280 Session::diskstream_by_id (const PBD::ID& id)
2282 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2284 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2285 if ((*i)->id() == id) {
2290 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2293 /* AudioRegion management */
2296 Session::new_region_name (string old)
2298 string::size_type last_period;
2300 string::size_type len = old.length() + 64;
2303 if ((last_period = old.find_last_of ('.')) == string::npos) {
2305 /* no period present - add one explicitly */
2308 last_period = old.length() - 1;
2313 number = atoi (old.substr (last_period+1).c_str());
2317 while (number < (UINT_MAX-1)) {
2319 AudioRegionList::const_iterator i;
2324 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2327 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2328 if (i->second->name() == sbuf) {
2333 if (i == audio_regions.end()) {
2338 if (number != (UINT_MAX-1)) {
2342 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2347 Session::region_name (string& result, string base, bool newlevel) const
2354 Glib::Mutex::Lock lm (region_lock);
2356 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2364 /* XXX this is going to be slow. optimize me later */
2369 string::size_type pos;
2371 pos = base.find_last_of ('.');
2373 /* pos may be npos, but then we just use entire base */
2375 subbase = base.substr (0, pos);
2379 bool name_taken = true;
2382 Glib::Mutex::Lock lm (region_lock);
2384 for (int n = 1; n < 5000; ++n) {
2387 snprintf (buf, sizeof (buf), ".%d", n);
2392 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2393 if (i->second->name() == result) {
2406 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2414 Session::add_region (boost::shared_ptr<Region> region)
2416 boost::shared_ptr<AudioRegion> ar;
2417 boost::shared_ptr<AudioRegion> oar;
2421 Glib::Mutex::Lock lm (region_lock);
2423 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2425 AudioRegionList::iterator x;
2427 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2429 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2431 if (ar->region_list_equivalent (oar)) {
2436 if (x == audio_regions.end()) {
2438 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2440 entry.first = region->id();
2443 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2455 fatal << _("programming error: ")
2456 << X_("unknown region type passed to Session::add_region()")
2463 /* mark dirty because something has changed even if we didn't
2464 add the region to the region list.
2470 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2471 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2472 AudioRegionAdded (ar); /* EMIT SIGNAL */
2477 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2479 boost::shared_ptr<Region> region (weak_region.lock ());
2485 if (what_changed & Region::HiddenChanged) {
2486 /* relay hidden changes */
2487 RegionHiddenChange (region);
2492 Session::remove_region (boost::weak_ptr<Region> weak_region)
2494 AudioRegionList::iterator i;
2495 boost::shared_ptr<Region> region (weak_region.lock ());
2501 boost::shared_ptr<AudioRegion> ar;
2502 bool removed = false;
2505 Glib::Mutex::Lock lm (region_lock);
2507 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2508 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2509 audio_regions.erase (i);
2515 fatal << _("programming error: ")
2516 << X_("unknown region type passed to Session::remove_region()")
2522 /* mark dirty because something has changed even if we didn't
2523 remove the region from the region list.
2529 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2533 boost::shared_ptr<AudioRegion>
2534 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2536 AudioRegionList::iterator i;
2537 boost::shared_ptr<AudioRegion> region;
2538 Glib::Mutex::Lock lm (region_lock);
2540 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2544 if (region->whole_file()) {
2546 if (child->source_equivalent (region)) {
2552 return boost::shared_ptr<AudioRegion> ();
2556 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2558 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2559 (*i)->get_region_list_equivalent_regions (region, result);
2563 Session::destroy_region (boost::shared_ptr<Region> region)
2565 boost::shared_ptr<AudioRegion> aregion;
2567 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2571 if (aregion->playlist()) {
2572 aregion->playlist()->destroy_region (region);
2575 vector<boost::shared_ptr<Source> > srcs;
2577 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2578 srcs.push_back (aregion->source (n));
2581 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2583 if ((*i).use_count() == 1) {
2584 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2587 (afs)->mark_for_remove ();
2590 (*i)->drop_references ();
2598 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2600 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2601 destroy_region (*i);
2607 Session::remove_last_capture ()
2609 list<boost::shared_ptr<Region> > r;
2611 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2613 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2614 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2617 r.insert (r.end(), l.begin(), l.end());
2622 destroy_regions (r);
2627 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2633 /* Source Management */
2636 Session::add_source (boost::shared_ptr<Source> source)
2638 boost::shared_ptr<AudioFileSource> afs;
2640 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2642 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2643 pair<AudioSourceList::iterator,bool> result;
2645 entry.first = source->id();
2649 Glib::Mutex::Lock lm (audio_source_lock);
2650 result = audio_sources.insert (entry);
2653 if (!result.second) {
2654 cerr << "\tNOT inserted ? " << result.second << endl;
2657 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2660 SourceAdded (source); /* EMIT SIGNAL */
2662 cerr << "\tNOT AUDIO FILE\n";
2667 Session::remove_source (boost::weak_ptr<Source> src)
2669 AudioSourceList::iterator i;
2670 boost::shared_ptr<Source> source = src.lock();
2677 Glib::Mutex::Lock lm (audio_source_lock);
2679 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2680 audio_sources.erase (i);
2684 if (!_state_of_the_state & InCleanup) {
2686 /* save state so we don't end up with a session file
2687 referring to non-existent sources.
2690 save_state (_current_snapshot_name);
2693 SourceRemoved(source); /* EMIT SIGNAL */
2696 boost::shared_ptr<Source>
2697 Session::source_by_id (const PBD::ID& id)
2699 Glib::Mutex::Lock lm (audio_source_lock);
2700 AudioSourceList::iterator i;
2701 boost::shared_ptr<Source> source;
2703 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2707 /* XXX search MIDI or other searches here */
2713 Session::peak_path_from_audio_path (string audio_path) const
2718 res += PBD::basename_nosuffix (audio_path);
2725 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2728 string old_basename = PBD::basename_nosuffix (oldname);
2729 string new_legalized = legalize_for_path (newname);
2731 /* note: we know (or assume) the old path is already valid */
2735 /* destructive file sources have a name of the form:
2737 /path/to/Tnnnn-NAME(%[LR])?.wav
2739 the task here is to replace NAME with the new name.
2742 /* find last slash */
2746 string::size_type slash;
2747 string::size_type dash;
2749 if ((slash = path.find_last_of ('/')) == string::npos) {
2753 dir = path.substr (0, slash+1);
2755 /* '-' is not a legal character for the NAME part of the path */
2757 if ((dash = path.find_last_of ('-')) == string::npos) {
2761 prefix = path.substr (slash+1, dash-(slash+1));
2766 path += new_legalized;
2767 path += ".wav"; /* XXX gag me with a spoon */
2771 /* non-destructive file sources have a name of the form:
2773 /path/to/NAME-nnnnn(%[LR])?.wav
2775 the task here is to replace NAME with the new name.
2780 string::size_type slash;
2781 string::size_type dash;
2782 string::size_type postfix;
2784 /* find last slash */
2786 if ((slash = path.find_last_of ('/')) == string::npos) {
2790 dir = path.substr (0, slash+1);
2792 /* '-' is not a legal character for the NAME part of the path */
2794 if ((dash = path.find_last_of ('-')) == string::npos) {
2798 suffix = path.substr (dash+1);
2800 // Suffix is now everything after the dash. Now we need to eliminate
2801 // the nnnnn part, which is done by either finding a '%' or a '.'
2803 postfix = suffix.find_last_of ("%");
2804 if (postfix == string::npos) {
2805 postfix = suffix.find_last_of ('.');
2808 if (postfix != string::npos) {
2809 suffix = suffix.substr (postfix);
2811 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2815 const uint32_t limit = 10000;
2816 char buf[PATH_MAX+1];
2818 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2820 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2822 if (access (buf, F_OK) != 0) {
2830 error << "FATAL ERROR! Could not find a " << endl;
2839 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2843 char buf[PATH_MAX+1];
2844 const uint32_t limit = 10000;
2848 legalized = legalize_for_path (name);
2850 /* find a "version" of the file name that doesn't exist in
2851 any of the possible directories.
2854 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2856 vector<space_and_path>::iterator i;
2857 uint32_t existing = 0;
2859 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2863 spath += sound_dir (false);
2867 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2868 } else if (nchan == 2) {
2870 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2872 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2874 } else if (nchan < 26) {
2875 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2877 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2885 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2886 } else if (nchan == 2) {
2888 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2890 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2892 } else if (nchan < 26) {
2893 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2895 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2899 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2905 if (existing == 0) {
2910 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2911 throw failed_constructor();
2915 /* we now have a unique name for the file, but figure out where to
2921 spath = discover_best_sound_dir ();
2923 string::size_type pos = foo.find_last_of ('/');
2925 if (pos == string::npos) {
2928 spath += foo.substr (pos + 1);
2934 boost::shared_ptr<AudioFileSource>
2935 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2937 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2938 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2941 /* Playlist management */
2944 Session::playlist_by_name (string name)
2946 Glib::Mutex::Lock lm (playlist_lock);
2947 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2948 if ((*i)->name() == name) {
2952 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2953 if ((*i)->name() == name) {
2961 Session::add_playlist (Playlist* playlist)
2963 if (playlist->hidden()) {
2968 Glib::Mutex::Lock lm (playlist_lock);
2969 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2970 playlists.insert (playlists.begin(), playlist);
2972 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2973 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2979 PlaylistAdded (playlist); /* EMIT SIGNAL */
2983 Session::track_playlist (Playlist* pl, bool inuse)
2985 PlaylistList::iterator x;
2988 Glib::Mutex::Lock lm (playlist_lock);
2991 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2993 unused_playlists.insert (pl);
2995 if ((x = playlists.find (pl)) != playlists.end()) {
2996 playlists.erase (x);
3001 //cerr << "shifting playlist to used: " << pl->name() << endl;
3003 playlists.insert (pl);
3005 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3006 unused_playlists.erase (x);
3013 Session::remove_playlist (Playlist* playlist)
3015 if (_state_of_the_state & Deletion) {
3020 Glib::Mutex::Lock lm (playlist_lock);
3021 // cerr << "removing playlist: " << playlist->name() << endl;
3023 PlaylistList::iterator i;
3025 i = find (playlists.begin(), playlists.end(), playlist);
3027 if (i != playlists.end()) {
3028 playlists.erase (i);
3031 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3032 if (i != unused_playlists.end()) {
3033 unused_playlists.erase (i);
3040 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3044 Session::set_audition (boost::shared_ptr<Region> r)
3046 pending_audition_region = r;
3047 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3048 schedule_butler_transport_work ();
3052 Session::audition_playlist ()
3054 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3055 ev->region.reset ();
3060 Session::non_realtime_set_audition ()
3062 if (!pending_audition_region) {
3063 auditioner->audition_current_playlist ();
3065 auditioner->audition_region (pending_audition_region);
3066 pending_audition_region.reset ();
3068 AuditionActive (true); /* EMIT SIGNAL */
3072 Session::audition_region (boost::shared_ptr<Region> r)
3074 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3080 Session::cancel_audition ()
3082 if (auditioner->active()) {
3083 auditioner->cancel_audition ();
3084 AuditionActive (false); /* EMIT SIGNAL */
3089 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3091 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3095 Session::remove_empty_sounds ()
3097 PathScanner scanner;
3099 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3101 Glib::Mutex::Lock lm (audio_source_lock);
3103 regex_t compiled_tape_track_pattern;
3106 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3110 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3112 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3116 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3118 /* never remove files that appear to be a tape track */
3120 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3125 if (AudioFileSource::is_empty (*this, *(*i))) {
3127 unlink ((*i)->c_str());
3129 string peak_path = peak_path_from_audio_path (**i);
3130 unlink (peak_path.c_str());
3136 delete possible_audiofiles;
3140 Session::is_auditioning () const
3142 /* can be called before we have an auditioner object */
3144 return auditioner->active();
3151 Session::set_all_solo (bool yn)
3153 shared_ptr<RouteList> r = routes.reader ();
3155 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3156 if (!(*i)->hidden()) {
3157 (*i)->set_solo (yn, this);
3165 Session::set_all_mute (bool yn)
3167 shared_ptr<RouteList> r = routes.reader ();
3169 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3170 if (!(*i)->hidden()) {
3171 (*i)->set_mute (yn, this);
3179 Session::n_diskstreams () const
3183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3185 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3186 if (!(*i)->hidden()) {
3194 Session::graph_reordered ()
3196 /* don't do this stuff if we are setting up connections
3197 from a set_state() call.
3200 if (_state_of_the_state & InitialConnecting) {
3206 /* force all diskstreams to update their capture offset values to
3207 reflect any changes in latencies within the graph.
3210 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3212 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3213 (*i)->set_capture_offset ();
3218 Session::record_disenable_all ()
3220 record_enable_change_all (false);
3224 Session::record_enable_all ()
3226 record_enable_change_all (true);
3230 Session::record_enable_change_all (bool yn)
3232 shared_ptr<RouteList> r = routes.reader ();
3234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3237 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3238 at->set_record_enable (yn, this);
3242 /* since we don't keep rec-enable state, don't mark session dirty */
3246 Session::add_redirect (Redirect* redirect)
3250 PortInsert* port_insert;
3251 PluginInsert* plugin_insert;
3253 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3254 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3255 _port_inserts.insert (_port_inserts.begin(), port_insert);
3256 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3257 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3259 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3262 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3263 _sends.insert (_sends.begin(), send);
3265 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3269 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3275 Session::remove_redirect (Redirect* redirect)
3279 PortInsert* port_insert;
3280 PluginInsert* plugin_insert;
3282 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3283 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3284 _port_inserts.remove (port_insert);
3285 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3286 _plugin_inserts.remove (plugin_insert);
3288 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3291 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3292 _sends.remove (send);
3294 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3302 Session::available_capture_duration ()
3304 float sample_bytes_on_disk;
3306 switch (Config->get_native_file_data_format()) {
3308 sample_bytes_on_disk = 4;
3312 sample_bytes_on_disk = 3;
3316 double scale = 4096.0 / sample_bytes_on_disk;
3318 if (_total_free_4k_blocks * scale > (double) max_frames) {
3322 return (nframes_t) floor (_total_free_4k_blocks * scale);
3326 Session::add_connection (ARDOUR::Connection* connection)
3329 Glib::Mutex::Lock guard (connection_lock);
3330 _connections.push_back (connection);
3333 ConnectionAdded (connection); /* EMIT SIGNAL */
3339 Session::remove_connection (ARDOUR::Connection* connection)
3341 bool removed = false;
3344 Glib::Mutex::Lock guard (connection_lock);
3345 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3347 if (i != _connections.end()) {
3348 _connections.erase (i);
3354 ConnectionRemoved (connection); /* EMIT SIGNAL */
3360 ARDOUR::Connection *
3361 Session::connection_by_name (string name) const
3363 Glib::Mutex::Lock lm (connection_lock);
3365 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3366 if ((*i)->name() == name) {
3375 Session::tempo_map_changed (Change ignored)
3382 Session::ensure_passthru_buffers (uint32_t howmany)
3384 while (howmany > _passthru_buffers.size()) {
3386 #ifdef NO_POSIX_MEMALIGN
3387 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3389 posix_memalign((void **)&p,16,current_block_size * 4);
3391 _passthru_buffers.push_back (p);
3395 #ifdef NO_POSIX_MEMALIGN
3396 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3398 posix_memalign((void **)&p,16,current_block_size * 4);
3400 memset (p, 0, sizeof (Sample) * current_block_size);
3401 _silent_buffers.push_back (p);
3405 #ifdef NO_POSIX_MEMALIGN
3406 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3408 posix_memalign((void **)&p,16,current_block_size * 4);
3410 memset (p, 0, sizeof (Sample) * current_block_size);
3411 _send_buffers.push_back (p);
3414 allocate_pan_automation_buffers (current_block_size, howmany, false);
3418 Session::next_send_name ()
3421 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3426 Session::next_insert_name ()
3429 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3433 /* Named Selection management */
3436 Session::named_selection_by_name (string name)
3438 Glib::Mutex::Lock lm (named_selection_lock);
3439 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3440 if ((*i)->name == name) {
3448 Session::add_named_selection (NamedSelection* named_selection)
3451 Glib::Mutex::Lock lm (named_selection_lock);
3452 named_selections.insert (named_selections.begin(), named_selection);
3457 NamedSelectionAdded (); /* EMIT SIGNAL */
3461 Session::remove_named_selection (NamedSelection* named_selection)
3463 bool removed = false;
3466 Glib::Mutex::Lock lm (named_selection_lock);
3468 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3470 if (i != named_selections.end()) {
3472 named_selections.erase (i);
3479 NamedSelectionRemoved (); /* EMIT SIGNAL */
3484 Session::reset_native_file_format ()
3486 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3488 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3489 (*i)->reset_write_sources (false);
3494 Session::route_name_unique (string n) const
3496 shared_ptr<RouteList> r = routes.reader ();
3498 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3499 if ((*i)->name() == n) {
3508 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3510 return fs->move_to_trash (dead_sound_dir_name);
3514 Session::n_playlists () const
3516 Glib::Mutex::Lock lm (playlist_lock);
3517 return playlists.size();
3521 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3523 if (!force && howmany <= _npan_buffers) {
3527 if (_pan_automation_buffer) {
3529 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3530 delete [] _pan_automation_buffer[i];
3533 delete [] _pan_automation_buffer;
3536 _pan_automation_buffer = new pan_t*[howmany];
3538 for (uint32_t i = 0; i < howmany; ++i) {
3539 _pan_automation_buffer[i] = new pan_t[nframes];
3542 _npan_buffers = howmany;
3546 Session::freeze (InterThreadInfo& itt)
3548 shared_ptr<RouteList> r = routes.reader ();
3550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3554 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3555 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3566 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3567 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3571 boost::shared_ptr<AudioFileSource> fsource;
3573 char buf[PATH_MAX+1];
3577 nframes_t this_chunk;
3579 vector<Sample*> buffers;
3581 // any bigger than this seems to cause stack overflows in called functions
3582 const nframes_t chunk_size = (128 * 1024)/4;
3584 g_atomic_int_set (&processing_prohibited, 1);
3586 /* call tree *MUST* hold route_lock */
3588 if ((playlist = track.diskstream()->playlist()) == 0) {
3592 /* external redirects will be a problem */
3594 if (track.has_external_redirects()) {
3598 nchans = track.audio_diskstream()->n_channels();
3600 dir = discover_best_sound_dir ();
3602 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3604 for (x = 0; x < 99999; ++x) {
3605 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3606 if (access (buf, F_OK) != 0) {
3612 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3617 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3620 catch (failed_constructor& err) {
3621 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3625 srcs.push_back (fsource);
3628 /* XXX need to flush all redirects */
3633 /* create a set of reasonably-sized buffers */
3635 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3637 #ifdef NO_POSIX_MEMALIGN
3638 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3640 posix_memalign((void **)&b,16,chunk_size * 4);
3642 buffers.push_back (b);
3645 while (to_do && !itt.cancel) {
3647 this_chunk = min (to_do, chunk_size);
3649 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3654 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3655 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3658 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3664 start += this_chunk;
3665 to_do -= this_chunk;
3667 itt.progress = (float) (1.0 - ((double) to_do / len));
3676 xnow = localtime (&now);
3678 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3679 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3682 afs->update_header (position, *xnow, now);
3686 /* build peakfile for new source */
3688 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3689 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3691 afs->build_peaks ();
3695 /* construct a region to represent the bounced material */
3697 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3698 region_name_from_path (srcs.front()->name()));
3705 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3706 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3709 afs->mark_for_remove ();
3712 (*src)->drop_references ();
3716 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3720 g_atomic_int_set (&processing_prohibited, 0);
3728 Session::get_silent_buffers (uint32_t howmany)
3730 for (uint32_t i = 0; i < howmany; ++i) {
3731 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3733 return _silent_buffers;
3737 Session::ntracks () const
3740 shared_ptr<RouteList> r = routes.reader ();
3742 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3743 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3752 Session::nbusses () const
3755 shared_ptr<RouteList> r = routes.reader ();
3757 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3758 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3767 Session::add_automation_list(AutomationList *al)
3769 automation_lists[al->id()] = al;