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 string first_physical_output;
682 /* we don't want to run execute this again */
684 BootMessage (_("Set block size and sample rate"));
686 set_block_size (_engine.frames_per_cycle());
687 set_frame_rate (_engine.frame_rate());
689 BootMessage (_("Using configuration"));
691 Config->map_parameters (mem_fun (*this, &Session::config_changed));
693 /* every time we reconnect, recompute worst case output latencies */
695 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
697 if (synced_to_jack()) {
698 _engine.transport_stop ();
701 if (Config->get_jack_time_master()) {
702 _engine.transport_locate (_transport_frame);
710 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
712 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
714 /* existing state for Click */
716 if (_click_io->set_state (*child->children().front()) == 0) {
718 _clicking = Config->get_clicking ();
722 error << _("could not setup Click I/O") << endmsg;
728 /* default state for Click */
730 first_physical_output = _engine.get_nth_physical_audio_output (0);
732 if (first_physical_output.length()) {
733 if (_click_io->add_output_port (first_physical_output, this)) {
734 // relax, even though its an error
736 _clicking = Config->get_clicking ();
742 catch (failed_constructor& err) {
743 error << _("cannot setup Click I/O") << endmsg;
746 BootMessage (_("Compute I/O Latencies"));
748 set_worst_io_latencies ();
751 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
754 /* Create a set of Connection objects that map
755 to the physical outputs currently available
758 BootMessage (_("Set up standard connections"));
762 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
764 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
766 Connection* c = new OutputConnection (buf, true);
769 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
774 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
776 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
778 Connection* c = new InputConnection (buf, true);
781 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
788 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
790 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
792 Connection* c = new OutputConnection (buf, true);
796 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
797 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
802 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
804 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
806 Connection* c = new InputConnection (buf, true);
810 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
811 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
820 /* create master/control ports */
825 /* force the master to ignore any later call to this */
827 if (_master_out->pending_state_node) {
828 _master_out->ports_became_legal();
831 /* no panner resets till we are through */
833 _master_out->defer_pan_reset ();
835 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
836 if (_master_out->add_input_port ("", this)) {
837 error << _("cannot setup master inputs")
843 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
844 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
845 error << _("cannot setup master outputs")
852 _master_out->allow_pan_reset ();
856 Connection* c = new OutputConnection (_("Master Out"), true);
858 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
860 c->add_connection ((int) n, _master_out->input(n)->name());
865 BootMessage (_("Setup signal flow and plugins"));
869 /* catch up on send+insert cnts */
871 BootMessage (_("Catch up with send/insert state"));
875 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
878 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
879 if (id > insert_cnt) {
887 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
890 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
898 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
900 /* hook us up to the engine */
902 BootMessage (_("Connect to engine"));
904 _engine.set_session (this);
909 BootMessage (_("OSC startup"));
911 osc->set_session (*this);
917 Session::hookup_io ()
919 /* stop graph reordering notifications from
920 causing resorts, etc.
923 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
926 if (auditioner == 0) {
928 /* we delay creating the auditioner till now because
929 it makes its own connections to ports.
930 the engine has to be running for this to work.
934 auditioner.reset (new Auditioner (*this));
937 catch (failed_constructor& err) {
938 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
942 /* Tell all IO objects to create their ports */
948 vector<string> cports;
950 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
951 if (_control_out->add_input_port ("", this)) {
952 error << _("cannot setup control inputs")
958 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
959 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
960 error << _("cannot set up master outputs")
968 uint32_t ni = _control_out->n_inputs();
970 for (n = 0; n < ni; ++n) {
971 cports.push_back (_control_out->input(n)->name());
974 boost::shared_ptr<RouteList> r = routes.reader ();
976 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
977 (*x)->set_control_outs (cports);
981 /* Tell all IO objects to connect themselves together */
983 IO::enable_connecting ();
985 /* Now reset all panners */
987 IO::reset_panners ();
989 /* Anyone who cares about input state, wake up and do something */
991 IOConnectionsComplete (); /* EMIT SIGNAL */
993 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
996 /* now handle the whole enchilada as if it was one
1002 /* update mixer solo state */
1008 Session::playlist_length_changed ()
1010 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1011 if larger. if the playlist used to be the longest playlist,
1012 and its now shorter, we have to decrease end_location->end(). hence,
1013 we have to iterate over all diskstreams and check the
1014 playlists currently in use.
1016 find_current_end ();
1020 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1022 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1029 boost::shared_ptr<Playlist> playlist;
1031 if ((playlist = dstream->playlist()) != 0) {
1032 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1035 /* see comment in playlist_length_changed () */
1036 find_current_end ();
1040 Session::record_enabling_legal () const
1042 /* this used to be in here, but survey says.... we don't need to restrict it */
1043 // if (record_status() == Recording) {
1047 if (Config->get_all_safe()) {
1054 Session::reset_input_monitor_state ()
1056 if (transport_rolling()) {
1058 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1060 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1061 if ((*i)->record_enabled ()) {
1062 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1063 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1067 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1069 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1070 if ((*i)->record_enabled ()) {
1071 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1072 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1079 Session::auto_punch_start_changed (Location* location)
1081 replace_event (Event::PunchIn, location->start());
1083 if (get_record_enabled() && Config->get_punch_in()) {
1084 /* capture start has been changed, so save new pending state */
1085 save_state ("", true);
1090 Session::auto_punch_end_changed (Location* location)
1092 nframes_t when_to_stop = location->end();
1093 // when_to_stop += _worst_output_latency + _worst_input_latency;
1094 replace_event (Event::PunchOut, when_to_stop);
1098 Session::auto_punch_changed (Location* location)
1100 nframes_t when_to_stop = location->end();
1102 replace_event (Event::PunchIn, location->start());
1103 //when_to_stop += _worst_output_latency + _worst_input_latency;
1104 replace_event (Event::PunchOut, when_to_stop);
1108 Session::auto_loop_changed (Location* location)
1110 replace_event (Event::AutoLoop, location->end(), location->start());
1112 if (transport_rolling() && play_loop) {
1114 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1116 if (_transport_frame > location->end()) {
1117 // relocate to beginning of loop
1118 clear_events (Event::LocateRoll);
1120 request_locate (location->start(), true);
1123 else if (Config->get_seamless_loop() && !loop_changing) {
1125 // schedule a locate-roll to refill the diskstreams at the
1126 // previous loop end
1127 loop_changing = true;
1129 if (location->end() > last_loopend) {
1130 clear_events (Event::LocateRoll);
1131 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1138 last_loopend = location->end();
1142 Session::set_auto_punch_location (Location* location)
1146 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1147 auto_punch_start_changed_connection.disconnect();
1148 auto_punch_end_changed_connection.disconnect();
1149 auto_punch_changed_connection.disconnect();
1150 existing->set_auto_punch (false, this);
1151 remove_event (existing->start(), Event::PunchIn);
1152 clear_events (Event::PunchOut);
1153 auto_punch_location_changed (0);
1158 if (location == 0) {
1162 if (location->end() <= location->start()) {
1163 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1167 auto_punch_start_changed_connection.disconnect();
1168 auto_punch_end_changed_connection.disconnect();
1169 auto_punch_changed_connection.disconnect();
1171 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1172 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1173 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1175 location->set_auto_punch (true, this);
1178 auto_punch_changed (location);
1180 auto_punch_location_changed (location);
1184 Session::set_auto_loop_location (Location* location)
1188 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1189 auto_loop_start_changed_connection.disconnect();
1190 auto_loop_end_changed_connection.disconnect();
1191 auto_loop_changed_connection.disconnect();
1192 existing->set_auto_loop (false, this);
1193 remove_event (existing->end(), Event::AutoLoop);
1194 auto_loop_location_changed (0);
1199 if (location == 0) {
1203 if (location->end() <= location->start()) {
1204 error << _("Session: you can't use a mark for auto loop") << endmsg;
1208 last_loopend = location->end();
1210 auto_loop_start_changed_connection.disconnect();
1211 auto_loop_end_changed_connection.disconnect();
1212 auto_loop_changed_connection.disconnect();
1214 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1215 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1216 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1218 location->set_auto_loop (true, this);
1220 /* take care of our stuff first */
1222 auto_loop_changed (location);
1224 /* now tell everyone else */
1226 auto_loop_location_changed (location);
1230 Session::locations_added (Location* ignored)
1236 Session::locations_changed ()
1238 _locations.apply (*this, &Session::handle_locations_changed);
1242 Session::handle_locations_changed (Locations::LocationList& locations)
1244 Locations::LocationList::iterator i;
1246 bool set_loop = false;
1247 bool set_punch = false;
1249 for (i = locations.begin(); i != locations.end(); ++i) {
1253 if (location->is_auto_punch()) {
1254 set_auto_punch_location (location);
1257 if (location->is_auto_loop()) {
1258 set_auto_loop_location (location);
1262 if (location->is_start()) {
1263 start_location = location;
1265 if (location->is_end()) {
1266 end_location = location;
1271 set_auto_loop_location (0);
1274 set_auto_punch_location (0);
1281 Session::enable_record ()
1283 /* XXX really atomic compare+swap here */
1284 if (g_atomic_int_get (&_record_status) != Recording) {
1285 g_atomic_int_set (&_record_status, Recording);
1286 _last_record_location = _transport_frame;
1287 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1289 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1290 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1291 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1292 if ((*i)->record_enabled ()) {
1293 (*i)->monitor_input (true);
1298 RecordStateChanged ();
1303 Session::disable_record (bool rt_context, bool force)
1307 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1309 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1310 g_atomic_int_set (&_record_status, Disabled);
1312 if (rs == Recording) {
1313 g_atomic_int_set (&_record_status, Enabled);
1317 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1319 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1320 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1322 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1323 if ((*i)->record_enabled ()) {
1324 (*i)->monitor_input (false);
1329 RecordStateChanged (); /* emit signal */
1332 remove_pending_capture_state ();
1338 Session::step_back_from_record ()
1340 /* XXX really atomic compare+swap here */
1341 if (g_atomic_int_get (&_record_status) == Recording) {
1342 g_atomic_int_set (&_record_status, Enabled);
1344 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1345 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1347 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1348 if ((*i)->record_enabled ()) {
1349 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1350 (*i)->monitor_input (false);
1358 Session::maybe_enable_record ()
1360 g_atomic_int_set (&_record_status, Enabled);
1362 /* this function is currently called from somewhere other than an RT thread.
1363 this save_state() call therefore doesn't impact anything.
1366 save_state ("", true);
1368 if (_transport_speed) {
1369 if (!Config->get_punch_in()) {
1373 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1374 RecordStateChanged (); /* EMIT SIGNAL */
1381 Session::audible_frame () const
1387 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1388 return last_stop_frame;
1391 /* the first of these two possible settings for "offset"
1392 mean that the audible frame is stationary until
1393 audio emerges from the latency compensation
1396 the second means that the audible frame is stationary
1397 until audio would emerge from a physical port
1398 in the absence of any plugin latency compensation
1401 offset = _worst_output_latency;
1403 if (offset > current_block_size) {
1404 offset -= current_block_size;
1406 /* XXX is this correct? if we have no external
1407 physical connections and everything is internal
1408 then surely this is zero? still, how
1409 likely is that anyway?
1411 offset = current_block_size;
1414 if (synced_to_jack()) {
1415 tf = _engine.transport_frame();
1417 tf = _transport_frame;
1422 if (!non_realtime_work_pending()) {
1426 /* check to see if we have passed the first guaranteed
1427 audible frame past our last stopping position. if not,
1428 the return that last stopping point because in terms
1429 of audible frames, we have not moved yet.
1432 if (_transport_speed > 0.0f) {
1434 if (!play_loop || !have_looped) {
1435 if (tf < last_stop_frame + offset) {
1436 return last_stop_frame;
1445 } else if (_transport_speed < 0.0f) {
1447 /* XXX wot? no backward looping? */
1449 if (tf > last_stop_frame - offset) {
1450 return last_stop_frame;
1462 Session::set_frame_rate (nframes_t frames_per_second)
1464 /** \fn void Session::set_frame_size(nframes_t)
1465 the AudioEngine object that calls this guarantees
1466 that it will not be called while we are also in
1467 ::process(). Its fine to do things that block
1471 _base_frame_rate = frames_per_second;
1475 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1479 // XXX we need some equivalent to this, somehow
1480 // SndFileSource::setup_standard_crossfades (frames_per_second);
1484 /* XXX need to reset/reinstantiate all LADSPA plugins */
1488 Session::set_block_size (nframes_t nframes)
1490 /* the AudioEngine guarantees
1491 that it will not be called while we are also in
1492 ::process(). It is therefore fine to do things that block
1497 vector<Sample*>::iterator i;
1500 current_block_size = nframes;
1502 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1506 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1510 _passthru_buffers.clear ();
1511 _silent_buffers.clear ();
1513 ensure_passthru_buffers (np);
1515 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1519 #ifdef NO_POSIX_MEMALIGN
1520 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1522 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1526 memset (*i, 0, sizeof (Sample) * current_block_size);
1530 if (_gain_automation_buffer) {
1531 delete [] _gain_automation_buffer;
1533 _gain_automation_buffer = new gain_t[nframes];
1535 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1537 boost::shared_ptr<RouteList> r = routes.reader ();
1539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1540 (*i)->set_block_size (nframes);
1543 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1544 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1545 (*i)->set_block_size (nframes);
1548 set_worst_io_latencies ();
1553 Session::set_default_fade (float steepness, float fade_msecs)
1556 nframes_t fade_frames;
1558 /* Don't allow fade of less 1 frame */
1560 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1567 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1571 default_fade_msecs = fade_msecs;
1572 default_fade_steepness = steepness;
1575 // jlc, WTF is this!
1576 Glib::RWLock::ReaderLock lm (route_lock);
1577 AudioRegion::set_default_fade (steepness, fade_frames);
1582 /* XXX have to do this at some point */
1583 /* foreach region using default fade, reset, then
1584 refill_all_diskstream_buffers ();
1589 struct RouteSorter {
1590 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1591 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1593 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1596 if (r1->fed_by.empty()) {
1597 if (r2->fed_by.empty()) {
1598 /* no ardour-based connections inbound to either route. just use signal order */
1599 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1601 /* r2 has connections, r1 does not; run r1 early */
1605 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1612 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1614 shared_ptr<Route> r2;
1616 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1617 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1621 /* make a copy of the existing list of routes that feed r1 */
1623 set<shared_ptr<Route> > existing = r1->fed_by;
1625 /* for each route that feeds r1, recurse, marking it as feeding
1629 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1632 /* r2 is a route that feeds r1 which somehow feeds base. mark
1633 base as being fed by r2
1636 rbase->fed_by.insert (r2);
1640 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1644 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1648 /* now recurse, so that we can mark base as being fed by
1649 all routes that feed r2
1652 trace_terminal (r2, rbase);
1659 Session::resort_routes ()
1661 /* don't do anything here with signals emitted
1662 by Routes while we are being destroyed.
1665 if (_state_of_the_state & Deletion) {
1672 RCUWriter<RouteList> writer (routes);
1673 shared_ptr<RouteList> r = writer.get_copy ();
1674 resort_routes_using (r);
1675 /* writer goes out of scope and forces update */
1680 Session::resort_routes_using (shared_ptr<RouteList> r)
1682 RouteList::iterator i, j;
1684 for (i = r->begin(); i != r->end(); ++i) {
1686 (*i)->fed_by.clear ();
1688 for (j = r->begin(); j != r->end(); ++j) {
1690 /* although routes can feed themselves, it will
1691 cause an endless recursive descent if we
1692 detect it. so don't bother checking for
1700 if ((*j)->feeds (*i)) {
1701 (*i)->fed_by.insert (*j);
1706 for (i = r->begin(); i != r->end(); ++i) {
1707 trace_terminal (*i, *i);
1713 /* don't leave dangling references to routes in Route::fed_by */
1715 for (i = r->begin(); i != r->end(); ++i) {
1716 (*i)->fed_by.clear ();
1720 cerr << "finished route resort\n";
1722 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1723 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1730 list<boost::shared_ptr<AudioTrack> >
1731 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1733 char track_name[32];
1734 uint32_t track_id = 0;
1736 uint32_t channels_used = 0;
1738 RouteList new_routes;
1739 list<boost::shared_ptr<AudioTrack> > ret;
1740 uint32_t control_id;
1742 /* count existing audio tracks */
1745 shared_ptr<RouteList> r = routes.reader ();
1747 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1748 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1749 if (!(*i)->hidden()) {
1751 channels_used += (*i)->n_inputs();
1757 vector<string> physinputs;
1758 vector<string> physoutputs;
1759 uint32_t nphysical_in;
1760 uint32_t nphysical_out;
1762 _engine.get_physical_audio_outputs (physoutputs);
1763 _engine.get_physical_audio_inputs (physinputs);
1764 control_id = ntracks() + nbusses() + 1;
1768 /* check for duplicate route names, since we might have pre-existing
1769 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1770 save, close,restart,add new route - first named route is now
1778 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1780 if (route_by_name (track_name) == 0) {
1784 } while (track_id < (UINT_MAX-1));
1786 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1787 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1792 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1793 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1798 shared_ptr<AudioTrack> track;
1801 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1803 if (track->ensure_io (input_channels, output_channels, false, this)) {
1804 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1805 input_channels, output_channels)
1811 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1815 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1816 port = physinputs[(channels_used+x)%nphysical_in];
1819 if (port.length() && track->connect_input (track->input (x), port, this)) {
1825 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1829 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1830 port = physoutputs[(channels_used+x)%nphysical_out];
1831 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1833 port = _master_out->input (x%_master_out->n_inputs())->name();
1837 if (port.length() && track->connect_output (track->output (x), port, this)) {
1842 channels_used += track->n_inputs ();
1844 track->audio_diskstream()->non_realtime_input_change();
1846 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1847 track->set_remote_control_id (control_id);
1850 new_routes.push_back (track);
1851 ret.push_back (track);
1855 catch (failed_constructor &err) {
1856 error << _("Session: could not create new audio track.") << endmsg;
1859 /* we need to get rid of this, since the track failed to be created */
1860 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1863 RCUWriter<DiskstreamList> writer (diskstreams);
1864 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1865 ds->remove (track->audio_diskstream());
1872 catch (AudioEngine::PortRegistrationFailure& pfe) {
1874 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1877 /* we need to get rid of this, since the track failed to be created */
1878 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1881 RCUWriter<DiskstreamList> writer (diskstreams);
1882 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1883 ds->remove (track->audio_diskstream());
1894 if (!new_routes.empty()) {
1895 add_routes (new_routes, true);
1902 Session::set_remote_control_ids ()
1904 RemoteModel m = Config->get_remote_model();
1906 shared_ptr<RouteList> r = routes.reader ();
1908 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1909 if ( MixerOrdered == m) {
1910 long order = (*i)->order_key(N_("signal"));
1911 (*i)->set_remote_control_id( order+1 );
1912 } else if ( EditorOrdered == m) {
1913 long order = (*i)->order_key(N_("editor"));
1914 (*i)->set_remote_control_id( order+1 );
1915 } else if ( UserOrdered == m) {
1916 //do nothing ... only changes to remote id's are initiated by user
1923 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1926 uint32_t bus_id = 1;
1930 uint32_t control_id;
1932 /* count existing audio busses */
1935 shared_ptr<RouteList> r = routes.reader ();
1937 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1938 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1939 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1946 vector<string> physinputs;
1947 vector<string> physoutputs;
1949 _engine.get_physical_audio_outputs (physoutputs);
1950 _engine.get_physical_audio_inputs (physinputs);
1951 control_id = ntracks() + nbusses() + 1;
1956 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1960 if (route_by_name (bus_name) == 0) {
1964 } while (bus_id < (UINT_MAX-1));
1967 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1969 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1970 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1971 input_channels, output_channels)
1976 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1980 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1981 port = physinputs[((n+x)%n_physical_audio_inputs)];
1984 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1989 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1993 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1994 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1995 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1997 port = _master_out->input (x%_master_out->n_inputs())->name();
2001 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2006 bus->set_remote_control_id (control_id);
2009 ret.push_back (bus);
2013 catch (failed_constructor &err) {
2014 error << _("Session: could not create new audio route.") << endmsg;
2018 catch (AudioEngine::PortRegistrationFailure& pfe) {
2019 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
2029 add_routes (ret, true);
2037 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2041 uint32_t control_id;
2044 if (!tree.read (template_path.c_str())) {
2048 XMLNode* node = tree.root();
2050 control_id = ntracks() + nbusses() + 1;
2054 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2056 std::string node_name = IO::name_from_state (*node_copy.children().front());
2058 if (route_by_name (node_name) != 0) {
2060 /* generate a new name by adding a number to the end of the template name */
2062 uint32_t number = 1;
2065 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2069 if (route_by_name (name) == 0) {
2073 } while (number < UINT_MAX);
2075 if (number == UINT_MAX) {
2076 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2080 IO::set_name_in_state (*node_copy.children().front(), name);
2083 Track::zero_diskstream_id_in_xml (node_copy);
2086 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2089 error << _("Session: cannot create track/bus from template description") << endmsg;
2093 if (boost::dynamic_pointer_cast<Track>(route)) {
2094 /* force input/output change signals so that the new diskstream
2095 picks up the configuration of the route. During session
2096 loading this normally happens in a different way.
2098 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2099 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2102 route->set_remote_control_id (control_id);
2105 ret.push_back (route);
2108 catch (failed_constructor &err) {
2109 error << _("Session: could not create new route from template") << endmsg;
2113 catch (AudioEngine::PortRegistrationFailure& pfe) {
2114 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
2123 add_routes (ret, true);
2129 boost::shared_ptr<Route>
2130 Session::new_video_track (string name)
2132 uint32_t control_id = ntracks() + nbusses() + 1;
2133 shared_ptr<Route> new_route (
2134 new Route ( *this, name, -1, -1, -1, -1, Route::Flag(0), ARDOUR::DataType::NIL));
2135 new_route->set_remote_control_id (control_id);
2138 rl.push_back (new_route);
2140 RCUWriter<RouteList> writer (routes);
2141 shared_ptr<RouteList> r = writer.get_copy ();
2142 r->insert (r->end(), rl.begin(), rl.end());
2143 resort_routes_using (r);
2149 Session::add_routes (RouteList& new_routes, bool save)
2152 RCUWriter<RouteList> writer (routes);
2153 shared_ptr<RouteList> r = writer.get_copy ();
2154 r->insert (r->end(), new_routes.begin(), new_routes.end());
2155 resort_routes_using (r);
2158 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2160 boost::weak_ptr<Route> wpr (*x);
2162 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2163 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2164 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2165 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2167 if ((*x)->master()) {
2171 if ((*x)->control()) {
2172 _control_out = (*x);
2176 if (_control_out && IO::connecting_legal) {
2178 vector<string> cports;
2179 uint32_t ni = _control_out->n_inputs();
2182 for (n = 0; n < ni; ++n) {
2183 cports.push_back (_control_out->input(n)->name());
2186 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2187 (*x)->set_control_outs (cports);
2194 save_state (_current_snapshot_name);
2197 RouteAdded (new_routes); /* EMIT SIGNAL */
2201 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2203 /* need to do this in case we're rolling at the time, to prevent false underruns */
2204 dstream->do_refill_with_alloc ();
2206 dstream->set_block_size (current_block_size);
2209 RCUWriter<DiskstreamList> writer (diskstreams);
2210 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2211 ds->push_back (dstream);
2212 /* writer goes out of scope, copies ds back to main */
2215 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2216 boost::weak_ptr<Diskstream> (dstream)));
2217 /* this will connect to future changes, and check the current length */
2218 diskstream_playlist_changed (dstream);
2220 dstream->prepare ();
2224 Session::remove_route (shared_ptr<Route> route)
2227 RCUWriter<RouteList> writer (routes);
2228 shared_ptr<RouteList> rs = writer.get_copy ();
2232 /* deleting the master out seems like a dumb
2233 idea, but its more of a UI policy issue
2237 if (route == _master_out) {
2238 _master_out = shared_ptr<Route> ();
2241 if (route == _control_out) {
2242 _control_out = shared_ptr<Route> ();
2244 /* cancel control outs for all routes */
2246 vector<string> empty;
2248 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2249 (*r)->set_control_outs (empty);
2253 update_route_solo_state ();
2255 /* writer goes out of scope, forces route list update */
2258 // FIXME: audio specific
2260 boost::shared_ptr<AudioDiskstream> ds;
2262 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2263 ds = at->audio_diskstream();
2269 RCUWriter<DiskstreamList> dsl (diskstreams);
2270 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2274 diskstreams.flush ();
2277 find_current_end ();
2279 // We need to disconnect the routes inputs and outputs
2281 route->disconnect_inputs (0);
2282 route->disconnect_outputs (0);
2284 update_latency_compensation (false, false);
2287 /* get rid of it from the dead wood collection in the route list manager */
2289 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2293 /* try to cause everyone to drop their references */
2295 route->drop_references ();
2297 sync_order_keys (N_("session"));
2299 /* save the new state of the world */
2301 if (save_state (_current_snapshot_name)) {
2302 save_history (_current_snapshot_name);
2307 Session::route_mute_changed (void* src)
2313 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2315 if (solo_update_disabled) {
2321 boost::shared_ptr<Route> route = wpr.lock ();
2324 /* should not happen */
2325 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2329 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2331 shared_ptr<RouteList> r = routes.reader ();
2333 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2335 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2339 /* don't mess with busses */
2341 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2347 /* don't mess with tracks */
2349 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2354 if ((*i) != route &&
2355 ((*i)->mix_group () == 0 ||
2356 (*i)->mix_group () != route->mix_group () ||
2357 !route->mix_group ()->is_active())) {
2359 if ((*i)->soloed()) {
2361 /* if its already soloed, and solo latching is enabled,
2362 then leave it as it is.
2365 if (Config->get_solo_latched()) {
2372 solo_update_disabled = true;
2373 (*i)->set_solo (false, src);
2374 solo_update_disabled = false;
2378 bool something_soloed = false;
2379 bool same_thing_soloed = false;
2380 bool signal = false;
2382 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2383 if ((*i)->soloed()) {
2384 something_soloed = true;
2385 if (dynamic_cast<AudioTrack*>((*i).get())) {
2387 same_thing_soloed = true;
2392 same_thing_soloed = true;
2400 if (something_soloed != currently_soloing) {
2402 currently_soloing = something_soloed;
2405 modify_solo_mute (is_track, same_thing_soloed);
2408 SoloActive (currently_soloing); /* EMIT SIGNAL */
2411 SoloChanged (); /* EMIT SIGNAL */
2417 Session::update_route_solo_state ()
2420 bool is_track = false;
2421 bool signal = false;
2423 /* this is where we actually implement solo by changing
2424 the solo mute setting of each track.
2427 shared_ptr<RouteList> r = routes.reader ();
2429 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2430 if ((*i)->soloed()) {
2432 if (dynamic_cast<AudioTrack*>((*i).get())) {
2439 if (mute != currently_soloing) {
2441 currently_soloing = mute;
2444 if (!is_track && !mute) {
2446 /* nothing is soloed */
2448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2449 (*i)->set_solo_mute (false);
2459 modify_solo_mute (is_track, mute);
2462 SoloActive (currently_soloing);
2467 Session::modify_solo_mute (bool is_track, bool mute)
2469 shared_ptr<RouteList> r = routes.reader ();
2471 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2475 /* only alter track solo mute */
2477 if (dynamic_cast<AudioTrack*>((*i).get())) {
2478 if ((*i)->soloed()) {
2479 (*i)->set_solo_mute (!mute);
2481 (*i)->set_solo_mute (mute);
2487 /* only alter bus solo mute */
2489 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2491 if ((*i)->soloed()) {
2493 (*i)->set_solo_mute (false);
2497 /* don't mute master or control outs
2498 in response to another bus solo
2501 if ((*i) != _master_out &&
2502 (*i) != _control_out) {
2503 (*i)->set_solo_mute (mute);
2514 Session::catch_up_on_solo ()
2516 /* this is called after set_state() to catch the full solo
2517 state, which can't be correctly determined on a per-route
2518 basis, but needs the global overview that only the session
2521 update_route_solo_state();
2525 Session::catch_up_on_solo_mute_override ()
2527 if (Config->get_solo_model() != InverseMute) {
2531 /* this is called whenever the param solo-mute-override is
2534 shared_ptr<RouteList> r = routes.reader ();
2536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2537 (*i)->catch_up_on_solo_mute_override ();
2542 Session::route_by_name (string name)
2544 shared_ptr<RouteList> r = routes.reader ();
2546 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2547 if ((*i)->name() == name) {
2552 return shared_ptr<Route> ((Route*) 0);
2556 Session::route_by_id (PBD::ID id)
2558 shared_ptr<RouteList> r = routes.reader ();
2560 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2561 if ((*i)->id() == id) {
2566 return shared_ptr<Route> ((Route*) 0);
2570 Session::route_by_remote_id (uint32_t id)
2572 shared_ptr<RouteList> r = routes.reader ();
2574 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2575 if ((*i)->remote_control_id() == id) {
2580 return shared_ptr<Route> ((Route*) 0);
2584 Session::find_current_end ()
2586 if (_state_of_the_state & Loading) {
2590 nframes_t max = get_maximum_extent ();
2592 if (max > end_location->end()) {
2593 end_location->set_end (max);
2595 DurationChanged(); /* EMIT SIGNAL */
2600 Session::get_maximum_extent () const
2605 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2607 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2608 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2610 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2611 if ((me = pl->get_maximum_extent()) > max) {
2619 boost::shared_ptr<Diskstream>
2620 Session::diskstream_by_name (string name)
2622 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2624 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2625 if ((*i)->name() == name) {
2630 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2633 boost::shared_ptr<Diskstream>
2634 Session::diskstream_by_id (const PBD::ID& id)
2636 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2638 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2639 if ((*i)->id() == id) {
2644 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2647 /* AudioRegion management */
2650 Session::new_region_name (string old)
2652 string::size_type last_period;
2654 string::size_type len = old.length() + 64;
2657 if ((last_period = old.find_last_of ('.')) == string::npos) {
2659 /* no period present - add one explicitly */
2662 last_period = old.length() - 1;
2667 number = atoi (old.substr (last_period+1).c_str());
2671 while (number < (UINT_MAX-1)) {
2673 AudioRegionList::const_iterator i;
2678 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2681 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2682 if (i->second->name() == sbuf) {
2687 if (i == audio_regions.end()) {
2692 if (number != (UINT_MAX-1)) {
2696 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2701 Session::region_name (string& result, string base, bool newlevel)
2708 Glib::Mutex::Lock lm (region_lock);
2710 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2719 string::size_type pos;
2721 pos = base.find_last_of ('.');
2723 /* pos may be npos, but then we just use entire base */
2725 subbase = base.substr (0, pos);
2730 Glib::Mutex::Lock lm (region_lock);
2732 map<string,uint32_t>::iterator x;
2736 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2738 region_name_map[subbase] = 1;
2741 snprintf (buf, sizeof (buf), ".%d", x->second);
2751 Session::add_region (boost::shared_ptr<Region> region)
2753 vector<boost::shared_ptr<Region> > v;
2754 v.push_back (region);
2759 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2761 boost::shared_ptr<AudioRegion> ar;
2762 boost::shared_ptr<AudioRegion> oar;
2766 Glib::Mutex::Lock lm (region_lock);
2768 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2770 boost::shared_ptr<Region> region = *ii;
2774 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2776 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2778 AudioRegionList::iterator x;
2780 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2782 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2784 if (ar->region_list_equivalent (oar)) {
2789 if (x == audio_regions.end()) {
2791 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2793 entry.first = region->id();
2796 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2807 fatal << _("programming error: ")
2808 << X_("unknown region type passed to Session::add_region()")
2816 /* mark dirty because something has changed even if we didn't
2817 add the region to the region list.
2824 vector<boost::weak_ptr<AudioRegion> > v;
2825 boost::shared_ptr<AudioRegion> first_ar;
2827 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2829 boost::shared_ptr<Region> region = *ii;
2830 boost::shared_ptr<AudioRegion> ar;
2834 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2836 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2844 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2845 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2847 update_region_name_map (region);
2851 AudioRegionsAdded (v); /* EMIT SIGNAL */
2857 Session::update_region_name_map (boost::shared_ptr<Region> region)
2859 string::size_type last_period = region->name().find_last_of ('.');
2861 if (last_period != string::npos && last_period < region->name().length() - 1) {
2863 string base = region->name().substr (0, last_period);
2864 string number = region->name().substr (last_period+1);
2865 map<string,uint32_t>::iterator x;
2867 /* note that if there is no number, we get zero from atoi,
2871 region_name_map[base] = atoi (number);
2876 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2878 boost::shared_ptr<Region> region (weak_region.lock ());
2884 if (what_changed & Region::HiddenChanged) {
2885 /* relay hidden changes */
2886 RegionHiddenChange (region);
2889 if (what_changed & NameChanged) {
2890 update_region_name_map (region);
2895 Session::remove_region (boost::weak_ptr<Region> weak_region)
2897 AudioRegionList::iterator i;
2898 boost::shared_ptr<Region> region (weak_region.lock ());
2904 boost::shared_ptr<AudioRegion> ar;
2905 bool removed = false;
2908 Glib::Mutex::Lock lm (region_lock);
2910 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2911 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2912 audio_regions.erase (i);
2918 fatal << _("programming error: ")
2919 << X_("unknown region type passed to Session::remove_region()")
2925 /* mark dirty because something has changed even if we didn't
2926 remove the region from the region list.
2932 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2936 boost::shared_ptr<AudioRegion>
2937 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2939 AudioRegionList::iterator i;
2940 boost::shared_ptr<AudioRegion> region;
2941 Glib::Mutex::Lock lm (region_lock);
2943 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2947 if (region->whole_file()) {
2949 if (child->source_equivalent (region)) {
2955 return boost::shared_ptr<AudioRegion> ();
2959 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2961 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2962 (*i)->get_region_list_equivalent_regions (region, result);
2966 Session::destroy_region (boost::shared_ptr<Region> region)
2968 vector<boost::shared_ptr<Source> > srcs;
2971 boost::shared_ptr<AudioRegion> aregion;
2973 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2977 if (aregion->playlist()) {
2978 aregion->playlist()->destroy_region (region);
2981 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2982 srcs.push_back (aregion->source (n));
2986 region->drop_references ();
2988 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2990 if (!(*i)->used()) {
2991 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2994 (afs)->mark_for_remove ();
2997 (*i)->drop_references ();
2999 cerr << "source was not used by any playlist\n";
3007 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3009 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3010 destroy_region (*i);
3016 Session::remove_last_capture ()
3018 list<boost::shared_ptr<Region> > r;
3020 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3022 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3023 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3026 r.insert (r.end(), l.begin(), l.end());
3031 destroy_regions (r);
3033 save_state (_current_snapshot_name);
3039 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3045 /* Source Management */
3048 Session::add_source (boost::shared_ptr<Source> source)
3050 boost::shared_ptr<AudioFileSource> afs;
3052 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3054 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3055 pair<AudioSourceList::iterator,bool> result;
3057 entry.first = source->id();
3061 Glib::Mutex::Lock lm (audio_source_lock);
3062 result = audio_sources.insert (entry);
3065 if (result.second) {
3066 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3070 if (Config->get_auto_analyse_audio()) {
3071 Analyser::queue_source_for_analysis (source, false);
3077 Session::remove_source (boost::weak_ptr<Source> src)
3079 AudioSourceList::iterator i;
3080 boost::shared_ptr<Source> source = src.lock();
3087 Glib::Mutex::Lock lm (audio_source_lock);
3089 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3090 audio_sources.erase (i);
3094 if (!_state_of_the_state & InCleanup) {
3096 /* save state so we don't end up with a session file
3097 referring to non-existent sources.
3100 save_state (_current_snapshot_name);
3104 boost::shared_ptr<Source>
3105 Session::source_by_id (const PBD::ID& id)
3107 Glib::Mutex::Lock lm (audio_source_lock);
3108 AudioSourceList::iterator i;
3109 boost::shared_ptr<Source> source;
3111 if ((i = audio_sources.find (id)) != audio_sources.end()) {
3115 /* XXX search MIDI or other searches here */
3121 boost::shared_ptr<Source>
3122 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3124 Glib::Mutex::Lock lm (audio_source_lock);
3126 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3127 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3129 if (afs && afs->path() == path && chn == afs->channel()) {
3134 return boost::shared_ptr<Source>();
3138 Session::peak_path (Glib::ustring base) const
3140 return Glib::build_filename(peak_dir (), base + ".peak");
3144 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3147 string old_basename = PBD::basename_nosuffix (oldname);
3148 string new_legalized = legalize_for_path (newname);
3150 /* note: we know (or assume) the old path is already valid */
3154 /* destructive file sources have a name of the form:
3156 /path/to/Tnnnn-NAME(%[LR])?.wav
3158 the task here is to replace NAME with the new name.
3161 /* find last slash */
3165 string::size_type slash;
3166 string::size_type dash;
3168 if ((slash = path.find_last_of ('/')) == string::npos) {
3172 dir = path.substr (0, slash+1);
3174 /* '-' is not a legal character for the NAME part of the path */
3176 if ((dash = path.find_last_of ('-')) == string::npos) {
3180 prefix = path.substr (slash+1, dash-(slash+1));
3185 path += new_legalized;
3186 path += ".wav"; /* XXX gag me with a spoon */
3190 /* non-destructive file sources have a name of the form:
3192 /path/to/NAME-nnnnn(%[LR])?.wav
3194 the task here is to replace NAME with the new name.
3199 string::size_type slash;
3200 string::size_type dash;
3201 string::size_type postfix;
3203 /* find last slash */
3205 if ((slash = path.find_last_of ('/')) == string::npos) {
3209 dir = path.substr (0, slash+1);
3211 /* '-' is not a legal character for the NAME part of the path */
3213 if ((dash = path.find_last_of ('-')) == string::npos) {
3217 suffix = path.substr (dash+1);
3219 // Suffix is now everything after the dash. Now we need to eliminate
3220 // the nnnnn part, which is done by either finding a '%' or a '.'
3222 postfix = suffix.find_last_of ("%");
3223 if (postfix == string::npos) {
3224 postfix = suffix.find_last_of ('.');
3227 if (postfix != string::npos) {
3228 suffix = suffix.substr (postfix);
3230 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3234 const uint32_t limit = 10000;
3235 char buf[PATH_MAX+1];
3237 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3239 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3241 if (access (buf, F_OK) != 0) {
3249 error << "FATAL ERROR! Could not find a " << endl;
3258 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3262 char buf[PATH_MAX+1];
3263 const uint32_t limit = 10000;
3267 legalized = legalize_for_path (name);
3269 /* find a "version" of the file name that doesn't exist in
3270 any of the possible directories.
3273 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3275 vector<space_and_path>::iterator i;
3276 uint32_t existing = 0;
3278 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3282 spath += sound_dir (false);
3286 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3287 } else if (nchan == 2) {
3289 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3291 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3293 } else if (nchan < 26) {
3294 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3296 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3305 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3306 } else if (nchan == 2) {
3308 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3310 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3312 } else if (nchan < 26) {
3313 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3315 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3319 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3325 if (existing == 0) {
3330 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3332 throw failed_constructor();
3336 /* we now have a unique name for the file, but figure out where to
3342 spath = discover_best_sound_dir ();
3345 string::size_type pos = foo.find_last_of ('/');
3347 if (pos == string::npos) {
3350 spath += foo.substr (pos + 1);
3356 boost::shared_ptr<AudioFileSource>
3357 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3359 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3360 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3363 /* Playlist management */
3365 boost::shared_ptr<Playlist>
3366 Session::playlist_by_name (string name)
3368 Glib::Mutex::Lock lm (playlist_lock);
3369 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3370 if ((*i)->name() == name) {
3374 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3375 if ((*i)->name() == name) {
3380 return boost::shared_ptr<Playlist>();
3384 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3386 if (playlist->hidden()) {
3391 Glib::Mutex::Lock lm (playlist_lock);
3392 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3393 playlists.insert (playlists.begin(), playlist);
3394 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3395 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3401 PlaylistAdded (playlist); /* EMIT SIGNAL */
3405 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3408 Glib::Mutex::Lock lm (playlist_lock);
3409 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3412 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3419 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3421 boost::shared_ptr<Playlist> pl(wpl.lock());
3427 PlaylistList::iterator x;
3430 /* its not supposed to be visible */
3435 Glib::Mutex::Lock lm (playlist_lock);
3439 unused_playlists.insert (pl);
3441 if ((x = playlists.find (pl)) != playlists.end()) {
3442 playlists.erase (x);
3448 playlists.insert (pl);
3450 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3451 unused_playlists.erase (x);
3458 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3460 if (_state_of_the_state & Deletion) {
3464 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3471 Glib::Mutex::Lock lm (playlist_lock);
3473 PlaylistList::iterator i;
3475 i = find (playlists.begin(), playlists.end(), playlist);
3476 if (i != playlists.end()) {
3477 playlists.erase (i);
3480 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3481 if (i != unused_playlists.end()) {
3482 unused_playlists.erase (i);
3489 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3493 Session::set_audition (boost::shared_ptr<Region> r)
3495 pending_audition_region = r;
3496 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3497 schedule_butler_transport_work ();
3501 Session::audition_playlist ()
3503 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3504 ev->region.reset ();
3509 Session::non_realtime_set_audition ()
3511 if (!pending_audition_region) {
3512 auditioner->audition_current_playlist ();
3514 auditioner->audition_region (pending_audition_region);
3515 pending_audition_region.reset ();
3517 AuditionActive (true); /* EMIT SIGNAL */
3521 Session::audition_region (boost::shared_ptr<Region> r)
3523 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3529 Session::cancel_audition ()
3531 if (auditioner->active()) {
3532 auditioner->cancel_audition ();
3533 AuditionActive (false); /* EMIT SIGNAL */
3538 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3540 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3544 Session::remove_empty_sounds ()
3546 PathScanner scanner;
3548 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3550 Glib::Mutex::Lock lm (audio_source_lock);
3552 regex_t compiled_tape_track_pattern;
3555 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3559 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3561 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3565 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3567 /* never remove files that appear to be a tape track */
3569 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3574 if (AudioFileSource::is_empty (*this, **i)) {
3576 unlink ((*i)->c_str());
3578 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3579 unlink (peakpath.c_str());
3585 delete possible_audiofiles;
3589 Session::is_auditioning () const
3591 /* can be called before we have an auditioner object */
3593 return auditioner->active();
3600 Session::set_all_solo (bool yn)
3602 shared_ptr<RouteList> r = routes.reader ();
3604 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3605 if (!(*i)->hidden()) {
3606 (*i)->set_solo (yn, this);
3614 Session::set_all_mute (bool yn)
3616 shared_ptr<RouteList> r = routes.reader ();
3618 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3619 if (!(*i)->hidden()) {
3620 (*i)->set_mute (yn, this);
3628 Session::n_diskstreams () const
3632 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3634 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3635 if (!(*i)->hidden()) {
3643 Session::graph_reordered ()
3645 /* don't do this stuff if we are setting up connections
3646 from a set_state() call or creating new tracks.
3649 if (_state_of_the_state & InitialConnecting) {
3653 /* every track/bus asked for this to be handled but it was deferred because
3654 we were connecting. do it now.
3657 request_input_change_handling ();
3661 /* force all diskstreams to update their capture offset values to
3662 reflect any changes in latencies within the graph.
3665 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3667 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3668 (*i)->set_capture_offset ();
3673 Session::record_disenable_all ()
3675 record_enable_change_all (false);
3679 Session::record_enable_all ()
3681 record_enable_change_all (true);
3685 Session::record_enable_change_all (bool yn)
3687 shared_ptr<RouteList> r = routes.reader ();
3689 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3692 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3693 at->set_record_enable (yn, this);
3697 /* since we don't keep rec-enable state, don't mark session dirty */
3701 Session::add_redirect (Redirect* redirect)
3705 PortInsert* port_insert;
3706 PluginInsert* plugin_insert;
3708 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3709 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3710 _port_inserts.insert (_port_inserts.begin(), port_insert);
3711 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3712 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3714 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3717 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3718 _sends.insert (_sends.begin(), send);
3720 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3724 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3730 Session::remove_redirect (Redirect* redirect)
3734 PortInsert* port_insert;
3735 PluginInsert* plugin_insert;
3737 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3738 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3739 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3740 if (x != _port_inserts.end()) {
3741 insert_bitset[port_insert->bit_slot()] = false;
3742 _port_inserts.erase (x);
3744 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3745 _plugin_inserts.remove (plugin_insert);
3747 fatal << string_compose (_("programming error: %1"),
3748 X_("unknown type of Insert deleted!"))
3752 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3753 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3754 if (x != _sends.end()) {
3755 send_bitset[send->bit_slot()] = false;
3759 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3767 Session::available_capture_duration ()
3769 float sample_bytes_on_disk = 4.0; // keep gcc happy
3771 switch (Config->get_native_file_data_format()) {
3773 sample_bytes_on_disk = 4.0;
3777 sample_bytes_on_disk = 3.0;
3781 sample_bytes_on_disk = 2.0;
3785 /* impossible, but keep some gcc versions happy */
3786 fatal << string_compose (_("programming error: %1"),
3787 X_("illegal native file data format"))
3792 double scale = 4096.0 / sample_bytes_on_disk;
3794 if (_total_free_4k_blocks * scale > (double) max_frames) {
3798 return (nframes_t) floor (_total_free_4k_blocks * scale);
3802 Session::add_connection (ARDOUR::Connection* connection)
3805 Glib::Mutex::Lock guard (connection_lock);
3806 _connections.push_back (connection);
3809 ConnectionAdded (connection); /* EMIT SIGNAL */
3815 Session::remove_connection (ARDOUR::Connection* connection)
3817 bool removed = false;
3820 Glib::Mutex::Lock guard (connection_lock);
3821 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3823 if (i != _connections.end()) {
3824 _connections.erase (i);
3830 ConnectionRemoved (connection); /* EMIT SIGNAL */
3836 ARDOUR::Connection *
3837 Session::connection_by_name (string name) const
3839 Glib::Mutex::Lock lm (connection_lock);
3841 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3842 if ((*i)->name() == name) {
3851 Session::tempo_map_changed (Change ignored)
3855 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3856 (*i)->update_after_tempo_map_change ();
3859 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3860 (*i)->update_after_tempo_map_change ();
3867 Session::ensure_passthru_buffers (uint32_t howmany)
3869 if (current_block_size == 0) {
3873 while (howmany > _passthru_buffers.size()) {
3875 #ifdef NO_POSIX_MEMALIGN
3876 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3878 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3879 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3880 current_block_size, sizeof (Sample), strerror (errno))
3885 _passthru_buffers.push_back (p);
3889 #ifdef NO_POSIX_MEMALIGN
3890 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3892 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3893 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3894 current_block_size, sizeof (Sample), strerror (errno))
3899 memset (p, 0, sizeof (Sample) * current_block_size);
3900 _silent_buffers.push_back (p);
3904 #ifdef NO_POSIX_MEMALIGN
3905 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3907 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3909 memset (p, 0, sizeof (Sample) * current_block_size);
3910 _send_buffers.push_back (p);
3913 allocate_pan_automation_buffers (current_block_size, howmany, false);
3917 Session::next_insert_id ()
3919 /* this doesn't really loop forever. just think about it */
3922 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3923 if (!insert_bitset[n]) {
3924 insert_bitset[n] = true;
3930 /* none available, so resize and try again */
3932 insert_bitset.resize (insert_bitset.size() + 16, false);
3937 Session::next_send_id ()
3939 /* this doesn't really loop forever. just think about it */
3942 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3943 if (!send_bitset[n]) {
3944 send_bitset[n] = true;
3950 /* none available, so resize and try again */
3952 send_bitset.resize (send_bitset.size() + 16, false);
3957 Session::mark_send_id (uint32_t id)
3959 if (id >= send_bitset.size()) {
3960 send_bitset.resize (id+16, false);
3962 if (send_bitset[id]) {
3963 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3965 send_bitset[id] = true;
3969 Session::mark_insert_id (uint32_t id)
3971 if (id >= insert_bitset.size()) {
3972 insert_bitset.resize (id+16, false);
3974 if (insert_bitset[id]) {
3975 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3977 insert_bitset[id] = true;
3980 /* Named Selection management */
3983 Session::named_selection_by_name (string name)
3985 Glib::Mutex::Lock lm (named_selection_lock);
3986 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3987 if ((*i)->name == name) {
3995 Session::add_named_selection (NamedSelection* named_selection)
3998 Glib::Mutex::Lock lm (named_selection_lock);
3999 named_selections.insert (named_selections.begin(), named_selection);
4002 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4008 NamedSelectionAdded (); /* EMIT SIGNAL */
4012 Session::remove_named_selection (NamedSelection* named_selection)
4014 bool removed = false;
4017 Glib::Mutex::Lock lm (named_selection_lock);
4019 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4021 if (i != named_selections.end()) {
4023 named_selections.erase (i);
4030 NamedSelectionRemoved (); /* EMIT SIGNAL */
4035 Session::reset_native_file_format ()
4037 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4039 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4040 (*i)->reset_write_sources (false);
4045 Session::route_name_unique (string n) const
4047 shared_ptr<RouteList> r = routes.reader ();
4049 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4050 if ((*i)->name() == n) {
4059 Session::n_playlists () const
4061 Glib::Mutex::Lock lm (playlist_lock);
4062 return playlists.size();
4066 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4068 if (!force && howmany <= _npan_buffers) {
4072 if (_pan_automation_buffer) {
4074 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4075 delete [] _pan_automation_buffer[i];
4078 delete [] _pan_automation_buffer;
4081 _pan_automation_buffer = new pan_t*[howmany];
4083 for (uint32_t i = 0; i < howmany; ++i) {
4084 _pan_automation_buffer[i] = new pan_t[nframes];
4087 _npan_buffers = howmany;
4091 Session::freeze (InterThreadInfo& itt)
4093 shared_ptr<RouteList> r = routes.reader ();
4095 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4099 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4100 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4110 boost::shared_ptr<Region>
4111 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
4112 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
4114 boost::shared_ptr<Region> result;
4115 boost::shared_ptr<Playlist> playlist;
4116 boost::shared_ptr<AudioFileSource> fsource;
4118 char buf[PATH_MAX+1];
4122 nframes_t this_chunk;
4124 nframes_t len = end - start;
4125 vector<Sample*> buffers;
4128 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4129 end, start) << endmsg;
4133 // any bigger than this seems to cause stack overflows in called functions
4134 const nframes_t chunk_size = (128 * 1024)/4;
4136 g_atomic_int_set (&processing_prohibited, 1);
4138 /* call tree *MUST* hold route_lock */
4140 if ((playlist = track.diskstream()->playlist()) == 0) {
4144 /* external redirects will be a problem */
4146 if (track.has_external_redirects()) {
4150 nchans = track.audio_diskstream()->n_channels();
4152 dir = discover_best_sound_dir ();
4154 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
4156 for (x = 0; x < 99999; ++x) {
4157 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4158 if (access (buf, F_OK) != 0) {
4164 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4169 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
4172 catch (failed_constructor& err) {
4173 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4177 srcs.push_back (fsource);
4180 /* XXX need to flush all redirects */
4185 /* create a set of reasonably-sized buffers */
4187 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4189 #ifdef NO_POSIX_MEMALIGN
4190 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4192 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4194 buffers.push_back (b);
4197 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4198 (*src)->prepare_for_peakfile_writes ();
4201 while (to_do && !itt.cancel) {
4203 this_chunk = min (to_do, chunk_size);
4205 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
4210 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4211 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4214 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4220 start += this_chunk;
4221 to_do -= this_chunk;
4223 itt.progress = (float) (1.0 - ((double) to_do / len));
4232 xnow = localtime (&now);
4234 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4235 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4238 afs->update_header (position, *xnow, now);
4239 afs->flush_header ();
4243 /* construct a region to represent the bounced material */
4245 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4246 region_name_from_path (srcs.front()->name(), true));
4251 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4252 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4255 afs->mark_for_remove ();
4258 (*src)->drop_references ();
4262 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4263 (*src)->done_with_peakfile_writes ();
4267 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4271 g_atomic_int_set (&processing_prohibited, 0);
4279 Session::get_silent_buffers (uint32_t howmany)
4281 if (howmany > _silent_buffers.size()) {
4283 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4284 howmany, _silent_buffers.size()) << endmsg;
4286 if (howmany > 1000) {
4287 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4291 while (howmany > _silent_buffers.size()) {
4294 #ifdef NO_POSIX_MEMALIGN
4295 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4297 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
4298 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4299 current_block_size, sizeof (Sample), strerror (errno))
4304 _silent_buffers.push_back (p);
4308 for (uint32_t i = 0; i < howmany; ++i) {
4309 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4312 return _silent_buffers;
4316 Session::ntracks () const
4319 shared_ptr<RouteList> r = routes.reader ();
4321 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4322 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4331 Session::nbusses () const
4334 shared_ptr<RouteList> r = routes.reader ();
4336 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4337 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4346 Session::add_automation_list(AutomationList *al)
4348 automation_lists[al->id()] = al;
4352 Session::compute_initial_length ()
4354 return _engine.frame_rate() * 60 * 5;
4358 Session::sync_order_keys (const char* base)
4360 if (!Config->get_sync_all_route_ordering()) {
4361 /* leave order keys as they are */
4365 boost::shared_ptr<RouteList> r = routes.reader ();
4367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4368 (*i)->sync_order_keys (base);
4371 Route::SyncOrderKeys (base); // EMIT SIGNAL