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>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
81 const char* Session::_template_suffix = X_(".template");
82 const char* Session::_statefile_suffix = X_(".ardour");
83 const char* Session::_pending_suffix = X_(".pending");
84 const char* Session::old_sound_dir_name = X_("sounds");
85 const char* Session::sound_dir_name = X_("audiofiles");
86 const char* Session::peak_dir_name = X_("peaks");
87 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 const char* Session::interchange_dir_name = X_("interchange");
90 Session::compute_peak_t Session::compute_peak = 0;
91 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
92 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
93 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::StartTimeChanged;
100 sigc::signal<void> Session::EndTimeChanged;
103 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
106 char buf[PATH_MAX+1];
110 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
111 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
117 /* check to see if it exists, and what it is */
119 if (stat (str.c_str(), &statbuf)) {
120 if (errno == ENOENT) {
123 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
131 /* it exists, so it must either be the name
132 of the directory, or the name of the statefile
136 if (S_ISDIR (statbuf.st_mode)) {
138 string::size_type slash = str.find_last_of ('/');
140 if (slash == string::npos) {
142 /* a subdirectory of cwd, so statefile should be ... */
148 tmp += _statefile_suffix;
152 if (stat (tmp.c_str(), &statbuf)) {
153 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
163 /* some directory someplace in the filesystem.
164 the snapshot name is the directory name
169 snapshot = str.substr (slash+1);
173 } else if (S_ISREG (statbuf.st_mode)) {
175 string::size_type slash = str.find_last_of ('/');
176 string::size_type suffix;
178 /* remove the suffix */
180 if (slash != string::npos) {
181 snapshot = str.substr (slash+1);
186 suffix = snapshot.find (_statefile_suffix);
188 if (suffix == string::npos) {
189 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
195 snapshot = snapshot.substr (0, suffix);
197 if (slash == string::npos) {
199 /* we must be in the directory where the
200 statefile lives. get it using cwd().
203 char cwd[PATH_MAX+1];
205 if (getcwd (cwd, sizeof (cwd)) == 0) {
206 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
215 /* full path to the statefile */
217 path = str.substr (0, slash);
222 /* what type of file is it? */
223 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
229 /* its the name of a new directory. get the name
233 string::size_type slash = str.find_last_of ('/');
235 if (slash == string::npos) {
237 /* no slash, just use the name, but clean it up */
239 path = legalize_for_path (str);
245 snapshot = str.substr (slash+1);
252 Session::Session (AudioEngine &eng,
254 string snapshot_name,
255 string* mix_template)
258 _mmc_port (default_mmc_port),
259 _mtc_port (default_mtc_port),
260 _midi_port (default_midi_port),
261 pending_events (2048),
262 midi_requests (128), // the size of this should match the midi request pool size
263 diskstreams (new DiskstreamList),
264 routes (new RouteList),
265 auditioner ((Auditioner*) 0),
271 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
273 n_physical_outputs = _engine.n_physical_outputs();
274 n_physical_inputs = _engine.n_physical_inputs();
276 first_stage_init (fullpath, snapshot_name);
278 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
280 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
281 cerr << "create failed\n";
282 throw failed_constructor ();
286 if (second_stage_init (new_session)) {
287 cerr << "2nd state failed\n";
288 throw failed_constructor ();
291 store_recent_sessions(_name, _path);
293 bool was_dirty = dirty();
295 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
297 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
300 DirtyChanged (); /* EMIT SIGNAL */
304 Session::Session (AudioEngine &eng,
306 string snapshot_name,
307 AutoConnectOption input_ac,
308 AutoConnectOption output_ac,
309 uint32_t control_out_channels,
310 uint32_t master_out_channels,
311 uint32_t requested_physical_in,
312 uint32_t requested_physical_out,
313 nframes_t initial_length)
316 _mmc_port (default_mmc_port),
317 _mtc_port (default_mtc_port),
318 _midi_port (default_midi_port),
319 pending_events (2048),
321 diskstreams (new DiskstreamList),
322 routes (new RouteList),
328 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
330 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
331 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
333 first_stage_init (fullpath, snapshot_name);
335 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
337 if (create (new_session, 0, initial_length)) {
338 throw failed_constructor ();
342 if (control_out_channels) {
343 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
350 if (master_out_channels) {
351 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
357 /* prohibit auto-connect to master, because there isn't one */
358 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
361 Config->set_input_auto_connect (input_ac);
362 Config->set_output_auto_connect (output_ac);
364 if (second_stage_init (new_session)) {
365 throw failed_constructor ();
368 store_recent_sessions(_name, _path);
370 bool was_dirty = dirty ();
372 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
375 DirtyChanged (); /* EMIT SIGNAL */
381 /* if we got to here, leaving pending capture state around
385 remove_pending_capture_state ();
387 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
388 _engine.remove_session ();
390 GoingAway (); /* EMIT SIGNAL */
396 /* clear history so that no references to objects are held any more */
400 /* clear state tree so that no references to objects are held any more */
406 terminate_butler_thread ();
407 terminate_midi_thread ();
409 if (click_data && click_data != default_click) {
410 delete [] click_data;
413 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
414 delete [] click_emphasis_data;
419 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
423 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
427 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
431 AudioDiskstream::free_working_buffers();
433 #undef TRACK_DESTRUCTION
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete named selections\n";
436 #endif /* TRACK_DESTRUCTION */
437 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
438 NamedSelectionList::iterator tmp;
447 #ifdef TRACK_DESTRUCTION
448 cerr << "delete playlists\n";
449 #endif /* TRACK_DESTRUCTION */
450 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
451 PlaylistList::iterator tmp;
461 #ifdef TRACK_DESTRUCTION
462 cerr << "delete audio regions\n";
463 #endif /* TRACK_DESTRUCTION */
465 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
466 i->second->drop_references ();
469 audio_regions.clear ();
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete routes\n";
473 #endif /* TRACK_DESTRUCTION */
475 RCUWriter<RouteList> writer (routes);
476 boost::shared_ptr<RouteList> r = writer.get_copy ();
477 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
478 (*i)->drop_references ();
481 /* writer goes out of scope and updates master */
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete diskstreams\n";
488 #endif /* TRACK_DESTRUCTION */
490 RCUWriter<DiskstreamList> dwriter (diskstreams);
491 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
492 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
493 (*i)->drop_references ();
497 diskstreams.flush ();
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete audio sources\n";
501 #endif /* TRACK_DESTRUCTION */
502 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
503 AudioSourceList::iterator tmp;
508 i->second->drop_references ();
513 audio_sources.clear ();
515 #ifdef TRACK_DESTRUCTION
516 cerr << "delete mix groups\n";
517 #endif /* TRACK_DESTRUCTION */
518 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
519 list<RouteGroup*>::iterator tmp;
529 #ifdef TRACK_DESTRUCTION
530 cerr << "delete edit groups\n";
531 #endif /* TRACK_DESTRUCTION */
532 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
533 list<RouteGroup*>::iterator tmp;
543 #ifdef TRACK_DESTRUCTION
544 cerr << "delete connections\n";
545 #endif /* TRACK_DESTRUCTION */
546 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
547 ConnectionList::iterator tmp;
557 if (butler_mixdown_buffer) {
558 delete [] butler_mixdown_buffer;
561 if (butler_gain_buffer) {
562 delete [] butler_gain_buffer;
565 Crossfade::set_buffer_size (0);
573 Session::set_worst_io_latencies ()
575 _worst_output_latency = 0;
576 _worst_input_latency = 0;
578 if (!_engine.connected()) {
582 boost::shared_ptr<RouteList> r = routes.reader ();
584 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
585 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
586 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
591 Session::when_engine_running ()
593 string first_physical_output;
595 /* we don't want to run execute this again */
597 first_time_running.disconnect ();
599 set_block_size (_engine.frames_per_cycle());
600 set_frame_rate (_engine.frame_rate());
602 Config->map_parameters (mem_fun (*this, &Session::config_changed));
604 /* every time we reconnect, recompute worst case output latencies */
606 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
608 if (synced_to_jack()) {
609 _engine.transport_stop ();
612 if (Config->get_jack_time_master()) {
613 _engine.transport_locate (_transport_frame);
621 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
623 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
625 /* existing state for Click */
627 if (_click_io->set_state (*child->children().front()) == 0) {
629 _clicking = Config->get_clicking ();
633 error << _("could not setup Click I/O") << endmsg;
639 /* default state for Click */
641 first_physical_output = _engine.get_nth_physical_output (0);
643 if (first_physical_output.length()) {
644 if (_click_io->add_output_port (first_physical_output, this)) {
645 // relax, even though its an error
647 _clicking = Config->get_clicking ();
653 catch (failed_constructor& err) {
654 error << _("cannot setup Click I/O") << endmsg;
657 set_worst_io_latencies ();
660 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
663 if (auditioner == 0) {
665 /* we delay creating the auditioner till now because
666 it makes its own connections to ports named
667 in the ARDOUR_RC config file. the engine has
668 to be running for this to work.
672 auditioner.reset (new Auditioner (*this));
675 catch (failed_constructor& err) {
676 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
680 /* Create a set of Connection objects that map
681 to the physical outputs currently available
686 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
688 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
690 Connection* c = new OutputConnection (buf, true);
693 c->add_connection (0, _engine.get_nth_physical_output (np));
698 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
700 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
702 Connection* c = new InputConnection (buf, true);
705 c->add_connection (0, _engine.get_nth_physical_input (np));
712 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
714 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
716 Connection* c = new OutputConnection (buf, true);
720 c->add_connection (0, _engine.get_nth_physical_output (np));
721 c->add_connection (1, _engine.get_nth_physical_output (np+1));
726 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
728 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
730 Connection* c = new InputConnection (buf, true);
734 c->add_connection (0, _engine.get_nth_physical_input (np));
735 c->add_connection (1, _engine.get_nth_physical_input (np+1));
744 /* create master/control ports */
749 /* force the master to ignore any later call to this */
751 if (_master_out->pending_state_node) {
752 _master_out->ports_became_legal();
755 /* no panner resets till we are through */
757 _master_out->defer_pan_reset ();
759 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
760 if (_master_out->add_input_port ("", this)) {
761 error << _("cannot setup master inputs")
767 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
768 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
769 error << _("cannot setup master outputs")
776 _master_out->allow_pan_reset ();
780 Connection* c = new OutputConnection (_("Master Out"), true);
782 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
784 c->add_connection ((int) n, _master_out->input(n)->name());
791 /* catch up on send+insert cnts */
795 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
798 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
799 if (id > insert_cnt) {
807 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
810 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
817 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
819 /* hook us up to the engine */
821 _engine.set_session (this);
826 osc->set_session (*this);
829 _state_of_the_state = Clean;
831 DirtyChanged (); /* EMIT SIGNAL */
835 Session::hookup_io ()
837 /* stop graph reordering notifications from
838 causing resorts, etc.
841 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
843 /* Tell all IO objects to create their ports */
850 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
851 if (_control_out->add_input_port ("", this)) {
852 error << _("cannot setup control inputs")
858 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
859 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
860 error << _("cannot set up master outputs")
868 /* Tell all IO objects to connect themselves together */
870 IO::enable_connecting ();
872 /* Now reset all panners */
874 IO::reset_panners ();
876 /* Anyone who cares about input state, wake up and do something */
878 IOConnectionsComplete (); /* EMIT SIGNAL */
880 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
882 /* now handle the whole enchilada as if it was one
888 /* update mixer solo state */
894 Session::playlist_length_changed (Playlist* pl)
896 /* we can't just increase end_location->end() if pl->get_maximum_extent()
897 if larger. if the playlist used to be the longest playlist,
898 and its now shorter, we have to decrease end_location->end(). hence,
899 we have to iterate over all diskstreams and check the
900 playlists currently in use.
906 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
910 if ((playlist = dstream->playlist()) != 0) {
911 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
914 /* see comment in playlist_length_changed () */
919 Session::record_enabling_legal () const
921 /* this used to be in here, but survey says.... we don't need to restrict it */
922 // if (record_status() == Recording) {
926 if (Config->get_all_safe()) {
933 Session::reset_input_monitor_state ()
935 if (transport_rolling()) {
937 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
939 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
940 if ((*i)->record_enabled ()) {
941 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
942 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
946 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
948 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
949 if ((*i)->record_enabled ()) {
950 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
951 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
958 Session::auto_punch_start_changed (Location* location)
960 replace_event (Event::PunchIn, location->start());
962 if (get_record_enabled() && Config->get_punch_in()) {
963 /* capture start has been changed, so save new pending state */
964 save_state ("", true);
969 Session::auto_punch_end_changed (Location* location)
971 nframes_t when_to_stop = location->end();
972 // when_to_stop += _worst_output_latency + _worst_input_latency;
973 replace_event (Event::PunchOut, when_to_stop);
977 Session::auto_punch_changed (Location* location)
979 nframes_t when_to_stop = location->end();
981 replace_event (Event::PunchIn, location->start());
982 //when_to_stop += _worst_output_latency + _worst_input_latency;
983 replace_event (Event::PunchOut, when_to_stop);
987 Session::auto_loop_changed (Location* location)
989 replace_event (Event::AutoLoop, location->end(), location->start());
991 if (transport_rolling() && play_loop) {
993 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
995 if (_transport_frame > location->end()) {
996 // relocate to beginning of loop
997 clear_events (Event::LocateRoll);
999 request_locate (location->start(), true);
1002 else if (Config->get_seamless_loop() && !loop_changing) {
1004 // schedule a locate-roll to refill the diskstreams at the
1005 // previous loop end
1006 loop_changing = true;
1008 if (location->end() > last_loopend) {
1009 clear_events (Event::LocateRoll);
1010 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1017 last_loopend = location->end();
1022 Session::set_auto_punch_location (Location* location)
1026 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1027 auto_punch_start_changed_connection.disconnect();
1028 auto_punch_end_changed_connection.disconnect();
1029 auto_punch_changed_connection.disconnect();
1030 existing->set_auto_punch (false, this);
1031 remove_event (existing->start(), Event::PunchIn);
1032 clear_events (Event::PunchOut);
1033 auto_punch_location_changed (0);
1038 if (location == 0) {
1042 if (location->end() <= location->start()) {
1043 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1047 auto_punch_start_changed_connection.disconnect();
1048 auto_punch_end_changed_connection.disconnect();
1049 auto_punch_changed_connection.disconnect();
1051 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1052 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1053 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1055 location->set_auto_punch (true, this);
1056 auto_punch_location_changed (location);
1060 Session::set_auto_loop_location (Location* location)
1064 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1065 auto_loop_start_changed_connection.disconnect();
1066 auto_loop_end_changed_connection.disconnect();
1067 auto_loop_changed_connection.disconnect();
1068 existing->set_auto_loop (false, this);
1069 remove_event (existing->end(), Event::AutoLoop);
1070 auto_loop_location_changed (0);
1075 if (location == 0) {
1079 if (location->end() <= location->start()) {
1080 error << _("Session: you can't use a mark for auto loop") << endmsg;
1084 last_loopend = location->end();
1086 auto_loop_start_changed_connection.disconnect();
1087 auto_loop_end_changed_connection.disconnect();
1088 auto_loop_changed_connection.disconnect();
1090 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1091 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1092 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1094 location->set_auto_loop (true, this);
1095 auto_loop_location_changed (location);
1099 Session::locations_added (Location* ignored)
1105 Session::locations_changed ()
1107 _locations.apply (*this, &Session::handle_locations_changed);
1111 Session::handle_locations_changed (Locations::LocationList& locations)
1113 Locations::LocationList::iterator i;
1115 bool set_loop = false;
1116 bool set_punch = false;
1118 for (i = locations.begin(); i != locations.end(); ++i) {
1122 if (location->is_auto_punch()) {
1123 set_auto_punch_location (location);
1126 if (location->is_auto_loop()) {
1127 set_auto_loop_location (location);
1134 set_auto_loop_location (0);
1137 set_auto_punch_location (0);
1144 Session::enable_record ()
1146 /* XXX really atomic compare+swap here */
1147 if (g_atomic_int_get (&_record_status) != Recording) {
1148 g_atomic_int_set (&_record_status, Recording);
1149 _last_record_location = _transport_frame;
1150 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1152 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1153 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1154 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1155 if ((*i)->record_enabled ()) {
1156 (*i)->monitor_input (true);
1161 RecordStateChanged ();
1166 Session::disable_record (bool rt_context, bool force)
1170 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1172 if (!Config->get_latched_record_enable () || force) {
1173 g_atomic_int_set (&_record_status, Disabled);
1175 if (rs == Recording) {
1176 g_atomic_int_set (&_record_status, Enabled);
1180 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1182 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1185 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1186 if ((*i)->record_enabled ()) {
1187 (*i)->monitor_input (false);
1192 RecordStateChanged (); /* emit signal */
1195 remove_pending_capture_state ();
1201 Session::step_back_from_record ()
1203 g_atomic_int_set (&_record_status, Enabled);
1205 if (Config->get_monitoring_model() == HardwareMonitoring) {
1206 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1208 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1209 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1210 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1211 (*i)->monitor_input (false);
1218 Session::maybe_enable_record ()
1220 g_atomic_int_set (&_record_status, Enabled);
1222 /* XXX this save should really happen in another thread. its needed so that
1223 pending capture state can be recovered if we crash.
1226 save_state ("", true);
1228 if (_transport_speed) {
1229 if (!Config->get_punch_in()) {
1233 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1234 RecordStateChanged (); /* EMIT SIGNAL */
1241 Session::audible_frame () const
1247 /* the first of these two possible settings for "offset"
1248 mean that the audible frame is stationary until
1249 audio emerges from the latency compensation
1252 the second means that the audible frame is stationary
1253 until audio would emerge from a physical port
1254 in the absence of any plugin latency compensation
1257 offset = _worst_output_latency;
1259 if (offset > current_block_size) {
1260 offset -= current_block_size;
1262 /* XXX is this correct? if we have no external
1263 physical connections and everything is internal
1264 then surely this is zero? still, how
1265 likely is that anyway?
1267 offset = current_block_size;
1270 if (synced_to_jack()) {
1271 tf = _engine.transport_frame();
1273 tf = _transport_frame;
1276 if (_transport_speed == 0) {
1286 if (!non_realtime_work_pending()) {
1290 /* take latency into account */
1299 Session::set_frame_rate (nframes_t frames_per_second)
1301 /** \fn void Session::set_frame_size(nframes_t)
1302 the AudioEngine object that calls this guarantees
1303 that it will not be called while we are also in
1304 ::process(). Its fine to do things that block
1308 _base_frame_rate = frames_per_second;
1312 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1314 // XXX we need some equivalent to this, somehow
1315 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1319 /* XXX need to reset/reinstantiate all LADSPA plugins */
1323 Session::set_block_size (nframes_t nframes)
1325 /* the AudioEngine guarantees
1326 that it will not be called while we are also in
1327 ::process(). It is therefore fine to do things that block
1332 vector<Sample*>::iterator i;
1335 current_block_size = nframes;
1337 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1341 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1345 _passthru_buffers.clear ();
1346 _silent_buffers.clear ();
1348 ensure_passthru_buffers (np);
1350 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1354 #ifdef NO_POSIX_MEMALIGN
1355 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1357 posix_memalign((void **)&buf,16,current_block_size * 4);
1361 memset (*i, 0, sizeof (Sample) * current_block_size);
1365 if (_gain_automation_buffer) {
1366 delete [] _gain_automation_buffer;
1368 _gain_automation_buffer = new gain_t[nframes];
1370 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1372 boost::shared_ptr<RouteList> r = routes.reader ();
1374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1375 (*i)->set_block_size (nframes);
1378 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1379 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1380 (*i)->set_block_size (nframes);
1383 set_worst_io_latencies ();
1388 Session::set_default_fade (float steepness, float fade_msecs)
1391 nframes_t fade_frames;
1393 /* Don't allow fade of less 1 frame */
1395 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1402 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1406 default_fade_msecs = fade_msecs;
1407 default_fade_steepness = steepness;
1410 // jlc, WTF is this!
1411 Glib::RWLock::ReaderLock lm (route_lock);
1412 AudioRegion::set_default_fade (steepness, fade_frames);
1417 /* XXX have to do this at some point */
1418 /* foreach region using default fade, reset, then
1419 refill_all_diskstream_buffers ();
1424 struct RouteSorter {
1425 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1426 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1428 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1431 if (r1->fed_by.empty()) {
1432 if (r2->fed_by.empty()) {
1433 /* no ardour-based connections inbound to either route. just use signal order */
1434 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1436 /* r2 has connections, r1 does not; run r1 early */
1440 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1447 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1449 shared_ptr<Route> r2;
1451 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1452 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1456 /* make a copy of the existing list of routes that feed r1 */
1458 set<shared_ptr<Route> > existing = r1->fed_by;
1460 /* for each route that feeds r1, recurse, marking it as feeding
1464 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1467 /* r2 is a route that feeds r1 which somehow feeds base. mark
1468 base as being fed by r2
1471 rbase->fed_by.insert (r2);
1475 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1479 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1483 /* now recurse, so that we can mark base as being fed by
1484 all routes that feed r2
1487 trace_terminal (r2, rbase);
1494 Session::resort_routes ()
1496 /* don't do anything here with signals emitted
1497 by Routes while we are being destroyed.
1500 if (_state_of_the_state & Deletion) {
1507 RCUWriter<RouteList> writer (routes);
1508 shared_ptr<RouteList> r = writer.get_copy ();
1509 resort_routes_using (r);
1510 /* writer goes out of scope and forces update */
1515 Session::resort_routes_using (shared_ptr<RouteList> r)
1517 RouteList::iterator i, j;
1519 for (i = r->begin(); i != r->end(); ++i) {
1521 (*i)->fed_by.clear ();
1523 for (j = r->begin(); j != r->end(); ++j) {
1525 /* although routes can feed themselves, it will
1526 cause an endless recursive descent if we
1527 detect it. so don't bother checking for
1535 if ((*j)->feeds (*i)) {
1536 (*i)->fed_by.insert (*j);
1541 for (i = r->begin(); i != r->end(); ++i) {
1542 trace_terminal (*i, *i);
1549 cerr << "finished route resort\n";
1551 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1552 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1559 list<boost::shared_ptr<AudioTrack> >
1560 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1562 char track_name[32];
1563 uint32_t track_id = 0;
1565 uint32_t channels_used = 0;
1567 RouteList new_routes;
1568 list<boost::shared_ptr<AudioTrack> > ret;
1570 /* count existing audio tracks */
1573 shared_ptr<RouteList> r = routes.reader ();
1575 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1576 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1577 if (!(*i)->hidden()) {
1579 channels_used += (*i)->n_inputs();
1585 vector<string> physinputs;
1586 vector<string> physoutputs;
1587 uint32_t nphysical_in;
1588 uint32_t nphysical_out;
1590 _engine.get_physical_outputs (physoutputs);
1591 _engine.get_physical_inputs (physinputs);
1595 /* check for duplicate route names, since we might have pre-existing
1596 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1597 save, close,restart,add new route - first named route is now
1605 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1607 if (route_by_name (track_name) == 0) {
1611 } while (track_id < (UINT_MAX-1));
1613 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1614 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1619 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1620 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1626 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1628 if (track->ensure_io (input_channels, output_channels, false, this)) {
1629 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1630 input_channels, output_channels)
1635 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1639 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1640 port = physinputs[(channels_used+x)%nphysical_in];
1643 if (port.length() && track->connect_input (track->input (x), port, this)) {
1649 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1653 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1654 port = physoutputs[(channels_used+x)%nphysical_out];
1655 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1657 port = _master_out->input (x%_master_out->n_inputs())->name();
1661 if (port.length() && track->connect_output (track->output (x), port, this)) {
1666 channels_used += track->n_inputs ();
1669 vector<string> cports;
1670 uint32_t ni = _control_out->n_inputs();
1672 for (n = 0; n < ni; ++n) {
1673 cports.push_back (_control_out->input(n)->name());
1676 track->set_control_outs (cports);
1679 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1680 track->set_remote_control_id (ntracks());
1682 new_routes.push_back (track);
1683 ret.push_back (track);
1686 catch (failed_constructor &err) {
1687 error << _("Session: could not create new audio track.") << endmsg;
1688 // XXX should we delete the tracks already created?
1696 if (!new_routes.empty()) {
1697 add_routes (new_routes, false);
1698 save_state (_current_snapshot_name);
1705 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1708 uint32_t bus_id = 1;
1713 /* count existing audio busses */
1716 shared_ptr<RouteList> r = routes.reader ();
1718 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1719 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1720 if (!(*i)->hidden()) {
1727 vector<string> physinputs;
1728 vector<string> physoutputs;
1730 _engine.get_physical_outputs (physoutputs);
1731 _engine.get_physical_inputs (physinputs);
1738 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1740 if (route_by_name (bus_name) == 0) {
1744 } while (bus_id < (UINT_MAX-1));
1747 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1749 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1750 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1751 input_channels, output_channels)
1755 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1759 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1760 port = physinputs[((n+x)%n_physical_inputs)];
1763 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1768 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1772 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1773 port = physoutputs[((n+x)%n_physical_outputs)];
1774 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1776 port = _master_out->input (x%_master_out->n_inputs())->name();
1780 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1786 vector<string> cports;
1787 uint32_t ni = _control_out->n_inputs();
1789 for (uint32_t n = 0; n < ni; ++n) {
1790 cports.push_back (_control_out->input(n)->name());
1792 bus->set_control_outs (cports);
1795 ret.push_back (bus);
1799 catch (failed_constructor &err) {
1800 error << _("Session: could not create new audio route.") << endmsg;
1809 add_routes (ret, false);
1810 save_state (_current_snapshot_name);
1818 Session::add_routes (RouteList& new_routes, bool save)
1821 RCUWriter<RouteList> writer (routes);
1822 shared_ptr<RouteList> r = writer.get_copy ();
1823 r->insert (r->end(), new_routes.begin(), new_routes.end());
1824 resort_routes_using (r);
1827 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1828 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
1829 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1830 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1831 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1833 if ((*x)->master()) {
1837 if ((*x)->control()) {
1838 _control_out = (*x);
1845 save_state (_current_snapshot_name);
1848 RouteAdded (new_routes); /* EMIT SIGNAL */
1852 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1854 /* need to do this in case we're rolling at the time, to prevent false underruns */
1855 dstream->do_refill_with_alloc();
1858 RCUWriter<DiskstreamList> writer (diskstreams);
1859 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1860 ds->push_back (dstream);
1863 dstream->set_block_size (current_block_size);
1865 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1866 /* this will connect to future changes, and check the current length */
1867 diskstream_playlist_changed (dstream);
1869 dstream->prepare ();
1873 Session::remove_route (shared_ptr<Route> route)
1876 RCUWriter<RouteList> writer (routes);
1877 shared_ptr<RouteList> rs = writer.get_copy ();
1880 /* deleting the master out seems like a dumb
1881 idea, but its more of a UI policy issue
1885 if (route == _master_out) {
1886 _master_out = shared_ptr<Route> ((Route*) 0);
1889 if (route == _control_out) {
1890 _control_out = shared_ptr<Route> ((Route*) 0);
1892 /* cancel control outs for all routes */
1894 vector<string> empty;
1896 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1897 (*r)->set_control_outs (empty);
1901 update_route_solo_state ();
1903 /* writer goes out of scope, forces route list update */
1906 // FIXME: audio specific
1908 boost::shared_ptr<AudioDiskstream> ds;
1910 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1911 ds = at->audio_diskstream();
1917 RCUWriter<DiskstreamList> dsl (diskstreams);
1918 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1923 find_current_end ();
1925 update_latency_compensation (false, false);
1928 /* XXX should we disconnect from the Route's signals ? */
1930 save_state (_current_snapshot_name);
1932 /* try to cause everyone to drop their references */
1934 route->drop_references ();
1938 Session::route_mute_changed (void* src)
1944 Session::route_solo_changed (void* src, shared_ptr<Route> route)
1946 if (solo_update_disabled) {
1953 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
1955 shared_ptr<RouteList> r = routes.reader ();
1957 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1959 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1963 /* don't mess with busses */
1965 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1971 /* don't mess with tracks */
1973 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1978 if ((*i) != route &&
1979 ((*i)->mix_group () == 0 ||
1980 (*i)->mix_group () != route->mix_group () ||
1981 !route->mix_group ()->is_active())) {
1983 if ((*i)->soloed()) {
1985 /* if its already soloed, and solo latching is enabled,
1986 then leave it as it is.
1989 if (Config->get_solo_latched()) {
1996 solo_update_disabled = true;
1997 (*i)->set_solo (false, src);
1998 solo_update_disabled = false;
2002 bool something_soloed = false;
2003 bool same_thing_soloed = false;
2004 bool signal = false;
2006 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2007 if ((*i)->soloed()) {
2008 something_soloed = true;
2009 if (dynamic_cast<AudioTrack*>((*i).get())) {
2011 same_thing_soloed = true;
2016 same_thing_soloed = true;
2024 if (something_soloed != currently_soloing) {
2026 currently_soloing = something_soloed;
2029 modify_solo_mute (is_track, same_thing_soloed);
2032 SoloActive (currently_soloing);
2039 Session::update_route_solo_state ()
2042 bool is_track = false;
2043 bool signal = false;
2045 /* caller must hold RouteLock */
2047 /* this is where we actually implement solo by changing
2048 the solo mute setting of each track.
2051 shared_ptr<RouteList> r = routes.reader ();
2053 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2054 if ((*i)->soloed()) {
2056 if (dynamic_cast<AudioTrack*>((*i).get())) {
2063 if (mute != currently_soloing) {
2065 currently_soloing = mute;
2068 if (!is_track && !mute) {
2070 /* nothing is soloed */
2072 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2073 (*i)->set_solo_mute (false);
2083 modify_solo_mute (is_track, mute);
2086 SoloActive (currently_soloing);
2091 Session::modify_solo_mute (bool is_track, bool mute)
2093 shared_ptr<RouteList> r = routes.reader ();
2095 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2099 /* only alter track solo mute */
2101 if (dynamic_cast<AudioTrack*>((*i).get())) {
2102 if ((*i)->soloed()) {
2103 (*i)->set_solo_mute (!mute);
2105 (*i)->set_solo_mute (mute);
2111 /* only alter bus solo mute */
2113 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2115 if ((*i)->soloed()) {
2117 (*i)->set_solo_mute (false);
2121 /* don't mute master or control outs
2122 in response to another bus solo
2125 if ((*i) != _master_out &&
2126 (*i) != _control_out) {
2127 (*i)->set_solo_mute (mute);
2138 Session::catch_up_on_solo ()
2140 /* this is called after set_state() to catch the full solo
2141 state, which can't be correctly determined on a per-route
2142 basis, but needs the global overview that only the session
2145 update_route_solo_state();
2149 Session::route_by_name (string name)
2151 shared_ptr<RouteList> r = routes.reader ();
2153 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2154 if ((*i)->name() == name) {
2159 return shared_ptr<Route> ((Route*) 0);
2163 Session::route_by_id (PBD::ID id)
2165 shared_ptr<RouteList> r = routes.reader ();
2167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 if ((*i)->id() == id) {
2173 return shared_ptr<Route> ((Route*) 0);
2177 Session::route_by_remote_id (uint32_t id)
2179 shared_ptr<RouteList> r = routes.reader ();
2181 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2182 if ((*i)->remote_control_id() == id) {
2187 return shared_ptr<Route> ((Route*) 0);
2191 Session::find_current_end ()
2193 if (_state_of_the_state & Loading) {
2197 nframes_t max = get_maximum_extent ();
2199 if (max > end_location->end()) {
2200 end_location->set_end (max);
2202 DurationChanged(); /* EMIT SIGNAL */
2207 Session::get_maximum_extent () const
2212 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2214 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2215 Playlist* pl = (*i)->playlist();
2216 if ((me = pl->get_maximum_extent()) > max) {
2224 boost::shared_ptr<Diskstream>
2225 Session::diskstream_by_name (string name)
2227 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2229 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2230 if ((*i)->name() == name) {
2235 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2238 boost::shared_ptr<Diskstream>
2239 Session::diskstream_by_id (const PBD::ID& id)
2241 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2243 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2244 if ((*i)->id() == id) {
2249 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2252 /* AudioRegion management */
2255 Session::new_region_name (string old)
2257 string::size_type last_period;
2259 string::size_type len = old.length() + 64;
2262 if ((last_period = old.find_last_of ('.')) == string::npos) {
2264 /* no period present - add one explicitly */
2267 last_period = old.length() - 1;
2272 number = atoi (old.substr (last_period+1).c_str());
2276 while (number < (UINT_MAX-1)) {
2278 AudioRegionList::const_iterator i;
2283 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2286 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2287 if (i->second->name() == sbuf) {
2292 if (i == audio_regions.end()) {
2297 if (number != (UINT_MAX-1)) {
2301 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2306 Session::region_name (string& result, string base, bool newlevel) const
2313 Glib::Mutex::Lock lm (region_lock);
2315 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2323 /* XXX this is going to be slow. optimize me later */
2328 string::size_type pos;
2330 pos = base.find_last_of ('.');
2332 /* pos may be npos, but then we just use entire base */
2334 subbase = base.substr (0, pos);
2338 bool name_taken = true;
2341 Glib::Mutex::Lock lm (region_lock);
2343 for (int n = 1; n < 5000; ++n) {
2346 snprintf (buf, sizeof (buf), ".%d", n);
2351 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2352 if (i->second->name() == result) {
2365 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2373 Session::add_region (boost::shared_ptr<Region> region)
2375 boost::shared_ptr<AudioRegion> ar;
2376 boost::shared_ptr<AudioRegion> oar;
2380 Glib::Mutex::Lock lm (region_lock);
2382 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2384 AudioRegionList::iterator x;
2386 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2388 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2390 if (ar->region_list_equivalent (oar)) {
2395 if (x == audio_regions.end()) {
2397 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2399 entry.first = region->id();
2402 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2414 fatal << _("programming error: ")
2415 << X_("unknown region type passed to Session::add_region()")
2422 /* mark dirty because something has changed even if we didn't
2423 add the region to the region list.
2429 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2430 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2431 AudioRegionAdded (ar); /* EMIT SIGNAL */
2436 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2438 if (what_changed & Region::HiddenChanged) {
2439 /* relay hidden changes */
2440 RegionHiddenChange (region);
2445 Session::region_renamed (boost::shared_ptr<Region> region)
2447 add_region (region);
2451 Session::remove_region (boost::shared_ptr<Region> region)
2453 AudioRegionList::iterator i;
2454 boost::shared_ptr<AudioRegion> ar;
2455 bool removed = false;
2458 Glib::Mutex::Lock lm (region_lock);
2460 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2461 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2462 audio_regions.erase (i);
2468 fatal << _("programming error: ")
2469 << X_("unknown region type passed to Session::remove_region()")
2475 /* mark dirty because something has changed even if we didn't
2476 remove the region from the region list.
2482 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2486 boost::shared_ptr<AudioRegion>
2487 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2489 AudioRegionList::iterator i;
2490 boost::shared_ptr<AudioRegion> region;
2491 Glib::Mutex::Lock lm (region_lock);
2493 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2497 if (region->whole_file()) {
2499 if (child->source_equivalent (region)) {
2505 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2509 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2511 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2512 (*i)->get_region_list_equivalent_regions (region, result);
2516 Session::destroy_region (boost::shared_ptr<Region> region)
2518 boost::shared_ptr<AudioRegion> aregion;
2520 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2524 if (aregion->playlist()) {
2525 aregion->playlist()->destroy_region (region);
2528 vector<boost::shared_ptr<Source> > srcs;
2530 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2531 srcs.push_back (aregion->source (n));
2534 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2536 if ((*i).use_count() == 1) {
2537 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2540 (afs)->mark_for_remove ();
2543 (*i)->drop_references ();
2551 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2553 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2554 destroy_region (*i);
2560 Session::remove_last_capture ()
2562 list<boost::shared_ptr<Region> > r;
2564 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2566 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2567 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2570 r.insert (r.end(), l.begin(), l.end());
2575 destroy_regions (r);
2580 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2586 /* Source Management */
2589 Session::add_source (boost::shared_ptr<Source> source)
2591 boost::shared_ptr<AudioFileSource> afs;
2593 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2595 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2596 pair<AudioSourceList::iterator,bool> result;
2598 entry.first = source->id();
2602 Glib::Mutex::Lock lm (audio_source_lock);
2603 result = audio_sources.insert (entry);
2606 if (!result.second) {
2607 cerr << "\tNOT inserted ? " << result.second << endl;
2610 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2613 SourceAdded (source); /* EMIT SIGNAL */
2615 cerr << "\tNOT AUDIO FILE\n";
2620 Session::remove_source (boost::weak_ptr<Source> src)
2622 AudioSourceList::iterator i;
2623 boost::shared_ptr<Source> source = src.lock();
2626 cerr << "removing a source DEAD\n";
2628 cerr << "removing a source " << source->name () << endl;
2631 Glib::Mutex::Lock lm (audio_source_lock);
2633 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2634 audio_sources.erase (i);
2638 if (!_state_of_the_state & InCleanup) {
2640 /* save state so we don't end up with a session file
2641 referring to non-existent sources.
2644 save_state (_current_snapshot_name);
2647 SourceRemoved(source); /* EMIT SIGNAL */
2651 boost::shared_ptr<Source>
2652 Session::source_by_id (const PBD::ID& id)
2654 Glib::Mutex::Lock lm (audio_source_lock);
2655 AudioSourceList::iterator i;
2656 boost::shared_ptr<Source> source;
2658 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2662 /* XXX search MIDI or other searches here */
2668 Session::peak_path_from_audio_path (string audio_path) const
2673 res += PBD::basename_nosuffix (audio_path);
2680 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2683 string old_basename = PBD::basename_nosuffix (oldname);
2684 string new_legalized = legalize_for_path (newname);
2686 /* note: we know (or assume) the old path is already valid */
2690 /* destructive file sources have a name of the form:
2692 /path/to/Tnnnn-NAME(%[LR])?.wav
2694 the task here is to replace NAME with the new name.
2697 /* find last slash */
2701 string::size_type slash;
2702 string::size_type dash;
2704 if ((slash = path.find_last_of ('/')) == string::npos) {
2708 dir = path.substr (0, slash+1);
2710 /* '-' is not a legal character for the NAME part of the path */
2712 if ((dash = path.find_last_of ('-')) == string::npos) {
2716 prefix = path.substr (slash+1, dash-(slash+1));
2721 path += new_legalized;
2722 path += ".wav"; /* XXX gag me with a spoon */
2726 /* non-destructive file sources have a name of the form:
2728 /path/to/NAME-nnnnn(%[LR])?.wav
2730 the task here is to replace NAME with the new name.
2735 string::size_type slash;
2736 string::size_type dash;
2737 string::size_type postfix;
2739 /* find last slash */
2741 if ((slash = path.find_last_of ('/')) == string::npos) {
2745 dir = path.substr (0, slash+1);
2747 /* '-' is not a legal character for the NAME part of the path */
2749 if ((dash = path.find_last_of ('-')) == string::npos) {
2753 suffix = path.substr (dash+1);
2755 // Suffix is now everything after the dash. Now we need to eliminate
2756 // the nnnnn part, which is done by either finding a '%' or a '.'
2758 postfix = suffix.find_last_of ("%");
2759 if (postfix == string::npos) {
2760 postfix = suffix.find_last_of ('.');
2763 if (postfix != string::npos) {
2764 suffix = suffix.substr (postfix);
2766 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2770 const uint32_t limit = 10000;
2771 char buf[PATH_MAX+1];
2773 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2775 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2777 if (access (buf, F_OK) != 0) {
2785 error << "FATAL ERROR! Could not find a " << endl;
2794 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2798 char buf[PATH_MAX+1];
2799 const uint32_t limit = 10000;
2803 legalized = legalize_for_path (name);
2805 /* find a "version" of the file name that doesn't exist in
2806 any of the possible directories.
2809 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2811 vector<space_and_path>::iterator i;
2812 uint32_t existing = 0;
2814 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2818 spath += sound_dir (false);
2822 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2823 } else if (nchan == 2) {
2825 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2827 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2829 } else if (nchan < 26) {
2830 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2832 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2840 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2841 } else if (nchan == 2) {
2843 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2845 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2847 } else if (nchan < 26) {
2848 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2850 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2854 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2860 if (existing == 0) {
2865 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2866 throw failed_constructor();
2870 /* we now have a unique name for the file, but figure out where to
2876 spath = discover_best_sound_dir ();
2878 string::size_type pos = foo.find_last_of ('/');
2880 if (pos == string::npos) {
2883 spath += foo.substr (pos + 1);
2889 boost::shared_ptr<AudioFileSource>
2890 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2892 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2893 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2896 /* Playlist management */
2899 Session::playlist_by_name (string name)
2901 Glib::Mutex::Lock lm (playlist_lock);
2902 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2903 if ((*i)->name() == name) {
2907 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2908 if ((*i)->name() == name) {
2916 Session::add_playlist (Playlist* playlist)
2918 if (playlist->hidden()) {
2923 Glib::Mutex::Lock lm (playlist_lock);
2924 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2925 playlists.insert (playlists.begin(), playlist);
2927 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2928 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2934 PlaylistAdded (playlist); /* EMIT SIGNAL */
2938 Session::track_playlist (Playlist* pl, bool inuse)
2940 PlaylistList::iterator x;
2943 Glib::Mutex::Lock lm (playlist_lock);
2946 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2948 unused_playlists.insert (pl);
2950 if ((x = playlists.find (pl)) != playlists.end()) {
2951 playlists.erase (x);
2956 //cerr << "shifting playlist to used: " << pl->name() << endl;
2958 playlists.insert (pl);
2960 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2961 unused_playlists.erase (x);
2968 Session::remove_playlist (Playlist* playlist)
2970 if (_state_of_the_state & Deletion) {
2975 Glib::Mutex::Lock lm (playlist_lock);
2976 // cerr << "removing playlist: " << playlist->name() << endl;
2978 PlaylistList::iterator i;
2980 i = find (playlists.begin(), playlists.end(), playlist);
2982 if (i != playlists.end()) {
2983 playlists.erase (i);
2986 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2987 if (i != unused_playlists.end()) {
2988 unused_playlists.erase (i);
2995 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2999 Session::set_audition (boost::shared_ptr<Region> r)
3001 pending_audition_region = r;
3002 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3003 schedule_butler_transport_work ();
3007 Session::audition_playlist ()
3009 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3010 ev->region.reset ();
3015 Session::non_realtime_set_audition ()
3017 if (!pending_audition_region) {
3018 auditioner->audition_current_playlist ();
3020 auditioner->audition_region (pending_audition_region);
3021 pending_audition_region.reset ();
3023 AuditionActive (true); /* EMIT SIGNAL */
3027 Session::audition_region (boost::shared_ptr<Region> r)
3029 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3035 Session::cancel_audition ()
3037 if (auditioner->active()) {
3038 auditioner->cancel_audition ();
3039 AuditionActive (false); /* EMIT SIGNAL */
3044 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3046 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3050 Session::remove_empty_sounds ()
3052 PathScanner scanner;
3054 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3056 Glib::Mutex::Lock lm (audio_source_lock);
3058 regex_t compiled_tape_track_pattern;
3061 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3065 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3067 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3071 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3073 /* never remove files that appear to be a tape track */
3075 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3080 if (AudioFileSource::is_empty (*this, *(*i))) {
3082 unlink ((*i)->c_str());
3084 string peak_path = peak_path_from_audio_path (**i);
3085 unlink (peak_path.c_str());
3091 delete possible_audiofiles;
3095 Session::is_auditioning () const
3097 /* can be called before we have an auditioner object */
3099 return auditioner->active();
3106 Session::set_all_solo (bool yn)
3108 shared_ptr<RouteList> r = routes.reader ();
3110 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3111 if (!(*i)->hidden()) {
3112 (*i)->set_solo (yn, this);
3120 Session::set_all_mute (bool yn)
3122 shared_ptr<RouteList> r = routes.reader ();
3124 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3125 if (!(*i)->hidden()) {
3126 (*i)->set_mute (yn, this);
3134 Session::n_diskstreams () const
3138 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3140 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3141 if (!(*i)->hidden()) {
3149 Session::graph_reordered ()
3151 /* don't do this stuff if we are setting up connections
3152 from a set_state() call.
3155 if (_state_of_the_state & InitialConnecting) {
3161 /* force all diskstreams to update their capture offset values to
3162 reflect any changes in latencies within the graph.
3165 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3167 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3168 (*i)->set_capture_offset ();
3173 Session::record_disenable_all ()
3175 record_enable_change_all (false);
3179 Session::record_enable_all ()
3181 record_enable_change_all (true);
3185 Session::record_enable_change_all (bool yn)
3187 shared_ptr<RouteList> r = routes.reader ();
3189 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3192 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3193 at->set_record_enable (yn, this);
3197 /* since we don't keep rec-enable state, don't mark session dirty */
3201 Session::add_redirect (Redirect* redirect)
3205 PortInsert* port_insert;
3206 PluginInsert* plugin_insert;
3208 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3209 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3210 _port_inserts.insert (_port_inserts.begin(), port_insert);
3211 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3212 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3214 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3217 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3218 _sends.insert (_sends.begin(), send);
3220 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3224 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3230 Session::remove_redirect (Redirect* redirect)
3234 PortInsert* port_insert;
3235 PluginInsert* plugin_insert;
3237 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3238 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3239 _port_inserts.remove (port_insert);
3240 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3241 _plugin_inserts.remove (plugin_insert);
3243 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3246 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3247 _sends.remove (send);
3249 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3257 Session::available_capture_duration ()
3259 const double scale = 4096.0 / sizeof (Sample);
3261 if (_total_free_4k_blocks * scale > (double) max_frames) {
3265 return (nframes_t) floor (_total_free_4k_blocks * scale);
3269 Session::add_connection (ARDOUR::Connection* connection)
3272 Glib::Mutex::Lock guard (connection_lock);
3273 _connections.push_back (connection);
3276 ConnectionAdded (connection); /* EMIT SIGNAL */
3282 Session::remove_connection (ARDOUR::Connection* connection)
3284 bool removed = false;
3287 Glib::Mutex::Lock guard (connection_lock);
3288 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3290 if (i != _connections.end()) {
3291 _connections.erase (i);
3297 ConnectionRemoved (connection); /* EMIT SIGNAL */
3303 ARDOUR::Connection *
3304 Session::connection_by_name (string name) const
3306 Glib::Mutex::Lock lm (connection_lock);
3308 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3309 if ((*i)->name() == name) {
3318 Session::tempo_map_changed (Change ignored)
3325 Session::ensure_passthru_buffers (uint32_t howmany)
3327 while (howmany > _passthru_buffers.size()) {
3329 #ifdef NO_POSIX_MEMALIGN
3330 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3332 posix_memalign((void **)&p,16,current_block_size * 4);
3334 _passthru_buffers.push_back (p);
3338 #ifdef NO_POSIX_MEMALIGN
3339 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3341 posix_memalign((void **)&p,16,current_block_size * 4);
3343 memset (p, 0, sizeof (Sample) * current_block_size);
3344 _silent_buffers.push_back (p);
3348 #ifdef NO_POSIX_MEMALIGN
3349 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3351 posix_memalign((void **)&p,16,current_block_size * 4);
3353 memset (p, 0, sizeof (Sample) * current_block_size);
3354 _send_buffers.push_back (p);
3357 allocate_pan_automation_buffers (current_block_size, howmany, false);
3361 Session::next_send_name ()
3364 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3369 Session::next_insert_name ()
3372 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3376 /* Named Selection management */
3379 Session::named_selection_by_name (string name)
3381 Glib::Mutex::Lock lm (named_selection_lock);
3382 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3383 if ((*i)->name == name) {
3391 Session::add_named_selection (NamedSelection* named_selection)
3394 Glib::Mutex::Lock lm (named_selection_lock);
3395 named_selections.insert (named_selections.begin(), named_selection);
3400 NamedSelectionAdded (); /* EMIT SIGNAL */
3404 Session::remove_named_selection (NamedSelection* named_selection)
3406 bool removed = false;
3409 Glib::Mutex::Lock lm (named_selection_lock);
3411 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3413 if (i != named_selections.end()) {
3415 named_selections.erase (i);
3422 NamedSelectionRemoved (); /* EMIT SIGNAL */
3427 Session::reset_native_file_format ()
3429 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3431 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3432 (*i)->reset_write_sources (false);
3437 Session::route_name_unique (string n) const
3439 shared_ptr<RouteList> r = routes.reader ();
3441 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3442 if ((*i)->name() == n) {
3451 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3453 return fs->move_to_trash (dead_sound_dir_name);
3457 Session::n_playlists () const
3459 Glib::Mutex::Lock lm (playlist_lock);
3460 return playlists.size();
3464 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3466 if (!force && howmany <= _npan_buffers) {
3470 if (_pan_automation_buffer) {
3472 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3473 delete [] _pan_automation_buffer[i];
3476 delete [] _pan_automation_buffer;
3479 _pan_automation_buffer = new pan_t*[howmany];
3481 for (uint32_t i = 0; i < howmany; ++i) {
3482 _pan_automation_buffer[i] = new pan_t[nframes];
3485 _npan_buffers = howmany;
3489 Session::freeze (InterThreadInfo& itt)
3491 shared_ptr<RouteList> r = routes.reader ();
3493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3497 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3498 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3509 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3510 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3514 boost::shared_ptr<AudioFileSource> fsource;
3516 char buf[PATH_MAX+1];
3520 nframes_t this_chunk;
3522 vector<Sample*> buffers;
3524 // any bigger than this seems to cause stack overflows in called functions
3525 const nframes_t chunk_size = (128 * 1024)/4;
3527 g_atomic_int_set (&processing_prohibited, 1);
3529 /* call tree *MUST* hold route_lock */
3531 if ((playlist = track.diskstream()->playlist()) == 0) {
3535 /* external redirects will be a problem */
3537 if (track.has_external_redirects()) {
3541 nchans = track.audio_diskstream()->n_channels();
3543 dir = discover_best_sound_dir ();
3545 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3547 for (x = 0; x < 99999; ++x) {
3548 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3549 if (access (buf, F_OK) != 0) {
3555 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3560 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3563 catch (failed_constructor& err) {
3564 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3568 srcs.push_back (fsource);
3571 /* XXX need to flush all redirects */
3576 /* create a set of reasonably-sized buffers */
3578 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3580 #ifdef NO_POSIX_MEMALIGN
3581 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3583 posix_memalign((void **)&b,16,chunk_size * 4);
3585 buffers.push_back (b);
3588 while (to_do && !itt.cancel) {
3590 this_chunk = min (to_do, chunk_size);
3592 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3597 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3598 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3601 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3607 start += this_chunk;
3608 to_do -= this_chunk;
3610 itt.progress = (float) (1.0 - ((double) to_do / len));
3619 xnow = localtime (&now);
3621 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3622 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3625 afs->update_header (position, *xnow, now);
3629 /* build peakfile for new source */
3631 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3632 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3634 afs->build_peaks ();
3643 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3644 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3647 afs->mark_for_remove ();
3650 (*src)->drop_references ();
3654 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3658 g_atomic_int_set (&processing_prohibited, 0);
3666 Session::get_silent_buffers (uint32_t howmany)
3668 for (uint32_t i = 0; i < howmany; ++i) {
3669 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3671 return _silent_buffers;
3675 Session::ntracks () const
3678 shared_ptr<RouteList> r = routes.reader ();
3680 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3681 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3690 Session::nbusses () const
3693 shared_ptr<RouteList> r = routes.reader ();
3695 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3696 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3705 Session::add_curve(Curve *curve)
3707 curves[curve->id()] = curve;
3711 Session::add_automation_list(AutomationList *al)
3713 automation_lists[al->id()] = al;