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.
25 #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>
37 #include <glibmm/fileutils.h>
39 #include <pbd/error.h>
40 #include <glibmm/thread.h>
41 #include <pbd/pathscanner.h>
42 #include <pbd/stl_delete.h>
43 #include <pbd/basename.h>
44 #include <pbd/stacktrace.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/analyser.h>
50 #include <ardour/audio_diskstream.h>
51 #include <ardour/utils.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/audiofilesource.h>
55 #include <ardour/auditioner.h>
56 #include <ardour/recent_sessions.h>
57 #include <ardour/redirect.h>
58 #include <ardour/send.h>
59 #include <ardour/insert.h>
60 #include <ardour/connection.h>
61 #include <ardour/slave.h>
62 #include <ardour/tempo.h>
63 #include <ardour/audio_track.h>
64 #include <ardour/cycle_timer.h>
65 #include <ardour/named_selection.h>
66 #include <ardour/crossfade.h>
67 #include <ardour/playlist.h>
68 #include <ardour/click.h>
69 #include <ardour/data_type.h>
70 #include <ardour/source_factory.h>
71 #include <ardour/region_factory.h>
74 #include <ardour/osc.h>
80 using namespace ARDOUR;
82 using boost::shared_ptr;
85 static const int CPU_CACHE_ALIGN = 64;
87 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
90 const char* Session::_template_suffix = X_(".template");
91 const char* Session::_statefile_suffix = X_(".ardour");
92 const char* Session::_pending_suffix = X_(".pending");
93 const char* Session::old_sound_dir_name = X_("sounds");
94 const char* Session::sound_dir_name = X_("audiofiles");
95 const char* Session::peak_dir_name = X_("peaks");
96 const char* Session::dead_sound_dir_name = X_("dead_sounds");
97 const char* Session::interchange_dir_name = X_("interchange");
98 const char* Session::export_dir_name = X_("export");
100 bool Session::_disable_all_loaded_plugins = false;
102 Session::compute_peak_t Session::compute_peak = 0;
103 Session::find_peaks_t Session::find_peaks = 0;
104 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
105 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
106 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
108 sigc::signal<void,std::string> Session::Dialog;
109 sigc::signal<int> Session::AskAboutPendingState;
110 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
111 sigc::signal<void> Session::SendFeedback;
113 sigc::signal<void> Session::SMPTEOffsetChanged;
114 sigc::signal<void> Session::StartTimeChanged;
115 sigc::signal<void> Session::EndTimeChanged;
117 sigc::signal<void> Session::AutoBindingOn;
118 sigc::signal<void> Session::AutoBindingOff;
121 sigc::signal<void, std::string, std::string> Session::Exported;
124 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
127 char buf[PATH_MAX+1];
131 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
132 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
138 /* check to see if it exists, and what it is */
140 if (stat (str.c_str(), &statbuf)) {
141 if (errno == ENOENT) {
144 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
152 /* it exists, so it must either be the name
153 of the directory, or the name of the statefile
157 if (S_ISDIR (statbuf.st_mode)) {
159 string::size_type slash = str.find_last_of ('/');
161 if (slash == string::npos) {
163 /* a subdirectory of cwd, so statefile should be ... */
169 tmp += _statefile_suffix;
173 if (stat (tmp.c_str(), &statbuf)) {
174 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
184 /* some directory someplace in the filesystem.
185 the snapshot name is the directory name
190 snapshot = str.substr (slash+1);
194 } else if (S_ISREG (statbuf.st_mode)) {
196 string::size_type slash = str.find_last_of ('/');
197 string::size_type suffix;
199 /* remove the suffix */
201 if (slash != string::npos) {
202 snapshot = str.substr (slash+1);
207 suffix = snapshot.find (_statefile_suffix);
209 if (suffix == string::npos) {
210 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
216 snapshot = snapshot.substr (0, suffix);
218 if (slash == string::npos) {
220 /* we must be in the directory where the
221 statefile lives. get it using cwd().
224 char cwd[PATH_MAX+1];
226 if (getcwd (cwd, sizeof (cwd)) == 0) {
227 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
236 /* full path to the statefile */
238 path = str.substr (0, slash);
243 /* what type of file is it? */
244 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
250 /* its the name of a new directory. get the name
254 string::size_type slash = str.find_last_of ('/');
256 if (slash == string::npos) {
258 /* no slash, just use the name, but clean it up */
260 path = legalize_for_path (str);
266 snapshot = str.substr (slash+1);
273 Session::Session (AudioEngine &eng,
274 const string& fullpath,
275 const string& snapshot_name,
280 _mmc_port (default_mmc_port),
281 _mtc_port (default_mtc_port),
282 _midi_port (default_midi_port),
283 pending_events (2048),
285 butler_mixdown_buffer (0),
286 butler_gain_buffer (0),
287 midi_thread (pthread_t (0)),
288 midi_requests (128), // the size of this should match the midi request pool size
289 diskstreams (new DiskstreamList),
290 routes (new RouteList),
291 auditioner ((Auditioner*) 0),
292 _total_free_4k_blocks (0),
295 click_emphasis_data (0),
300 if (!eng.connected()) {
301 throw failed_constructor();
304 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
306 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
307 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
309 first_stage_init (fullpath, snapshot_name);
311 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
314 if (create (new_session, mix_template, compute_initial_length())) {
316 throw failed_constructor ();
320 if (second_stage_init (new_session)) {
322 throw failed_constructor ();
325 store_recent_sessions(_name, _path);
327 bool was_dirty = dirty();
329 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
331 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
334 DirtyChanged (); /* EMIT SIGNAL */
338 Session::Session (AudioEngine &eng,
340 string snapshot_name,
341 AutoConnectOption input_ac,
342 AutoConnectOption output_ac,
343 uint32_t control_out_channels,
344 uint32_t master_out_channels,
345 uint32_t requested_physical_in,
346 uint32_t requested_physical_out,
347 nframes_t initial_length)
351 _mmc_port (default_mmc_port),
352 _mtc_port (default_mtc_port),
353 _midi_port (default_midi_port),
354 pending_events (2048),
356 butler_mixdown_buffer (0),
357 butler_gain_buffer (0),
358 midi_thread (pthread_t (0)),
360 diskstreams (new DiskstreamList),
361 routes (new RouteList),
362 auditioner ((Auditioner *) 0),
363 _total_free_4k_blocks (0),
364 _click_io ((IO *) 0),
366 click_emphasis_data (0),
372 if (!eng.connected()) {
373 throw failed_constructor();
376 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
378 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
379 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
381 if (n_physical_audio_inputs) {
382 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
385 if (n_physical_audio_outputs) {
386 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
389 first_stage_init (fullpath, snapshot_name);
391 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
394 if (create (new_session, string(), initial_length)) {
396 throw failed_constructor ();
401 /* set up Master Out and Control Out if necessary */
406 if (control_out_channels) {
407 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
408 r->set_remote_control_id (control_id++);
413 if (master_out_channels) {
414 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
415 r->set_remote_control_id (control_id);
419 /* prohibit auto-connect to master, because there isn't one */
420 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
424 add_routes (rl, false);
429 Config->set_input_auto_connect (input_ac);
430 Config->set_output_auto_connect (output_ac);
432 if (second_stage_init (new_session)) {
434 throw failed_constructor ();
437 store_recent_sessions (_name, _path);
439 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
442 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
453 /* if we got to here, leaving pending capture state around
457 remove_pending_capture_state ();
459 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
461 _engine.remove_session ();
463 GoingAway (); /* EMIT SIGNAL */
469 /* clear history so that no references to objects are held any more */
473 /* clear state tree so that no references to objects are held any more */
476 terminate_butler_thread ();
477 terminate_midi_thread ();
479 if (click_data != default_click) {
480 delete [] click_data;
483 if (click_emphasis_data != default_click_emphasis) {
484 delete [] click_emphasis_data;
489 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
493 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
497 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
501 AudioDiskstream::free_working_buffers();
503 /* this should cause deletion of the auditioner */
505 // auditioner.reset ();
507 #undef TRACK_DESTRUCTION
508 #ifdef TRACK_DESTRUCTION
509 cerr << "delete named selections\n";
510 #endif /* TRACK_DESTRUCTION */
511 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
512 NamedSelectionList::iterator tmp;
521 #ifdef TRACK_DESTRUCTION
522 cerr << "delete playlists\n";
523 #endif /* TRACK_DESTRUCTION */
524 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
525 PlaylistList::iterator tmp;
530 (*i)->drop_references ();
535 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
536 PlaylistList::iterator tmp;
541 (*i)->drop_references ();
547 unused_playlists.clear ();
549 #ifdef TRACK_DESTRUCTION
550 cerr << "delete audio regions\n";
551 #endif /* TRACK_DESTRUCTION */
553 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
554 AudioRegionList::iterator tmp;
559 i->second->drop_references ();
564 audio_regions.clear ();
566 #ifdef TRACK_DESTRUCTION
567 cerr << "delete routes\n";
568 #endif /* TRACK_DESTRUCTION */
570 RCUWriter<RouteList> writer (routes);
571 boost::shared_ptr<RouteList> r = writer.get_copy ();
572 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
573 (*i)->drop_references ();
576 /* writer goes out of scope and updates master */
581 #ifdef TRACK_DESTRUCTION
582 cerr << "delete diskstreams\n";
583 #endif /* TRACK_DESTRUCTION */
585 RCUWriter<DiskstreamList> dwriter (diskstreams);
586 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
587 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
588 (*i)->drop_references ();
592 diskstreams.flush ();
594 #ifdef TRACK_DESTRUCTION
595 cerr << "delete audio sources\n";
596 #endif /* TRACK_DESTRUCTION */
597 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
598 AudioSourceList::iterator tmp;
603 i->second->drop_references ();
607 audio_sources.clear ();
609 #ifdef TRACK_DESTRUCTION
610 cerr << "delete mix groups\n";
611 #endif /* TRACK_DESTRUCTION */
612 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
613 list<RouteGroup*>::iterator tmp;
623 #ifdef TRACK_DESTRUCTION
624 cerr << "delete edit groups\n";
625 #endif /* TRACK_DESTRUCTION */
626 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
627 list<RouteGroup*>::iterator tmp;
637 #ifdef TRACK_DESTRUCTION
638 cerr << "delete connections\n";
639 #endif /* TRACK_DESTRUCTION */
640 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
641 ConnectionList::iterator tmp;
651 delete [] butler_mixdown_buffer;
652 delete [] butler_gain_buffer;
654 Crossfade::set_buffer_size (0);
660 Session::set_worst_io_latencies ()
662 _worst_output_latency = 0;
663 _worst_input_latency = 0;
665 if (!_engine.connected()) {
669 boost::shared_ptr<RouteList> r = routes.reader ();
671 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
672 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
673 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
678 Session::when_engine_running ()
680 /* we don't want to run execute this again */
682 BootMessage (_("Set block size and sample rate"));
684 set_block_size (_engine.frames_per_cycle());
685 set_frame_rate (_engine.frame_rate());
687 BootMessage (_("Using configuration"));
689 Config->map_parameters (mem_fun (*this, &Session::config_changed));
691 /* every time we reconnect, recompute worst case output latencies */
693 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
695 if (synced_to_jack()) {
696 _engine.transport_stop ();
699 if (Config->get_jack_time_master()) {
700 _engine.transport_locate (_transport_frame);
708 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
710 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
712 /* existing state for Click */
714 if (_click_io->set_state (*child->children().front()) == 0) {
716 _clicking = Config->get_clicking ();
720 error << _("could not setup Click I/O") << endmsg;
726 /* default state for Click: dual-mono to first 2 physical outputs */
728 for (int physport = 0; physport < 2; ++physport) {
729 string physical_output = _engine.get_nth_physical_audio_output (physport);
731 if (physical_output.length()) {
732 if (_click_io->add_output_port (physical_output, this)) {
733 // relax, even though its an error
738 if (_click_io->n_outputs() > 0) {
739 _clicking = Config->get_clicking ();
744 catch (failed_constructor& err) {
745 error << _("cannot setup Click I/O") << endmsg;
748 BootMessage (_("Compute I/O Latencies"));
750 set_worst_io_latencies ();
753 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
756 /* Create a set of Connection objects that map
757 to the physical outputs currently available
760 BootMessage (_("Set up standard connections"));
764 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
766 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
768 Connection* c = new OutputConnection (buf, true);
771 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
776 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
778 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
780 Connection* c = new InputConnection (buf, true);
783 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
790 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
792 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
794 Connection* c = new OutputConnection (buf, true);
798 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
799 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
804 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
806 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
808 Connection* c = new InputConnection (buf, true);
812 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
813 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
822 /* create master/control ports */
827 /* force the master to ignore any later call to this */
829 if (_master_out->pending_state_node) {
830 _master_out->ports_became_legal();
833 /* no panner resets till we are through */
835 _master_out->defer_pan_reset ();
837 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
838 if (_master_out->add_input_port ("", this)) {
839 error << _("cannot setup master inputs")
845 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
846 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
847 error << _("cannot setup master outputs")
854 _master_out->allow_pan_reset ();
858 Connection* c = new OutputConnection (_("Master Out"), true);
860 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
862 c->add_connection ((int) n, _master_out->input(n)->name());
867 BootMessage (_("Setup signal flow and plugins"));
871 /* catch up on send+insert cnts */
873 BootMessage (_("Catch up with send/insert state"));
877 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
880 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
881 if (id > insert_cnt) {
889 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
892 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
900 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
902 /* hook us up to the engine */
904 BootMessage (_("Connect to engine"));
906 _engine.set_session (this);
911 BootMessage (_("OSC startup"));
913 osc->set_session (*this);
919 Session::hookup_io ()
921 /* stop graph reordering notifications from
922 causing resorts, etc.
925 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
928 if (auditioner == 0) {
930 /* we delay creating the auditioner till now because
931 it makes its own connections to ports.
932 the engine has to be running for this to work.
936 auditioner.reset (new Auditioner (*this));
939 catch (failed_constructor& err) {
940 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
944 /* Tell all IO objects to create their ports */
950 vector<string> cports;
952 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
953 if (_control_out->add_input_port ("", this)) {
954 error << _("cannot setup control inputs")
960 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
961 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
962 error << _("cannot set up master outputs")
970 uint32_t ni = _control_out->n_inputs();
972 for (n = 0; n < ni; ++n) {
973 cports.push_back (_control_out->input(n)->name());
976 boost::shared_ptr<RouteList> r = routes.reader ();
978 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
979 (*x)->set_control_outs (cports);
983 /* Tell all IO objects to connect themselves together */
985 IO::enable_connecting ();
987 /* Now reset all panners */
989 IO::reset_panners ();
991 /* Anyone who cares about input state, wake up and do something */
993 IOConnectionsComplete (); /* EMIT SIGNAL */
995 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
998 /* now handle the whole enchilada as if it was one
1004 /* update mixer solo state */
1010 Session::playlist_length_changed ()
1012 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1013 if larger. if the playlist used to be the longest playlist,
1014 and its now shorter, we have to decrease end_location->end(). hence,
1015 we have to iterate over all diskstreams and check the
1016 playlists currently in use.
1018 find_current_end ();
1022 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1024 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1031 boost::shared_ptr<Playlist> playlist;
1033 if ((playlist = dstream->playlist()) != 0) {
1034 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1037 /* see comment in playlist_length_changed () */
1038 find_current_end ();
1042 Session::record_enabling_legal () const
1044 /* this used to be in here, but survey says.... we don't need to restrict it */
1045 // if (record_status() == Recording) {
1049 if (Config->get_all_safe()) {
1056 Session::reset_input_monitor_state ()
1058 if (transport_rolling()) {
1060 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1062 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1063 if ((*i)->record_enabled ()) {
1064 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1065 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1069 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1071 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1072 if ((*i)->record_enabled ()) {
1073 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1074 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1081 Session::auto_punch_start_changed (Location* location)
1083 replace_event (Event::PunchIn, location->start());
1085 if (get_record_enabled() && Config->get_punch_in()) {
1086 /* capture start has been changed, so save new pending state */
1087 save_state ("", true);
1092 Session::auto_punch_end_changed (Location* location)
1094 nframes_t when_to_stop = location->end();
1095 // when_to_stop += _worst_output_latency + _worst_input_latency;
1096 replace_event (Event::PunchOut, when_to_stop);
1100 Session::auto_punch_changed (Location* location)
1102 nframes_t when_to_stop = location->end();
1104 replace_event (Event::PunchIn, location->start());
1105 //when_to_stop += _worst_output_latency + _worst_input_latency;
1106 replace_event (Event::PunchOut, when_to_stop);
1110 Session::auto_loop_changed (Location* location)
1112 replace_event (Event::AutoLoop, location->end(), location->start());
1114 if (transport_rolling() && play_loop) {
1116 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1118 if (_transport_frame > location->end()) {
1119 // relocate to beginning of loop
1120 clear_events (Event::LocateRoll);
1122 request_locate (location->start(), true);
1125 else if (Config->get_seamless_loop() && !loop_changing) {
1127 // schedule a locate-roll to refill the diskstreams at the
1128 // previous loop end
1129 loop_changing = true;
1131 if (location->end() > last_loopend) {
1132 clear_events (Event::LocateRoll);
1133 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1140 last_loopend = location->end();
1144 Session::set_auto_punch_location (Location* location)
1148 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1149 auto_punch_start_changed_connection.disconnect();
1150 auto_punch_end_changed_connection.disconnect();
1151 auto_punch_changed_connection.disconnect();
1152 existing->set_auto_punch (false, this);
1153 remove_event (existing->start(), Event::PunchIn);
1154 clear_events (Event::PunchOut);
1155 auto_punch_location_changed (0);
1160 if (location == 0) {
1164 if (location->end() <= location->start()) {
1165 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1169 auto_punch_start_changed_connection.disconnect();
1170 auto_punch_end_changed_connection.disconnect();
1171 auto_punch_changed_connection.disconnect();
1173 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1174 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1175 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1177 location->set_auto_punch (true, this);
1180 auto_punch_changed (location);
1182 auto_punch_location_changed (location);
1186 Session::set_auto_loop_location (Location* location)
1190 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1191 auto_loop_start_changed_connection.disconnect();
1192 auto_loop_end_changed_connection.disconnect();
1193 auto_loop_changed_connection.disconnect();
1194 existing->set_auto_loop (false, this);
1195 remove_event (existing->end(), Event::AutoLoop);
1196 auto_loop_location_changed (0);
1201 if (location == 0) {
1205 if (location->end() <= location->start()) {
1206 error << _("Session: you can't use a mark for auto loop") << endmsg;
1210 last_loopend = location->end();
1212 auto_loop_start_changed_connection.disconnect();
1213 auto_loop_end_changed_connection.disconnect();
1214 auto_loop_changed_connection.disconnect();
1216 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1217 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1218 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1220 location->set_auto_loop (true, this);
1222 /* take care of our stuff first */
1224 auto_loop_changed (location);
1226 /* now tell everyone else */
1228 auto_loop_location_changed (location);
1232 Session::locations_added (Location* ignored)
1238 Session::locations_changed ()
1240 _locations.apply (*this, &Session::handle_locations_changed);
1244 Session::handle_locations_changed (Locations::LocationList& locations)
1246 Locations::LocationList::iterator i;
1248 bool set_loop = false;
1249 bool set_punch = false;
1251 for (i = locations.begin(); i != locations.end(); ++i) {
1255 if (location->is_auto_punch()) {
1256 set_auto_punch_location (location);
1259 if (location->is_auto_loop()) {
1260 set_auto_loop_location (location);
1264 if (location->is_start()) {
1265 start_location = location;
1267 if (location->is_end()) {
1268 end_location = location;
1273 set_auto_loop_location (0);
1276 set_auto_punch_location (0);
1283 Session::enable_record ()
1285 /* XXX really atomic compare+swap here */
1286 if (g_atomic_int_get (&_record_status) != Recording) {
1287 g_atomic_int_set (&_record_status, Recording);
1288 _last_record_location = _transport_frame;
1289 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1291 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1292 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1293 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1294 if ((*i)->record_enabled ()) {
1295 (*i)->monitor_input (true);
1300 RecordStateChanged ();
1305 Session::disable_record (bool rt_context, bool force)
1309 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1311 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1312 g_atomic_int_set (&_record_status, Disabled);
1314 if (rs == Recording) {
1315 g_atomic_int_set (&_record_status, Enabled);
1319 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1321 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1325 if ((*i)->record_enabled ()) {
1326 (*i)->monitor_input (false);
1331 RecordStateChanged (); /* emit signal */
1334 remove_pending_capture_state ();
1340 Session::step_back_from_record ()
1342 /* XXX really atomic compare+swap here */
1343 if (g_atomic_int_get (&_record_status) == Recording) {
1344 g_atomic_int_set (&_record_status, Enabled);
1346 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1347 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1349 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1350 if ((*i)->record_enabled ()) {
1351 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1352 (*i)->monitor_input (false);
1360 Session::maybe_enable_record ()
1362 g_atomic_int_set (&_record_status, Enabled);
1364 /* this function is currently called from somewhere other than an RT thread.
1365 this save_state() call therefore doesn't impact anything.
1368 save_state ("", true);
1370 if (_transport_speed) {
1371 if (!Config->get_punch_in()) {
1375 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1376 RecordStateChanged (); /* EMIT SIGNAL */
1383 Session::audible_frame () const
1389 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1390 return last_stop_frame;
1393 /* the first of these two possible settings for "offset"
1394 mean that the audible frame is stationary until
1395 audio emerges from the latency compensation
1398 the second means that the audible frame is stationary
1399 until audio would emerge from a physical port
1400 in the absence of any plugin latency compensation
1403 offset = _worst_output_latency;
1405 if (offset > current_block_size) {
1406 offset -= current_block_size;
1408 /* XXX is this correct? if we have no external
1409 physical connections and everything is internal
1410 then surely this is zero? still, how
1411 likely is that anyway?
1413 offset = current_block_size;
1416 if (synced_to_jack()) {
1417 tf = _engine.transport_frame();
1419 tf = _transport_frame;
1424 if (!non_realtime_work_pending()) {
1428 /* check to see if we have passed the first guaranteed
1429 audible frame past our last stopping position. if not,
1430 the return that last stopping point because in terms
1431 of audible frames, we have not moved yet.
1434 if (_transport_speed > 0.0f) {
1436 if (!play_loop || !have_looped) {
1437 if (tf < last_stop_frame + offset) {
1438 return last_stop_frame;
1447 } else if (_transport_speed < 0.0f) {
1449 /* XXX wot? no backward looping? */
1451 if (tf > last_stop_frame - offset) {
1452 return last_stop_frame;
1464 Session::set_frame_rate (nframes_t frames_per_second)
1466 /** \fn void Session::set_frame_size(nframes_t)
1467 the AudioEngine object that calls this guarantees
1468 that it will not be called while we are also in
1469 ::process(). Its fine to do things that block
1473 _base_frame_rate = frames_per_second;
1477 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1481 // XXX we need some equivalent to this, somehow
1482 // SndFileSource::setup_standard_crossfades (frames_per_second);
1486 /* XXX need to reset/reinstantiate all LADSPA plugins */
1490 Session::set_block_size (nframes_t nframes)
1492 /* the AudioEngine guarantees
1493 that it will not be called while we are also in
1494 ::process(). It is therefore fine to do things that block
1499 vector<Sample*>::iterator i;
1502 current_block_size = nframes;
1504 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1508 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1512 _passthru_buffers.clear ();
1513 _silent_buffers.clear ();
1515 ensure_passthru_buffers (np);
1517 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1521 #ifdef NO_POSIX_MEMALIGN
1522 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1524 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1528 memset (*i, 0, sizeof (Sample) * current_block_size);
1532 if (_gain_automation_buffer) {
1533 delete [] _gain_automation_buffer;
1535 _gain_automation_buffer = new gain_t[nframes];
1537 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1539 boost::shared_ptr<RouteList> r = routes.reader ();
1541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1542 (*i)->set_block_size (nframes);
1545 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1546 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1547 (*i)->set_block_size (nframes);
1550 set_worst_io_latencies ();
1555 Session::set_default_fade (float steepness, float fade_msecs)
1558 nframes_t fade_frames;
1560 /* Don't allow fade of less 1 frame */
1562 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1569 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1573 default_fade_msecs = fade_msecs;
1574 default_fade_steepness = steepness;
1577 // jlc, WTF is this!
1578 Glib::RWLock::ReaderLock lm (route_lock);
1579 AudioRegion::set_default_fade (steepness, fade_frames);
1584 /* XXX have to do this at some point */
1585 /* foreach region using default fade, reset, then
1586 refill_all_diskstream_buffers ();
1591 struct RouteSorter {
1592 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1593 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1595 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1598 if (r1->fed_by.empty()) {
1599 if (r2->fed_by.empty()) {
1600 /* no ardour-based connections inbound to either route. just use signal order */
1601 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1603 /* r2 has connections, r1 does not; run r1 early */
1607 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1614 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1616 shared_ptr<Route> r2;
1618 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1619 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1623 /* make a copy of the existing list of routes that feed r1 */
1625 set<shared_ptr<Route> > existing = r1->fed_by;
1627 /* for each route that feeds r1, recurse, marking it as feeding
1631 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1634 /* r2 is a route that feeds r1 which somehow feeds base. mark
1635 base as being fed by r2
1638 rbase->fed_by.insert (r2);
1642 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1646 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1650 /* now recurse, so that we can mark base as being fed by
1651 all routes that feed r2
1654 trace_terminal (r2, rbase);
1661 Session::resort_routes ()
1663 /* don't do anything here with signals emitted
1664 by Routes while we are being destroyed.
1667 if (_state_of_the_state & Deletion) {
1674 RCUWriter<RouteList> writer (routes);
1675 shared_ptr<RouteList> r = writer.get_copy ();
1676 resort_routes_using (r);
1677 /* writer goes out of scope and forces update */
1682 Session::resort_routes_using (shared_ptr<RouteList> r)
1684 RouteList::iterator i, j;
1686 for (i = r->begin(); i != r->end(); ++i) {
1688 (*i)->fed_by.clear ();
1690 for (j = r->begin(); j != r->end(); ++j) {
1692 /* although routes can feed themselves, it will
1693 cause an endless recursive descent if we
1694 detect it. so don't bother checking for
1702 if ((*j)->feeds (*i)) {
1703 (*i)->fed_by.insert (*j);
1708 for (i = r->begin(); i != r->end(); ++i) {
1709 trace_terminal (*i, *i);
1715 /* don't leave dangling references to routes in Route::fed_by */
1717 for (i = r->begin(); i != r->end(); ++i) {
1718 (*i)->fed_by.clear ();
1722 cerr << "finished route resort\n";
1724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1725 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1732 list<boost::shared_ptr<AudioTrack> >
1733 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1735 char track_name[32];
1736 uint32_t track_id = 0;
1738 uint32_t channels_used = 0;
1740 RouteList new_routes;
1741 list<boost::shared_ptr<AudioTrack> > ret;
1742 uint32_t control_id;
1744 /* count existing audio tracks */
1747 shared_ptr<RouteList> r = routes.reader ();
1749 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1750 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1751 if (!(*i)->hidden()) {
1753 channels_used += (*i)->n_inputs();
1759 vector<string> physinputs;
1760 vector<string> physoutputs;
1761 uint32_t nphysical_in;
1762 uint32_t nphysical_out;
1764 _engine.get_physical_audio_outputs (physoutputs);
1765 _engine.get_physical_audio_inputs (physinputs);
1766 control_id = ntracks() + nbusses() + 1;
1770 /* check for duplicate route names, since we might have pre-existing
1771 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1772 save, close,restart,add new route - first named route is now
1780 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1782 if (route_by_name (track_name) == 0) {
1786 } while (track_id < (UINT_MAX-1));
1788 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1789 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1794 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1795 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1800 shared_ptr<AudioTrack> track;
1803 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1805 if (track->ensure_io (input_channels, output_channels, false, this)) {
1806 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1807 input_channels, output_channels)
1813 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1817 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1818 port = physinputs[(channels_used+x)%nphysical_in];
1821 if (port.length() && track->connect_input (track->input (x), port, this)) {
1827 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1831 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1832 port = physoutputs[(channels_used+x)%nphysical_out];
1833 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1835 port = _master_out->input (x%_master_out->n_inputs())->name();
1839 if (port.length() && track->connect_output (track->output (x), port, this)) {
1844 channels_used += track->n_inputs ();
1846 track->audio_diskstream()->non_realtime_input_change();
1848 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1849 track->set_remote_control_id (control_id);
1852 new_routes.push_back (track);
1853 ret.push_back (track);
1857 catch (failed_constructor &err) {
1858 error << _("Session: could not create new audio track.") << endmsg;
1861 /* we need to get rid of this, since the track failed to be created */
1862 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1865 RCUWriter<DiskstreamList> writer (diskstreams);
1866 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1867 ds->remove (track->audio_diskstream());
1874 catch (AudioEngine::PortRegistrationFailure& pfe) {
1876 error << pfe.what() << endmsg;
1879 /* we need to get rid of this, since the track failed to be created */
1880 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1883 RCUWriter<DiskstreamList> writer (diskstreams);
1884 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1885 ds->remove (track->audio_diskstream());
1896 if (!new_routes.empty()) {
1897 add_routes (new_routes, true);
1904 Session::set_remote_control_ids ()
1906 RemoteModel m = Config->get_remote_model();
1908 shared_ptr<RouteList> r = routes.reader ();
1910 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1911 if ( MixerOrdered == m) {
1912 long order = (*i)->order_key(N_("signal"));
1913 (*i)->set_remote_control_id( order+1 );
1914 } else if ( EditorOrdered == m) {
1915 long order = (*i)->order_key(N_("editor"));
1916 (*i)->set_remote_control_id( order+1 );
1917 } else if ( UserOrdered == m) {
1918 //do nothing ... only changes to remote id's are initiated by user
1925 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1928 uint32_t bus_id = 1;
1932 uint32_t control_id;
1934 /* count existing audio busses */
1937 shared_ptr<RouteList> r = routes.reader ();
1939 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1940 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1941 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1948 vector<string> physinputs;
1949 vector<string> physoutputs;
1951 _engine.get_physical_audio_outputs (physoutputs);
1952 _engine.get_physical_audio_inputs (physinputs);
1953 control_id = ntracks() + nbusses() + 1;
1958 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1962 if (route_by_name (bus_name) == 0) {
1966 } while (bus_id < (UINT_MAX-1));
1969 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1971 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1972 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1973 input_channels, output_channels)
1978 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1982 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1983 port = physinputs[((n+x)%n_physical_audio_inputs)];
1986 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1991 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1995 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1996 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1997 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1999 port = _master_out->input (x%_master_out->n_inputs())->name();
2003 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2008 bus->set_remote_control_id (control_id);
2011 ret.push_back (bus);
2015 catch (failed_constructor &err) {
2016 error << _("Session: could not create new audio route.") << endmsg;
2020 catch (AudioEngine::PortRegistrationFailure& pfe) {
2021 error << pfe.what() << endmsg;
2031 add_routes (ret, true);
2039 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2043 uint32_t control_id;
2046 if (!tree.read (template_path.c_str())) {
2050 XMLNode* node = tree.root();
2052 control_id = ntracks() + nbusses() + 1;
2056 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2058 std::string node_name = IO::name_from_state (*node_copy.children().front());
2060 if (route_by_name (node_name) != 0) {
2062 /* generate a new name by adding a number to the end of the template name */
2064 uint32_t number = 1;
2067 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2071 if (route_by_name (name) == 0) {
2075 } while (number < UINT_MAX);
2077 if (number == UINT_MAX) {
2078 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2082 IO::set_name_in_state (*node_copy.children().front(), name);
2085 Track::zero_diskstream_id_in_xml (node_copy);
2088 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2091 error << _("Session: cannot create track/bus from template description") << endmsg;
2095 if (boost::dynamic_pointer_cast<Track>(route)) {
2096 /* force input/output change signals so that the new diskstream
2097 picks up the configuration of the route. During session
2098 loading this normally happens in a different way.
2100 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2101 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2104 route->set_remote_control_id (control_id);
2107 ret.push_back (route);
2110 catch (failed_constructor &err) {
2111 error << _("Session: could not create new route from template") << endmsg;
2115 catch (AudioEngine::PortRegistrationFailure& pfe) {
2116 error << pfe.what() << endmsg;
2125 add_routes (ret, true);
2131 boost::shared_ptr<Route>
2132 Session::new_video_track (string name)
2134 uint32_t control_id = ntracks() + nbusses() + 1;
2135 shared_ptr<Route> new_route (
2136 new Route ( *this, name, -1, -1, -1, -1, Route::Flag(0), ARDOUR::DataType::NIL));
2137 new_route->set_remote_control_id (control_id);
2140 rl.push_back (new_route);
2142 RCUWriter<RouteList> writer (routes);
2143 shared_ptr<RouteList> r = writer.get_copy ();
2144 r->insert (r->end(), rl.begin(), rl.end());
2145 resort_routes_using (r);
2151 Session::add_routes (RouteList& new_routes, bool save)
2154 RCUWriter<RouteList> writer (routes);
2155 shared_ptr<RouteList> r = writer.get_copy ();
2156 r->insert (r->end(), new_routes.begin(), new_routes.end());
2157 resort_routes_using (r);
2160 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2162 boost::weak_ptr<Route> wpr (*x);
2164 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2165 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2166 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2167 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2169 if ((*x)->master()) {
2173 if ((*x)->control()) {
2174 _control_out = (*x);
2178 if (_control_out && IO::connecting_legal) {
2180 vector<string> cports;
2181 uint32_t ni = _control_out->n_inputs();
2184 for (n = 0; n < ni; ++n) {
2185 cports.push_back (_control_out->input(n)->name());
2188 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2189 (*x)->set_control_outs (cports);
2196 save_state (_current_snapshot_name);
2199 RouteAdded (new_routes); /* EMIT SIGNAL */
2203 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2205 /* need to do this in case we're rolling at the time, to prevent false underruns */
2206 dstream->do_refill_with_alloc ();
2208 dstream->set_block_size (current_block_size);
2211 RCUWriter<DiskstreamList> writer (diskstreams);
2212 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2213 ds->push_back (dstream);
2214 /* writer goes out of scope, copies ds back to main */
2217 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2218 boost::weak_ptr<Diskstream> (dstream)));
2219 /* this will connect to future changes, and check the current length */
2220 diskstream_playlist_changed (dstream);
2222 dstream->prepare ();
2226 Session::remove_route (shared_ptr<Route> route)
2229 RCUWriter<RouteList> writer (routes);
2230 shared_ptr<RouteList> rs = writer.get_copy ();
2234 /* deleting the master out seems like a dumb
2235 idea, but its more of a UI policy issue
2239 if (route == _master_out) {
2240 _master_out = shared_ptr<Route> ();
2243 if (route == _control_out) {
2244 _control_out = shared_ptr<Route> ();
2246 /* cancel control outs for all routes */
2248 vector<string> empty;
2250 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2251 (*r)->set_control_outs (empty);
2255 update_route_solo_state ();
2257 /* writer goes out of scope, forces route list update */
2260 // FIXME: audio specific
2262 boost::shared_ptr<AudioDiskstream> ds;
2264 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2265 ds = at->audio_diskstream();
2271 RCUWriter<DiskstreamList> dsl (diskstreams);
2272 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2276 diskstreams.flush ();
2279 find_current_end ();
2281 // We need to disconnect the routes inputs and outputs
2283 route->disconnect_inputs (0);
2284 route->disconnect_outputs (0);
2286 update_latency_compensation (false, false);
2289 /* get rid of it from the dead wood collection in the route list manager */
2291 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2295 /* try to cause everyone to drop their references */
2297 route->drop_references ();
2299 sync_order_keys (N_("session"));
2301 /* save the new state of the world */
2303 if (save_state (_current_snapshot_name)) {
2304 save_history (_current_snapshot_name);
2309 Session::route_mute_changed (void* src)
2315 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2317 if (solo_update_disabled) {
2323 boost::shared_ptr<Route> route = wpr.lock ();
2326 /* should not happen */
2327 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2331 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2333 shared_ptr<RouteList> r = routes.reader ();
2335 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2341 /* don't mess with busses */
2343 if (boost::dynamic_pointer_cast<AudioTrack>(*i) == 0) {
2349 /* don't mess with tracks */
2351 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
2356 if ((*i) != route &&
2357 ((*i)->mix_group () == 0 ||
2358 (*i)->mix_group () != route->mix_group () ||
2359 !route->mix_group ()->is_active())) {
2361 if ((*i)->soloed()) {
2363 /* if its already soloed, and solo latching is enabled,
2364 then leave it as it is.
2367 if (Config->get_solo_latched()) {
2374 solo_update_disabled = true;
2375 (*i)->set_solo (false, src);
2376 solo_update_disabled = false;
2380 bool something_soloed = false;
2381 bool same_thing_soloed = false;
2382 bool signal = false;
2384 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2385 if ((*i)->soloed()) {
2386 something_soloed = true;
2387 if (dynamic_cast<AudioTrack*>((*i).get())) {
2389 same_thing_soloed = true;
2394 same_thing_soloed = true;
2402 if (something_soloed != currently_soloing) {
2404 currently_soloing = something_soloed;
2407 modify_solo_mute (is_track, same_thing_soloed);
2410 SoloActive (currently_soloing); /* EMIT SIGNAL */
2413 SoloChanged (); /* EMIT SIGNAL */
2419 Session::update_route_solo_state ()
2422 bool is_track = false;
2423 bool signal = false;
2425 /* this is where we actually implement solo by changing
2426 the solo mute setting of each track.
2429 shared_ptr<RouteList> r = routes.reader ();
2431 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2432 if ((*i)->soloed()) {
2434 if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2441 if (mute != currently_soloing) {
2443 currently_soloing = mute;
2446 if (!is_track && !mute) {
2448 /* nothing is soloed */
2450 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2451 (*i)->set_solo_mute (false);
2461 modify_solo_mute (is_track, mute);
2464 SoloActive (currently_soloing);
2469 Session::modify_solo_mute (bool is_track, bool mute)
2471 shared_ptr<RouteList> r = routes.reader ();
2473 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2477 /* only alter track solo mute */
2479 if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2480 if ((*i)->soloed()) {
2481 (*i)->set_solo_mute (!mute);
2483 (*i)->set_solo_mute (mute);
2489 /* only alter bus solo mute */
2491 if (!boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2493 if ((*i)->soloed()) {
2495 (*i)->set_solo_mute (false);
2499 /* don't mute master or control outs
2500 in response to another bus solo
2503 if ((*i) != _master_out &&
2504 (*i) != _control_out) {
2505 (*i)->set_solo_mute (mute);
2516 Session::catch_up_on_solo ()
2518 /* this is called after set_state() to catch the full solo
2519 state, which can't be correctly determined on a per-route
2520 basis, but needs the global overview that only the session
2523 update_route_solo_state();
2527 Session::catch_up_on_solo_mute_override ()
2529 if (Config->get_solo_model() != InverseMute) {
2533 /* this is called whenever the param solo-mute-override is
2536 shared_ptr<RouteList> r = routes.reader ();
2538 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2539 (*i)->catch_up_on_solo_mute_override ();
2544 Session::route_by_name (string name)
2546 shared_ptr<RouteList> r = routes.reader ();
2548 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2549 if ((*i)->name() == name) {
2554 return shared_ptr<Route> ((Route*) 0);
2558 Session::route_by_id (PBD::ID id)
2560 shared_ptr<RouteList> r = routes.reader ();
2562 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2563 if ((*i)->id() == id) {
2568 return shared_ptr<Route> ((Route*) 0);
2572 Session::route_by_remote_id (uint32_t id)
2574 shared_ptr<RouteList> r = routes.reader ();
2576 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2577 if ((*i)->remote_control_id() == id) {
2582 return shared_ptr<Route> ((Route*) 0);
2586 Session::find_current_end ()
2588 if (_state_of_the_state & Loading) {
2592 nframes_t max = get_maximum_extent ();
2594 if (max > end_location->end()) {
2595 end_location->set_end (max);
2597 DurationChanged(); /* EMIT SIGNAL */
2602 Session::get_maximum_extent () const
2607 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2609 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2610 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2612 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2613 if ((me = pl->get_maximum_extent()) > max) {
2621 boost::shared_ptr<Diskstream>
2622 Session::diskstream_by_name (string name)
2624 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2626 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2627 if ((*i)->name() == name) {
2632 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2635 boost::shared_ptr<Diskstream>
2636 Session::diskstream_by_id (const PBD::ID& id)
2638 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2640 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2641 if ((*i)->id() == id) {
2646 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2649 /* AudioRegion management */
2652 Session::new_region_name (string old)
2654 string::size_type last_period;
2656 string::size_type len = old.length() + 64;
2659 if ((last_period = old.find_last_of ('.')) == string::npos) {
2661 /* no period present - add one explicitly */
2664 last_period = old.length() - 1;
2669 number = atoi (old.substr (last_period+1).c_str());
2673 while (number < (UINT_MAX-1)) {
2675 AudioRegionList::const_iterator i;
2680 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2683 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2684 if (i->second->name() == sbuf) {
2689 if (i == audio_regions.end()) {
2694 if (number != (UINT_MAX-1)) {
2698 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2703 Session::region_name (string& result, string base, bool newlevel)
2710 Glib::Mutex::Lock lm (region_lock);
2712 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2721 string::size_type pos;
2723 pos = base.find_last_of ('.');
2725 /* pos may be npos, but then we just use entire base */
2727 subbase = base.substr (0, pos);
2732 Glib::Mutex::Lock lm (region_lock);
2734 map<string,uint32_t>::iterator x;
2738 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2740 region_name_map[subbase] = 1;
2743 snprintf (buf, sizeof (buf), ".%d", x->second);
2753 Session::add_region (boost::shared_ptr<Region> region)
2755 vector<boost::shared_ptr<Region> > v;
2756 v.push_back (region);
2761 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2763 boost::shared_ptr<AudioRegion> ar;
2764 boost::shared_ptr<AudioRegion> oar;
2768 Glib::Mutex::Lock lm (region_lock);
2770 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2772 boost::shared_ptr<Region> region = *ii;
2776 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2778 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2780 AudioRegionList::iterator x;
2782 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2784 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2786 if (ar->region_list_equivalent (oar)) {
2791 if (x == audio_regions.end()) {
2793 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2795 entry.first = region->id();
2798 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2809 fatal << _("programming error: ")
2810 << X_("unknown region type passed to Session::add_region()")
2818 /* mark dirty because something has changed even if we didn't
2819 add the region to the region list.
2826 vector<boost::weak_ptr<AudioRegion> > v;
2827 boost::shared_ptr<AudioRegion> first_ar;
2829 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2831 boost::shared_ptr<Region> region = *ii;
2832 boost::shared_ptr<AudioRegion> ar;
2836 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2838 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2846 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2847 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2849 update_region_name_map (region);
2853 AudioRegionsAdded (v); /* EMIT SIGNAL */
2859 Session::update_region_name_map (boost::shared_ptr<Region> region)
2861 string::size_type last_period = region->name().find_last_of ('.');
2863 if (last_period != string::npos && last_period < region->name().length() - 1) {
2865 string base = region->name().substr (0, last_period);
2866 string number = region->name().substr (last_period+1);
2867 map<string,uint32_t>::iterator x;
2869 /* note that if there is no number, we get zero from atoi,
2873 region_name_map[base] = atoi (number);
2878 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2880 boost::shared_ptr<Region> region (weak_region.lock ());
2886 if (what_changed & Region::HiddenChanged) {
2887 /* relay hidden changes */
2888 RegionHiddenChange (region);
2891 if (what_changed & NameChanged) {
2892 update_region_name_map (region);
2897 Session::remove_region (boost::weak_ptr<Region> weak_region)
2899 AudioRegionList::iterator i;
2900 boost::shared_ptr<Region> region (weak_region.lock ());
2906 boost::shared_ptr<AudioRegion> ar;
2907 bool removed = false;
2910 Glib::Mutex::Lock lm (region_lock);
2912 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2913 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2914 audio_regions.erase (i);
2920 fatal << _("programming error: ")
2921 << X_("unknown region type passed to Session::remove_region()")
2927 /* mark dirty because something has changed even if we didn't
2928 remove the region from the region list.
2934 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2938 boost::shared_ptr<AudioRegion>
2939 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2941 AudioRegionList::iterator i;
2942 boost::shared_ptr<AudioRegion> region;
2943 Glib::Mutex::Lock lm (region_lock);
2945 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2949 if (region->whole_file()) {
2951 if (child->source_equivalent (region)) {
2957 return boost::shared_ptr<AudioRegion> ();
2961 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2963 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2964 (*i)->get_region_list_equivalent_regions (region, result);
2968 Session::destroy_region (boost::shared_ptr<Region> region)
2970 vector<boost::shared_ptr<Source> > srcs;
2973 boost::shared_ptr<AudioRegion> aregion;
2975 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2979 if (aregion->playlist()) {
2980 aregion->playlist()->destroy_region (region);
2983 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2984 srcs.push_back (aregion->source (n));
2988 region->drop_references ();
2990 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2992 if (!(*i)->used()) {
2993 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2996 (afs)->mark_for_remove ();
2999 (*i)->drop_references ();
3001 cerr << "source was not used by any playlist\n";
3009 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3011 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3012 destroy_region (*i);
3018 Session::remove_last_capture ()
3020 list<boost::shared_ptr<Region> > r;
3022 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3024 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3025 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3028 r.insert (r.end(), l.begin(), l.end());
3033 destroy_regions (r);
3035 save_state (_current_snapshot_name);
3041 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3047 /* Source Management */
3050 Session::add_source (boost::shared_ptr<Source> source)
3052 boost::shared_ptr<AudioFileSource> afs;
3054 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3056 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3057 pair<AudioSourceList::iterator,bool> result;
3059 entry.first = source->id();
3063 Glib::Mutex::Lock lm (audio_source_lock);
3064 result = audio_sources.insert (entry);
3067 if (result.second) {
3068 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3072 if (Config->get_auto_analyse_audio()) {
3073 Analyser::queue_source_for_analysis (source, false);
3079 Session::remove_source (boost::weak_ptr<Source> src)
3081 AudioSourceList::iterator i;
3082 boost::shared_ptr<Source> source = src.lock();
3089 Glib::Mutex::Lock lm (audio_source_lock);
3091 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3092 audio_sources.erase (i);
3096 if (!_state_of_the_state & InCleanup) {
3098 /* save state so we don't end up with a session file
3099 referring to non-existent sources.
3102 save_state (_current_snapshot_name);
3106 boost::shared_ptr<Source>
3107 Session::source_by_id (const PBD::ID& id)
3109 Glib::Mutex::Lock lm (audio_source_lock);
3110 AudioSourceList::iterator i;
3111 boost::shared_ptr<Source> source;
3113 if ((i = audio_sources.find (id)) != audio_sources.end()) {
3117 /* XXX search MIDI or other searches here */
3123 boost::shared_ptr<Source>
3124 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3126 Glib::Mutex::Lock lm (audio_source_lock);
3128 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3129 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3131 if (afs && afs->path() == path && chn == afs->channel()) {
3136 return boost::shared_ptr<Source>();
3140 Session::peak_path (Glib::ustring base) const
3142 return Glib::build_filename(peak_dir (), base + ".peak");
3146 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3149 string old_basename = PBD::basename_nosuffix (oldname);
3150 string new_legalized = legalize_for_path (newname);
3152 /* note: we know (or assume) the old path is already valid */
3156 /* destructive file sources have a name of the form:
3158 /path/to/Tnnnn-NAME(%[LR])?.wav
3160 the task here is to replace NAME with the new name.
3163 /* find last slash */
3167 string::size_type slash;
3168 string::size_type dash;
3170 if ((slash = path.find_last_of ('/')) == string::npos) {
3174 dir = path.substr (0, slash+1);
3176 /* '-' is not a legal character for the NAME part of the path */
3178 if ((dash = path.find_last_of ('-')) == string::npos) {
3182 prefix = path.substr (slash+1, dash-(slash+1));
3187 path += new_legalized;
3188 path += ".wav"; /* XXX gag me with a spoon */
3192 /* non-destructive file sources have a name of the form:
3194 /path/to/NAME-nnnnn(%[LR])?.wav
3196 the task here is to replace NAME with the new name.
3201 string::size_type slash;
3202 string::size_type dash;
3203 string::size_type postfix;
3205 /* find last slash */
3207 if ((slash = path.find_last_of ('/')) == string::npos) {
3211 dir = path.substr (0, slash+1);
3213 /* '-' is not a legal character for the NAME part of the path */
3215 if ((dash = path.find_last_of ('-')) == string::npos) {
3219 suffix = path.substr (dash+1);
3221 // Suffix is now everything after the dash. Now we need to eliminate
3222 // the nnnnn part, which is done by either finding a '%' or a '.'
3224 postfix = suffix.find_last_of ("%");
3225 if (postfix == string::npos) {
3226 postfix = suffix.find_last_of ('.');
3229 if (postfix != string::npos) {
3230 suffix = suffix.substr (postfix);
3232 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3236 const uint32_t limit = 10000;
3237 char buf[PATH_MAX+1];
3239 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3241 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3243 if (access (buf, F_OK) != 0) {
3251 error << "FATAL ERROR! Could not find a " << endl;
3260 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3264 char buf[PATH_MAX+1];
3265 const uint32_t limit = 10000;
3269 legalized = legalize_for_path (name);
3271 /* find a "version" of the file name that doesn't exist in
3272 any of the possible directories.
3275 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3277 vector<space_and_path>::iterator i;
3278 uint32_t existing = 0;
3280 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3284 spath += sound_dir (false);
3288 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3289 } else if (nchan == 2) {
3291 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3293 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3295 } else if (nchan < 26) {
3296 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3298 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3307 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3308 } else if (nchan == 2) {
3310 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3312 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3314 } else if (nchan < 26) {
3315 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3317 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3321 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3327 if (existing == 0) {
3332 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3334 throw failed_constructor();
3338 /* we now have a unique name for the file, but figure out where to
3344 spath = discover_best_sound_dir ();
3347 string::size_type pos = foo.find_last_of ('/');
3349 if (pos == string::npos) {
3352 spath += foo.substr (pos + 1);
3358 boost::shared_ptr<AudioFileSource>
3359 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3361 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3362 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3365 /* Playlist management */
3367 boost::shared_ptr<Playlist>
3368 Session::playlist_by_name (string name)
3370 Glib::Mutex::Lock lm (playlist_lock);
3371 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3372 if ((*i)->name() == name) {
3376 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3377 if ((*i)->name() == name) {
3382 return boost::shared_ptr<Playlist>();
3386 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3388 if (playlist->hidden()) {
3393 Glib::Mutex::Lock lm (playlist_lock);
3394 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3395 playlists.insert (playlists.begin(), playlist);
3396 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3397 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3403 PlaylistAdded (playlist); /* EMIT SIGNAL */
3407 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3410 Glib::Mutex::Lock lm (playlist_lock);
3411 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3414 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3421 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3423 boost::shared_ptr<Playlist> pl(wpl.lock());
3429 PlaylistList::iterator x;
3432 /* its not supposed to be visible */
3437 Glib::Mutex::Lock lm (playlist_lock);
3441 unused_playlists.insert (pl);
3443 if ((x = playlists.find (pl)) != playlists.end()) {
3444 playlists.erase (x);
3450 playlists.insert (pl);
3452 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3453 unused_playlists.erase (x);
3460 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3462 if (_state_of_the_state & Deletion) {
3466 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3473 Glib::Mutex::Lock lm (playlist_lock);
3475 PlaylistList::iterator i;
3477 i = find (playlists.begin(), playlists.end(), playlist);
3478 if (i != playlists.end()) {
3479 playlists.erase (i);
3482 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3483 if (i != unused_playlists.end()) {
3484 unused_playlists.erase (i);
3491 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3495 Session::set_audition (boost::shared_ptr<Region> r)
3497 pending_audition_region = r;
3498 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3499 schedule_butler_transport_work ();
3503 Session::audition_playlist ()
3505 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3506 ev->region.reset ();
3511 Session::non_realtime_set_audition ()
3513 if (!pending_audition_region) {
3514 auditioner->audition_current_playlist ();
3516 auditioner->audition_region (pending_audition_region);
3517 pending_audition_region.reset ();
3519 AuditionActive (true); /* EMIT SIGNAL */
3523 Session::audition_region (boost::shared_ptr<Region> r)
3525 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3531 Session::cancel_audition ()
3533 if (auditioner->active()) {
3534 auditioner->cancel_audition ();
3535 AuditionActive (false); /* EMIT SIGNAL */
3540 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3542 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3546 Session::remove_empty_sounds ()
3548 PathScanner scanner;
3550 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3552 Glib::Mutex::Lock lm (audio_source_lock);
3554 regex_t compiled_tape_track_pattern;
3557 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3561 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3563 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3567 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3569 /* never remove files that appear to be a tape track */
3571 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3576 if (AudioFileSource::is_empty (*this, **i)) {
3578 unlink ((*i)->c_str());
3580 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3581 unlink (peakpath.c_str());
3587 delete possible_audiofiles;
3591 Session::is_auditioning () const
3593 /* can be called before we have an auditioner object */
3595 return auditioner->active();
3602 Session::set_all_solo (bool yn)
3604 shared_ptr<RouteList> r = routes.reader ();
3606 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3607 if (!(*i)->hidden()) {
3608 (*i)->set_solo (yn, this);
3616 Session::set_all_mute (bool yn)
3618 shared_ptr<RouteList> r = routes.reader ();
3620 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3621 if (!(*i)->hidden()) {
3622 (*i)->set_mute (yn, this);
3630 Session::n_diskstreams () const
3634 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3636 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3637 if (!(*i)->hidden()) {
3645 Session::graph_reordered ()
3647 /* don't do this stuff if we are setting up connections
3648 from a set_state() call or creating new tracks.
3651 if (_state_of_the_state & InitialConnecting) {
3655 /* every track/bus asked for this to be handled but it was deferred because
3656 we were connecting. do it now.
3659 request_input_change_handling ();
3663 /* force all diskstreams to update their capture offset values to
3664 reflect any changes in latencies within the graph.
3667 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3669 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3670 (*i)->set_capture_offset ();
3675 Session::record_disenable_all ()
3677 record_enable_change_all (false);
3681 Session::record_enable_all ()
3683 record_enable_change_all (true);
3687 Session::record_enable_change_all (bool yn)
3689 shared_ptr<RouteList> r = routes.reader ();
3691 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3694 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3695 at->set_record_enable (yn, this);
3699 /* since we don't keep rec-enable state, don't mark session dirty */
3703 Session::add_redirect (Redirect* redirect)
3707 PortInsert* port_insert;
3708 PluginInsert* plugin_insert;
3710 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3711 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3712 _port_inserts.insert (_port_inserts.begin(), port_insert);
3713 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3714 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3716 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3719 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3720 _sends.insert (_sends.begin(), send);
3722 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3726 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3732 Session::remove_redirect (Redirect* redirect)
3736 PortInsert* port_insert;
3737 PluginInsert* plugin_insert;
3739 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3740 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3741 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3742 if (x != _port_inserts.end()) {
3743 insert_bitset[port_insert->bit_slot()] = false;
3744 _port_inserts.erase (x);
3746 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3747 _plugin_inserts.remove (plugin_insert);
3749 fatal << string_compose (_("programming error: %1"),
3750 X_("unknown type of Insert deleted!"))
3754 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3755 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3756 if (x != _sends.end()) {
3757 send_bitset[send->bit_slot()] = false;
3761 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3769 Session::available_capture_duration ()
3771 float sample_bytes_on_disk = 4.0; // keep gcc happy
3773 switch (Config->get_native_file_data_format()) {
3775 sample_bytes_on_disk = 4.0;
3779 sample_bytes_on_disk = 3.0;
3783 sample_bytes_on_disk = 2.0;
3787 /* impossible, but keep some gcc versions happy */
3788 fatal << string_compose (_("programming error: %1"),
3789 X_("illegal native file data format"))
3794 double scale = 4096.0 / sample_bytes_on_disk;
3796 if (_total_free_4k_blocks * scale > (double) max_frames) {
3800 return (nframes_t) floor (_total_free_4k_blocks * scale);
3804 Session::add_connection (ARDOUR::Connection* connection)
3807 Glib::Mutex::Lock guard (connection_lock);
3808 _connections.push_back (connection);
3811 ConnectionAdded (connection); /* EMIT SIGNAL */
3817 Session::remove_connection (ARDOUR::Connection* connection)
3819 bool removed = false;
3822 Glib::Mutex::Lock guard (connection_lock);
3823 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3825 if (i != _connections.end()) {
3826 _connections.erase (i);
3832 ConnectionRemoved (connection); /* EMIT SIGNAL */
3838 ARDOUR::Connection *
3839 Session::connection_by_name (string name) const
3841 Glib::Mutex::Lock lm (connection_lock);
3843 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3844 if ((*i)->name() == name) {
3853 Session::tempo_map_changed (Change ignored)
3857 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3858 (*i)->update_after_tempo_map_change ();
3861 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3862 (*i)->update_after_tempo_map_change ();
3869 Session::ensure_passthru_buffers (uint32_t howmany)
3871 if (current_block_size == 0) {
3875 while (howmany > _passthru_buffers.size()) {
3877 #ifdef NO_POSIX_MEMALIGN
3878 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3880 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3881 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3882 current_block_size, sizeof (Sample), strerror (errno))
3887 _passthru_buffers.push_back (p);
3891 #ifdef NO_POSIX_MEMALIGN
3892 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3894 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3895 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3896 current_block_size, sizeof (Sample), strerror (errno))
3901 memset (p, 0, sizeof (Sample) * current_block_size);
3902 _silent_buffers.push_back (p);
3906 #ifdef NO_POSIX_MEMALIGN
3907 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3909 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3911 memset (p, 0, sizeof (Sample) * current_block_size);
3912 _send_buffers.push_back (p);
3915 allocate_pan_automation_buffers (current_block_size, howmany, false);
3919 Session::next_insert_id ()
3921 /* this doesn't really loop forever. just think about it */
3924 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3925 if (!insert_bitset[n]) {
3926 insert_bitset[n] = true;
3932 /* none available, so resize and try again */
3934 insert_bitset.resize (insert_bitset.size() + 16, false);
3939 Session::next_send_id ()
3941 /* this doesn't really loop forever. just think about it */
3944 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3945 if (!send_bitset[n]) {
3946 send_bitset[n] = true;
3952 /* none available, so resize and try again */
3954 send_bitset.resize (send_bitset.size() + 16, false);
3959 Session::mark_send_id (uint32_t id)
3961 if (id >= send_bitset.size()) {
3962 send_bitset.resize (id+16, false);
3964 if (send_bitset[id]) {
3965 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3967 send_bitset[id] = true;
3971 Session::mark_insert_id (uint32_t id)
3973 if (id >= insert_bitset.size()) {
3974 insert_bitset.resize (id+16, false);
3976 if (insert_bitset[id]) {
3977 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3979 insert_bitset[id] = true;
3982 /* Named Selection management */
3985 Session::named_selection_by_name (string name)
3987 Glib::Mutex::Lock lm (named_selection_lock);
3988 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3989 if ((*i)->name == name) {
3997 Session::add_named_selection (NamedSelection* named_selection)
4000 Glib::Mutex::Lock lm (named_selection_lock);
4001 named_selections.insert (named_selections.begin(), named_selection);
4004 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4010 NamedSelectionAdded (); /* EMIT SIGNAL */
4014 Session::remove_named_selection (NamedSelection* named_selection)
4016 bool removed = false;
4019 Glib::Mutex::Lock lm (named_selection_lock);
4021 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4023 if (i != named_selections.end()) {
4025 named_selections.erase (i);
4032 NamedSelectionRemoved (); /* EMIT SIGNAL */
4037 Session::reset_native_file_format ()
4039 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4041 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4042 (*i)->reset_write_sources (false);
4047 Session::route_name_unique (string n) const
4049 shared_ptr<RouteList> r = routes.reader ();
4051 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4052 if ((*i)->name() == n) {
4061 Session::n_playlists () const
4063 Glib::Mutex::Lock lm (playlist_lock);
4064 return playlists.size();
4068 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4070 if (!force && howmany <= _npan_buffers) {
4074 if (_pan_automation_buffer) {
4076 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4077 delete [] _pan_automation_buffer[i];
4080 delete [] _pan_automation_buffer;
4083 _pan_automation_buffer = new pan_t*[howmany];
4085 for (uint32_t i = 0; i < howmany; ++i) {
4086 _pan_automation_buffer[i] = new pan_t[nframes];
4089 _npan_buffers = howmany;
4093 Session::freeze (InterThreadInfo& itt)
4095 shared_ptr<RouteList> r = routes.reader ();
4097 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4101 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4102 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4112 boost::shared_ptr<Region>
4113 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
4114 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt, bool enable_processing)
4116 boost::shared_ptr<Region> result;
4117 boost::shared_ptr<Playlist> playlist;
4118 boost::shared_ptr<AudioFileSource> fsource;
4120 char buf[PATH_MAX+1];
4124 nframes_t this_chunk;
4126 nframes_t len = end - start;
4127 vector<Sample*> buffers;
4130 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4131 end, start) << endmsg;
4135 // any bigger than this seems to cause stack overflows in called functions
4136 const nframes_t chunk_size = (128 * 1024)/4;
4138 // block all process callback handling
4140 block_processing ();
4142 /* call tree *MUST* hold route_lock */
4144 if ((playlist = track.diskstream()->playlist()) == 0) {
4148 /* external redirects will be a problem */
4150 if (track.has_external_redirects()) {
4154 nchans = track.audio_diskstream()->n_channels();
4156 dir = discover_best_sound_dir ();
4158 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
4160 for (x = 0; x < 99999; ++x) {
4161 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4162 if (access (buf, F_OK) != 0) {
4168 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4173 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
4176 catch (failed_constructor& err) {
4177 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4181 srcs.push_back (fsource);
4184 /* XXX need to flush all redirects */
4189 /* create a set of reasonably-sized buffers */
4191 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4193 #ifdef NO_POSIX_MEMALIGN
4194 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4196 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4198 buffers.push_back (b);
4201 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4202 (*src)->prepare_for_peakfile_writes ();
4205 while (to_do && !itt.cancel) {
4207 this_chunk = min (to_do, chunk_size);
4209 if (track.export_stuff (buffers, nchans, start, this_chunk, enable_processing)) {
4214 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4215 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4218 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4224 start += this_chunk;
4225 to_do -= this_chunk;
4227 itt.progress = (float) (1.0 - ((double) to_do / len));
4236 xnow = localtime (&now);
4238 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4239 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4242 afs->update_header (position, *xnow, now);
4243 afs->flush_header ();
4247 /* construct a region to represent the bounced material */
4249 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4250 region_name_from_path (srcs.front()->name(), true));
4255 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4256 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4259 afs->mark_for_remove ();
4262 (*src)->drop_references ();
4266 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4267 (*src)->done_with_peakfile_writes ();
4271 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4275 unblock_processing ();
4283 Session::get_silent_buffers (uint32_t howmany)
4285 if (howmany > _silent_buffers.size()) {
4287 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4288 howmany, _silent_buffers.size()) << endmsg;
4290 if (howmany > 1000) {
4291 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4295 while (howmany > _silent_buffers.size()) {
4298 #ifdef NO_POSIX_MEMALIGN
4299 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4301 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
4302 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4303 current_block_size, sizeof (Sample), strerror (errno))
4308 _silent_buffers.push_back (p);
4312 for (uint32_t i = 0; i < howmany; ++i) {
4313 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4316 return _silent_buffers;
4320 Session::ntracks () const
4323 shared_ptr<RouteList> r = routes.reader ();
4325 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4326 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4335 Session::nbusses () const
4338 shared_ptr<RouteList> r = routes.reader ();
4340 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4341 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4350 Session::add_automation_list(AutomationList *al)
4352 automation_lists[al->id()] = al;
4356 Session::compute_initial_length ()
4358 return _engine.frame_rate() * 60 * 5;
4362 Session::sync_order_keys (const char* base)
4364 if (!Config->get_sync_all_route_ordering()) {
4365 /* leave order keys as they are */
4369 boost::shared_ptr<RouteList> r = routes.reader ();
4371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4372 (*i)->sync_order_keys (base);
4375 Route::SyncOrderKeys (base); // EMIT SIGNAL