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 cerr << "disable record is doing something\n";
1313 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1314 g_atomic_int_set (&_record_status, Disabled);
1316 if (rs == Recording) {
1317 g_atomic_int_set (&_record_status, Enabled);
1321 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1323 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1324 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1327 if ((*i)->record_enabled ()) {
1328 (*i)->monitor_input (false);
1333 RecordStateChanged (); /* emit signal */
1336 remove_pending_capture_state ();
1342 Session::step_back_from_record ()
1344 /* XXX really atomic compare+swap here */
1345 if (g_atomic_int_get (&_record_status) == Recording) {
1346 g_atomic_int_set (&_record_status, Enabled);
1348 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1349 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1351 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1352 if ((*i)->record_enabled ()) {
1353 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1354 (*i)->monitor_input (false);
1362 Session::maybe_enable_record ()
1364 g_atomic_int_set (&_record_status, Enabled);
1366 /* this function is currently called from somewhere other than an RT thread.
1367 this save_state() call therefore doesn't impact anything.
1370 save_state ("", true);
1372 if (_transport_speed) {
1373 if (!Config->get_punch_in()) {
1377 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1378 RecordStateChanged (); /* EMIT SIGNAL */
1385 Session::audible_frame () const
1391 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1392 return last_stop_frame;
1395 /* the first of these two possible settings for "offset"
1396 mean that the audible frame is stationary until
1397 audio emerges from the latency compensation
1400 the second means that the audible frame is stationary
1401 until audio would emerge from a physical port
1402 in the absence of any plugin latency compensation
1405 offset = _worst_output_latency;
1407 if (offset > current_block_size) {
1408 offset -= current_block_size;
1410 /* XXX is this correct? if we have no external
1411 physical connections and everything is internal
1412 then surely this is zero? still, how
1413 likely is that anyway?
1415 offset = current_block_size;
1418 if (synced_to_jack()) {
1419 tf = _engine.transport_frame();
1421 tf = _transport_frame;
1426 if (!non_realtime_work_pending()) {
1430 /* check to see if we have passed the first guaranteed
1431 audible frame past our last stopping position. if not,
1432 the return that last stopping point because in terms
1433 of audible frames, we have not moved yet.
1436 if (_transport_speed > 0.0f) {
1438 if (!play_loop || !have_looped) {
1439 if (tf < last_stop_frame + offset) {
1440 return last_stop_frame;
1449 } else if (_transport_speed < 0.0f) {
1451 /* XXX wot? no backward looping? */
1453 if (tf > last_stop_frame - offset) {
1454 return last_stop_frame;
1466 Session::set_frame_rate (nframes_t frames_per_second)
1468 /** \fn void Session::set_frame_size(nframes_t)
1469 the AudioEngine object that calls this guarantees
1470 that it will not be called while we are also in
1471 ::process(). Its fine to do things that block
1475 _base_frame_rate = frames_per_second;
1479 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1483 // XXX we need some equivalent to this, somehow
1484 // SndFileSource::setup_standard_crossfades (frames_per_second);
1488 /* XXX need to reset/reinstantiate all LADSPA plugins */
1492 Session::set_block_size (nframes_t nframes)
1494 /* the AudioEngine guarantees
1495 that it will not be called while we are also in
1496 ::process(). It is therefore fine to do things that block
1501 vector<Sample*>::iterator i;
1504 current_block_size = nframes;
1506 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1510 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1514 _passthru_buffers.clear ();
1515 _silent_buffers.clear ();
1517 ensure_passthru_buffers (np);
1519 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1523 #ifdef NO_POSIX_MEMALIGN
1524 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1526 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1530 memset (*i, 0, sizeof (Sample) * current_block_size);
1534 if (_gain_automation_buffer) {
1535 delete [] _gain_automation_buffer;
1537 _gain_automation_buffer = new gain_t[nframes];
1539 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1541 boost::shared_ptr<RouteList> r = routes.reader ();
1543 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1544 (*i)->set_block_size (nframes);
1547 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1548 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1549 (*i)->set_block_size (nframes);
1552 set_worst_io_latencies ();
1557 Session::set_default_fade (float steepness, float fade_msecs)
1560 nframes_t fade_frames;
1562 /* Don't allow fade of less 1 frame */
1564 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1571 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1575 default_fade_msecs = fade_msecs;
1576 default_fade_steepness = steepness;
1579 // jlc, WTF is this!
1580 Glib::RWLock::ReaderLock lm (route_lock);
1581 AudioRegion::set_default_fade (steepness, fade_frames);
1586 /* XXX have to do this at some point */
1587 /* foreach region using default fade, reset, then
1588 refill_all_diskstream_buffers ();
1593 struct RouteSorter {
1594 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1595 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1597 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1600 if (r1->fed_by.empty()) {
1601 if (r2->fed_by.empty()) {
1602 /* no ardour-based connections inbound to either route. just use signal order */
1603 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1605 /* r2 has connections, r1 does not; run r1 early */
1609 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1616 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1618 shared_ptr<Route> r2;
1620 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1621 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1625 /* make a copy of the existing list of routes that feed r1 */
1627 set<shared_ptr<Route> > existing = r1->fed_by;
1629 /* for each route that feeds r1, recurse, marking it as feeding
1633 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1636 /* r2 is a route that feeds r1 which somehow feeds base. mark
1637 base as being fed by r2
1640 rbase->fed_by.insert (r2);
1644 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1648 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1652 /* now recurse, so that we can mark base as being fed by
1653 all routes that feed r2
1656 trace_terminal (r2, rbase);
1663 Session::resort_routes ()
1665 /* don't do anything here with signals emitted
1666 by Routes while we are being destroyed.
1669 if (_state_of_the_state & Deletion) {
1676 RCUWriter<RouteList> writer (routes);
1677 shared_ptr<RouteList> r = writer.get_copy ();
1678 resort_routes_using (r);
1679 /* writer goes out of scope and forces update */
1684 Session::resort_routes_using (shared_ptr<RouteList> r)
1686 RouteList::iterator i, j;
1688 for (i = r->begin(); i != r->end(); ++i) {
1690 (*i)->fed_by.clear ();
1692 for (j = r->begin(); j != r->end(); ++j) {
1694 /* although routes can feed themselves, it will
1695 cause an endless recursive descent if we
1696 detect it. so don't bother checking for
1704 if ((*j)->feeds (*i)) {
1705 (*i)->fed_by.insert (*j);
1710 for (i = r->begin(); i != r->end(); ++i) {
1711 trace_terminal (*i, *i);
1717 /* don't leave dangling references to routes in Route::fed_by */
1719 for (i = r->begin(); i != r->end(); ++i) {
1720 (*i)->fed_by.clear ();
1724 cerr << "finished route resort\n";
1726 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1727 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1734 list<boost::shared_ptr<AudioTrack> >
1735 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1737 char track_name[32];
1738 uint32_t track_id = 0;
1740 uint32_t channels_used = 0;
1742 RouteList new_routes;
1743 list<boost::shared_ptr<AudioTrack> > ret;
1744 uint32_t control_id;
1746 /* count existing audio tracks */
1749 shared_ptr<RouteList> r = routes.reader ();
1751 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1752 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1753 if (!(*i)->hidden()) {
1755 channels_used += (*i)->n_inputs();
1761 vector<string> physinputs;
1762 vector<string> physoutputs;
1763 uint32_t nphysical_in;
1764 uint32_t nphysical_out;
1766 _engine.get_physical_audio_outputs (physoutputs);
1767 _engine.get_physical_audio_inputs (physinputs);
1768 control_id = ntracks() + nbusses() + 1;
1772 /* check for duplicate route names, since we might have pre-existing
1773 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1774 save, close,restart,add new route - first named route is now
1782 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1784 if (route_by_name (track_name) == 0) {
1788 } while (track_id < (UINT_MAX-1));
1790 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1791 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1796 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1797 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1802 shared_ptr<AudioTrack> track;
1805 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1807 if (track->ensure_io (input_channels, output_channels, false, this)) {
1808 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1809 input_channels, output_channels)
1815 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1819 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1820 port = physinputs[(channels_used+x)%nphysical_in];
1823 if (port.length() && track->connect_input (track->input (x), port, this)) {
1829 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1833 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1834 port = physoutputs[(channels_used+x)%nphysical_out];
1835 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1837 port = _master_out->input (x%_master_out->n_inputs())->name();
1841 if (port.length() && track->connect_output (track->output (x), port, this)) {
1846 channels_used += track->n_inputs ();
1848 track->audio_diskstream()->non_realtime_input_change();
1850 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1851 track->set_remote_control_id (control_id);
1854 new_routes.push_back (track);
1855 ret.push_back (track);
1859 catch (failed_constructor &err) {
1860 error << _("Session: could not create new audio track.") << endmsg;
1863 /* we need to get rid of this, since the track failed to be created */
1864 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1867 RCUWriter<DiskstreamList> writer (diskstreams);
1868 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1869 ds->remove (track->audio_diskstream());
1876 catch (AudioEngine::PortRegistrationFailure& pfe) {
1878 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;
1881 /* we need to get rid of this, since the track failed to be created */
1882 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1885 RCUWriter<DiskstreamList> writer (diskstreams);
1886 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1887 ds->remove (track->audio_diskstream());
1898 if (!new_routes.empty()) {
1899 add_routes (new_routes, true);
1906 Session::set_remote_control_ids ()
1908 RemoteModel m = Config->get_remote_model();
1910 shared_ptr<RouteList> r = routes.reader ();
1912 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1913 if ( MixerOrdered == m) {
1914 long order = (*i)->order_key(N_("signal"));
1915 (*i)->set_remote_control_id( order+1 );
1916 } else if ( EditorOrdered == m) {
1917 long order = (*i)->order_key(N_("editor"));
1918 (*i)->set_remote_control_id( order+1 );
1919 } else if ( UserOrdered == m) {
1920 //do nothing ... only changes to remote id's are initiated by user
1927 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1930 uint32_t bus_id = 1;
1934 uint32_t control_id;
1936 /* count existing audio busses */
1939 shared_ptr<RouteList> r = routes.reader ();
1941 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1942 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1943 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1950 vector<string> physinputs;
1951 vector<string> physoutputs;
1953 _engine.get_physical_audio_outputs (physoutputs);
1954 _engine.get_physical_audio_inputs (physinputs);
1955 control_id = ntracks() + nbusses() + 1;
1960 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1964 if (route_by_name (bus_name) == 0) {
1968 } while (bus_id < (UINT_MAX-1));
1971 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1973 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1974 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1975 input_channels, output_channels)
1980 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1984 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1985 port = physinputs[((n+x)%n_physical_audio_inputs)];
1988 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1993 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1997 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1998 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1999 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
2001 port = _master_out->input (x%_master_out->n_inputs())->name();
2005 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2010 bus->set_remote_control_id (control_id);
2013 ret.push_back (bus);
2017 catch (failed_constructor &err) {
2018 error << _("Session: could not create new audio route.") << endmsg;
2022 catch (AudioEngine::PortRegistrationFailure& pfe) {
2023 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;
2033 add_routes (ret, true);
2041 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2045 uint32_t control_id;
2048 if (!tree.read (template_path.c_str())) {
2052 XMLNode* node = tree.root();
2054 control_id = ntracks() + nbusses() + 1;
2058 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2060 std::string node_name = IO::name_from_state (*node_copy.children().front());
2062 if (route_by_name (node_name) != 0) {
2064 /* generate a new name by adding a number to the end of the template name */
2066 uint32_t number = 1;
2069 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2073 if (route_by_name (name) == 0) {
2077 } while (number < UINT_MAX);
2079 if (number == UINT_MAX) {
2080 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2084 IO::set_name_in_state (*node_copy.children().front(), name);
2087 Track::zero_diskstream_id_in_xml (node_copy);
2090 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2093 error << _("Session: cannot create track/bus from template description") << endmsg;
2097 if (boost::dynamic_pointer_cast<Track>(route)) {
2098 /* force input/output change signals so that the new diskstream
2099 picks up the configuration of the route. During session
2100 loading this normally happens in a different way.
2102 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2103 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2106 route->set_remote_control_id (control_id);
2109 ret.push_back (route);
2112 catch (failed_constructor &err) {
2113 error << _("Session: could not create new route from template") << endmsg;
2117 catch (AudioEngine::PortRegistrationFailure& pfe) {
2118 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;
2127 add_routes (ret, true);
2133 boost::shared_ptr<Route>
2134 Session::new_video_track (string name)
2136 uint32_t control_id = ntracks() + nbusses() + 1;
2137 shared_ptr<Route> new_route (
2138 new Route ( *this, name, -1, -1, -1, -1, Route::Flag(0), ARDOUR::DataType::NIL));
2139 new_route->set_remote_control_id (control_id);
2142 rl.push_back (new_route);
2144 RCUWriter<RouteList> writer (routes);
2145 shared_ptr<RouteList> r = writer.get_copy ();
2146 r->insert (r->end(), rl.begin(), rl.end());
2147 resort_routes_using (r);
2153 Session::add_routes (RouteList& new_routes, bool save)
2156 RCUWriter<RouteList> writer (routes);
2157 shared_ptr<RouteList> r = writer.get_copy ();
2158 r->insert (r->end(), new_routes.begin(), new_routes.end());
2159 resort_routes_using (r);
2162 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2164 boost::weak_ptr<Route> wpr (*x);
2166 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2167 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2168 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2169 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2171 if ((*x)->master()) {
2175 if ((*x)->control()) {
2176 _control_out = (*x);
2180 if (_control_out && IO::connecting_legal) {
2182 vector<string> cports;
2183 uint32_t ni = _control_out->n_inputs();
2186 for (n = 0; n < ni; ++n) {
2187 cports.push_back (_control_out->input(n)->name());
2190 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2191 (*x)->set_control_outs (cports);
2198 save_state (_current_snapshot_name);
2201 RouteAdded (new_routes); /* EMIT SIGNAL */
2205 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2207 /* need to do this in case we're rolling at the time, to prevent false underruns */
2208 dstream->do_refill_with_alloc ();
2210 dstream->set_block_size (current_block_size);
2213 RCUWriter<DiskstreamList> writer (diskstreams);
2214 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2215 ds->push_back (dstream);
2216 /* writer goes out of scope, copies ds back to main */
2219 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2220 boost::weak_ptr<Diskstream> (dstream)));
2221 /* this will connect to future changes, and check the current length */
2222 diskstream_playlist_changed (dstream);
2224 dstream->prepare ();
2228 Session::remove_route (shared_ptr<Route> route)
2231 RCUWriter<RouteList> writer (routes);
2232 shared_ptr<RouteList> rs = writer.get_copy ();
2236 /* deleting the master out seems like a dumb
2237 idea, but its more of a UI policy issue
2241 if (route == _master_out) {
2242 _master_out = shared_ptr<Route> ();
2245 if (route == _control_out) {
2246 _control_out = shared_ptr<Route> ();
2248 /* cancel control outs for all routes */
2250 vector<string> empty;
2252 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2253 (*r)->set_control_outs (empty);
2257 update_route_solo_state ();
2259 /* writer goes out of scope, forces route list update */
2262 // FIXME: audio specific
2264 boost::shared_ptr<AudioDiskstream> ds;
2266 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2267 ds = at->audio_diskstream();
2273 RCUWriter<DiskstreamList> dsl (diskstreams);
2274 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2278 diskstreams.flush ();
2281 find_current_end ();
2283 // We need to disconnect the routes inputs and outputs
2285 route->disconnect_inputs (0);
2286 route->disconnect_outputs (0);
2288 update_latency_compensation (false, false);
2291 /* get rid of it from the dead wood collection in the route list manager */
2293 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2297 /* try to cause everyone to drop their references */
2299 route->drop_references ();
2301 sync_order_keys (N_("session"));
2303 /* save the new state of the world */
2305 if (save_state (_current_snapshot_name)) {
2306 save_history (_current_snapshot_name);
2311 Session::route_mute_changed (void* src)
2317 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2319 if (solo_update_disabled) {
2325 boost::shared_ptr<Route> route = wpr.lock ();
2328 /* should not happen */
2329 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2333 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2335 shared_ptr<RouteList> r = routes.reader ();
2337 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2339 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2343 /* don't mess with busses */
2345 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2351 /* don't mess with tracks */
2353 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2358 if ((*i) != route &&
2359 ((*i)->mix_group () == 0 ||
2360 (*i)->mix_group () != route->mix_group () ||
2361 !route->mix_group ()->is_active())) {
2363 if ((*i)->soloed()) {
2365 /* if its already soloed, and solo latching is enabled,
2366 then leave it as it is.
2369 if (Config->get_solo_latched()) {
2376 solo_update_disabled = true;
2377 (*i)->set_solo (false, src);
2378 solo_update_disabled = false;
2382 bool something_soloed = false;
2383 bool same_thing_soloed = false;
2384 bool signal = false;
2386 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2387 if ((*i)->soloed()) {
2388 something_soloed = true;
2389 if (dynamic_cast<AudioTrack*>((*i).get())) {
2391 same_thing_soloed = true;
2396 same_thing_soloed = true;
2404 if (something_soloed != currently_soloing) {
2406 currently_soloing = something_soloed;
2409 modify_solo_mute (is_track, same_thing_soloed);
2412 SoloActive (currently_soloing); /* EMIT SIGNAL */
2415 SoloChanged (); /* EMIT SIGNAL */
2421 Session::update_route_solo_state ()
2424 bool is_track = false;
2425 bool signal = false;
2427 /* this is where we actually implement solo by changing
2428 the solo mute setting of each track.
2431 shared_ptr<RouteList> r = routes.reader ();
2433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2434 if ((*i)->soloed()) {
2436 if (dynamic_cast<AudioTrack*>((*i).get())) {
2443 if (mute != currently_soloing) {
2445 currently_soloing = mute;
2448 if (!is_track && !mute) {
2450 /* nothing is soloed */
2452 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2453 (*i)->set_solo_mute (false);
2463 modify_solo_mute (is_track, mute);
2466 SoloActive (currently_soloing);
2471 Session::modify_solo_mute (bool is_track, bool mute)
2473 shared_ptr<RouteList> r = routes.reader ();
2475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2479 /* only alter track solo mute */
2481 if (dynamic_cast<AudioTrack*>((*i).get())) {
2482 if ((*i)->soloed()) {
2483 (*i)->set_solo_mute (!mute);
2485 (*i)->set_solo_mute (mute);
2491 /* only alter bus solo mute */
2493 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2495 if ((*i)->soloed()) {
2497 (*i)->set_solo_mute (false);
2501 /* don't mute master or control outs
2502 in response to another bus solo
2505 if ((*i) != _master_out &&
2506 (*i) != _control_out) {
2507 (*i)->set_solo_mute (mute);
2518 Session::catch_up_on_solo ()
2520 /* this is called after set_state() to catch the full solo
2521 state, which can't be correctly determined on a per-route
2522 basis, but needs the global overview that only the session
2525 update_route_solo_state();
2529 Session::catch_up_on_solo_mute_override ()
2531 if (Config->get_solo_model() != InverseMute) {
2535 /* this is called whenever the param solo-mute-override is
2538 shared_ptr<RouteList> r = routes.reader ();
2540 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2541 (*i)->catch_up_on_solo_mute_override ();
2546 Session::route_by_name (string name)
2548 shared_ptr<RouteList> r = routes.reader ();
2550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2551 if ((*i)->name() == name) {
2556 return shared_ptr<Route> ((Route*) 0);
2560 Session::route_by_id (PBD::ID id)
2562 shared_ptr<RouteList> r = routes.reader ();
2564 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2565 if ((*i)->id() == id) {
2570 return shared_ptr<Route> ((Route*) 0);
2574 Session::route_by_remote_id (uint32_t id)
2576 shared_ptr<RouteList> r = routes.reader ();
2578 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2579 if ((*i)->remote_control_id() == id) {
2584 return shared_ptr<Route> ((Route*) 0);
2588 Session::find_current_end ()
2590 if (_state_of_the_state & Loading) {
2594 nframes_t max = get_maximum_extent ();
2596 if (max > end_location->end()) {
2597 end_location->set_end (max);
2599 DurationChanged(); /* EMIT SIGNAL */
2604 Session::get_maximum_extent () const
2609 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2611 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2612 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2614 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2615 if ((me = pl->get_maximum_extent()) > max) {
2623 boost::shared_ptr<Diskstream>
2624 Session::diskstream_by_name (string name)
2626 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2628 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2629 if ((*i)->name() == name) {
2634 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2637 boost::shared_ptr<Diskstream>
2638 Session::diskstream_by_id (const PBD::ID& id)
2640 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2642 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2643 if ((*i)->id() == id) {
2648 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2651 /* AudioRegion management */
2654 Session::new_region_name (string old)
2656 string::size_type last_period;
2658 string::size_type len = old.length() + 64;
2661 if ((last_period = old.find_last_of ('.')) == string::npos) {
2663 /* no period present - add one explicitly */
2666 last_period = old.length() - 1;
2671 number = atoi (old.substr (last_period+1).c_str());
2675 while (number < (UINT_MAX-1)) {
2677 AudioRegionList::const_iterator i;
2682 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2685 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2686 if (i->second->name() == sbuf) {
2691 if (i == audio_regions.end()) {
2696 if (number != (UINT_MAX-1)) {
2700 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2705 Session::region_name (string& result, string base, bool newlevel)
2712 Glib::Mutex::Lock lm (region_lock);
2714 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2723 string::size_type pos;
2725 pos = base.find_last_of ('.');
2727 /* pos may be npos, but then we just use entire base */
2729 subbase = base.substr (0, pos);
2734 Glib::Mutex::Lock lm (region_lock);
2736 map<string,uint32_t>::iterator x;
2740 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2742 region_name_map[subbase] = 1;
2745 snprintf (buf, sizeof (buf), ".%d", x->second);
2755 Session::add_region (boost::shared_ptr<Region> region)
2757 vector<boost::shared_ptr<Region> > v;
2758 v.push_back (region);
2763 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2765 boost::shared_ptr<AudioRegion> ar;
2766 boost::shared_ptr<AudioRegion> oar;
2770 Glib::Mutex::Lock lm (region_lock);
2772 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2774 boost::shared_ptr<Region> region = *ii;
2778 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2780 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2782 AudioRegionList::iterator x;
2784 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2786 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2788 if (ar->region_list_equivalent (oar)) {
2793 if (x == audio_regions.end()) {
2795 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2797 entry.first = region->id();
2800 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2811 fatal << _("programming error: ")
2812 << X_("unknown region type passed to Session::add_region()")
2820 /* mark dirty because something has changed even if we didn't
2821 add the region to the region list.
2828 vector<boost::weak_ptr<AudioRegion> > v;
2829 boost::shared_ptr<AudioRegion> first_ar;
2831 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2833 boost::shared_ptr<Region> region = *ii;
2834 boost::shared_ptr<AudioRegion> ar;
2838 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2840 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2848 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2849 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2851 update_region_name_map (region);
2855 AudioRegionsAdded (v); /* EMIT SIGNAL */
2861 Session::update_region_name_map (boost::shared_ptr<Region> region)
2863 string::size_type last_period = region->name().find_last_of ('.');
2865 if (last_period != string::npos && last_period < region->name().length() - 1) {
2867 string base = region->name().substr (0, last_period);
2868 string number = region->name().substr (last_period+1);
2869 map<string,uint32_t>::iterator x;
2871 /* note that if there is no number, we get zero from atoi,
2875 region_name_map[base] = atoi (number);
2880 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2882 boost::shared_ptr<Region> region (weak_region.lock ());
2888 if (what_changed & Region::HiddenChanged) {
2889 /* relay hidden changes */
2890 RegionHiddenChange (region);
2893 if (what_changed & NameChanged) {
2894 update_region_name_map (region);
2899 Session::remove_region (boost::weak_ptr<Region> weak_region)
2901 AudioRegionList::iterator i;
2902 boost::shared_ptr<Region> region (weak_region.lock ());
2908 boost::shared_ptr<AudioRegion> ar;
2909 bool removed = false;
2912 Glib::Mutex::Lock lm (region_lock);
2914 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2915 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2916 audio_regions.erase (i);
2922 fatal << _("programming error: ")
2923 << X_("unknown region type passed to Session::remove_region()")
2929 /* mark dirty because something has changed even if we didn't
2930 remove the region from the region list.
2936 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2940 boost::shared_ptr<AudioRegion>
2941 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2943 AudioRegionList::iterator i;
2944 boost::shared_ptr<AudioRegion> region;
2945 Glib::Mutex::Lock lm (region_lock);
2947 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2951 if (region->whole_file()) {
2953 if (child->source_equivalent (region)) {
2959 return boost::shared_ptr<AudioRegion> ();
2963 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2965 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2966 (*i)->get_region_list_equivalent_regions (region, result);
2970 Session::destroy_region (boost::shared_ptr<Region> region)
2972 vector<boost::shared_ptr<Source> > srcs;
2975 boost::shared_ptr<AudioRegion> aregion;
2977 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2981 if (aregion->playlist()) {
2982 aregion->playlist()->destroy_region (region);
2985 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2986 srcs.push_back (aregion->source (n));
2990 region->drop_references ();
2992 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2994 if (!(*i)->used()) {
2995 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2998 (afs)->mark_for_remove ();
3001 (*i)->drop_references ();
3003 cerr << "source was not used by any playlist\n";
3011 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3013 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3014 destroy_region (*i);
3020 Session::remove_last_capture ()
3022 list<boost::shared_ptr<Region> > r;
3024 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3026 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3027 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3030 r.insert (r.end(), l.begin(), l.end());
3035 destroy_regions (r);
3037 save_state (_current_snapshot_name);
3043 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3049 /* Source Management */
3052 Session::add_source (boost::shared_ptr<Source> source)
3054 boost::shared_ptr<AudioFileSource> afs;
3056 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3058 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3059 pair<AudioSourceList::iterator,bool> result;
3061 entry.first = source->id();
3065 Glib::Mutex::Lock lm (audio_source_lock);
3066 result = audio_sources.insert (entry);
3069 if (result.second) {
3070 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3074 if (Config->get_auto_analyse_audio()) {
3075 Analyser::queue_source_for_analysis (source, false);
3081 Session::remove_source (boost::weak_ptr<Source> src)
3083 AudioSourceList::iterator i;
3084 boost::shared_ptr<Source> source = src.lock();
3091 Glib::Mutex::Lock lm (audio_source_lock);
3093 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3094 audio_sources.erase (i);
3098 if (!_state_of_the_state & InCleanup) {
3100 /* save state so we don't end up with a session file
3101 referring to non-existent sources.
3104 save_state (_current_snapshot_name);
3108 boost::shared_ptr<Source>
3109 Session::source_by_id (const PBD::ID& id)
3111 Glib::Mutex::Lock lm (audio_source_lock);
3112 AudioSourceList::iterator i;
3113 boost::shared_ptr<Source> source;
3115 if ((i = audio_sources.find (id)) != audio_sources.end()) {
3119 /* XXX search MIDI or other searches here */
3125 boost::shared_ptr<Source>
3126 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3128 Glib::Mutex::Lock lm (audio_source_lock);
3130 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3131 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3133 if (afs && afs->path() == path && chn == afs->channel()) {
3138 return boost::shared_ptr<Source>();
3142 Session::peak_path (Glib::ustring base) const
3144 return Glib::build_filename(peak_dir (), base + ".peak");
3148 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3151 string old_basename = PBD::basename_nosuffix (oldname);
3152 string new_legalized = legalize_for_path (newname);
3154 /* note: we know (or assume) the old path is already valid */
3158 /* destructive file sources have a name of the form:
3160 /path/to/Tnnnn-NAME(%[LR])?.wav
3162 the task here is to replace NAME with the new name.
3165 /* find last slash */
3169 string::size_type slash;
3170 string::size_type dash;
3172 if ((slash = path.find_last_of ('/')) == string::npos) {
3176 dir = path.substr (0, slash+1);
3178 /* '-' is not a legal character for the NAME part of the path */
3180 if ((dash = path.find_last_of ('-')) == string::npos) {
3184 prefix = path.substr (slash+1, dash-(slash+1));
3189 path += new_legalized;
3190 path += ".wav"; /* XXX gag me with a spoon */
3194 /* non-destructive file sources have a name of the form:
3196 /path/to/NAME-nnnnn(%[LR])?.wav
3198 the task here is to replace NAME with the new name.
3203 string::size_type slash;
3204 string::size_type dash;
3205 string::size_type postfix;
3207 /* find last slash */
3209 if ((slash = path.find_last_of ('/')) == string::npos) {
3213 dir = path.substr (0, slash+1);
3215 /* '-' is not a legal character for the NAME part of the path */
3217 if ((dash = path.find_last_of ('-')) == string::npos) {
3221 suffix = path.substr (dash+1);
3223 // Suffix is now everything after the dash. Now we need to eliminate
3224 // the nnnnn part, which is done by either finding a '%' or a '.'
3226 postfix = suffix.find_last_of ("%");
3227 if (postfix == string::npos) {
3228 postfix = suffix.find_last_of ('.');
3231 if (postfix != string::npos) {
3232 suffix = suffix.substr (postfix);
3234 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3238 const uint32_t limit = 10000;
3239 char buf[PATH_MAX+1];
3241 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3243 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3245 if (access (buf, F_OK) != 0) {
3253 error << "FATAL ERROR! Could not find a " << endl;
3262 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3266 char buf[PATH_MAX+1];
3267 const uint32_t limit = 10000;
3271 legalized = legalize_for_path (name);
3273 /* find a "version" of the file name that doesn't exist in
3274 any of the possible directories.
3277 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3279 vector<space_and_path>::iterator i;
3280 uint32_t existing = 0;
3282 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3286 spath += sound_dir (false);
3290 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3291 } else if (nchan == 2) {
3293 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3295 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3297 } else if (nchan < 26) {
3298 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3300 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3309 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3310 } else if (nchan == 2) {
3312 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3314 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3316 } else if (nchan < 26) {
3317 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3319 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3323 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3329 if (existing == 0) {
3334 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3336 throw failed_constructor();
3340 /* we now have a unique name for the file, but figure out where to
3346 spath = discover_best_sound_dir ();
3349 string::size_type pos = foo.find_last_of ('/');
3351 if (pos == string::npos) {
3354 spath += foo.substr (pos + 1);
3360 boost::shared_ptr<AudioFileSource>
3361 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3363 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3364 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3367 /* Playlist management */
3369 boost::shared_ptr<Playlist>
3370 Session::playlist_by_name (string name)
3372 Glib::Mutex::Lock lm (playlist_lock);
3373 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3374 if ((*i)->name() == name) {
3378 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3379 if ((*i)->name() == name) {
3384 return boost::shared_ptr<Playlist>();
3388 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3390 if (playlist->hidden()) {
3395 Glib::Mutex::Lock lm (playlist_lock);
3396 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3397 playlists.insert (playlists.begin(), playlist);
3398 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3399 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3405 PlaylistAdded (playlist); /* EMIT SIGNAL */
3409 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3412 Glib::Mutex::Lock lm (playlist_lock);
3413 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3416 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3423 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3425 boost::shared_ptr<Playlist> pl(wpl.lock());
3431 PlaylistList::iterator x;
3434 /* its not supposed to be visible */
3439 Glib::Mutex::Lock lm (playlist_lock);
3443 unused_playlists.insert (pl);
3445 if ((x = playlists.find (pl)) != playlists.end()) {
3446 playlists.erase (x);
3452 playlists.insert (pl);
3454 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3455 unused_playlists.erase (x);
3462 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3464 if (_state_of_the_state & Deletion) {
3468 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3475 Glib::Mutex::Lock lm (playlist_lock);
3477 PlaylistList::iterator i;
3479 i = find (playlists.begin(), playlists.end(), playlist);
3480 if (i != playlists.end()) {
3481 playlists.erase (i);
3484 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3485 if (i != unused_playlists.end()) {
3486 unused_playlists.erase (i);
3493 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3497 Session::set_audition (boost::shared_ptr<Region> r)
3499 pending_audition_region = r;
3500 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3501 schedule_butler_transport_work ();
3505 Session::audition_playlist ()
3507 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3508 ev->region.reset ();
3513 Session::non_realtime_set_audition ()
3515 if (!pending_audition_region) {
3516 auditioner->audition_current_playlist ();
3518 auditioner->audition_region (pending_audition_region);
3519 pending_audition_region.reset ();
3521 AuditionActive (true); /* EMIT SIGNAL */
3525 Session::audition_region (boost::shared_ptr<Region> r)
3527 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3533 Session::cancel_audition ()
3535 if (auditioner->active()) {
3536 auditioner->cancel_audition ();
3537 AuditionActive (false); /* EMIT SIGNAL */
3542 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3544 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3548 Session::remove_empty_sounds ()
3550 PathScanner scanner;
3552 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3554 Glib::Mutex::Lock lm (audio_source_lock);
3556 regex_t compiled_tape_track_pattern;
3559 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3563 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3565 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3569 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3571 /* never remove files that appear to be a tape track */
3573 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3578 if (AudioFileSource::is_empty (*this, **i)) {
3580 unlink ((*i)->c_str());
3582 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3583 unlink (peakpath.c_str());
3589 delete possible_audiofiles;
3593 Session::is_auditioning () const
3595 /* can be called before we have an auditioner object */
3597 return auditioner->active();
3604 Session::set_all_solo (bool yn)
3606 shared_ptr<RouteList> r = routes.reader ();
3608 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3609 if (!(*i)->hidden()) {
3610 (*i)->set_solo (yn, this);
3618 Session::set_all_mute (bool yn)
3620 shared_ptr<RouteList> r = routes.reader ();
3622 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3623 if (!(*i)->hidden()) {
3624 (*i)->set_mute (yn, this);
3632 Session::n_diskstreams () const
3636 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3638 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3639 if (!(*i)->hidden()) {
3647 Session::graph_reordered ()
3649 /* don't do this stuff if we are setting up connections
3650 from a set_state() call or creating new tracks.
3653 if (_state_of_the_state & InitialConnecting) {
3657 /* every track/bus asked for this to be handled but it was deferred because
3658 we were connecting. do it now.
3661 request_input_change_handling ();
3665 /* force all diskstreams to update their capture offset values to
3666 reflect any changes in latencies within the graph.
3669 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3671 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3672 (*i)->set_capture_offset ();
3677 Session::record_disenable_all ()
3679 record_enable_change_all (false);
3683 Session::record_enable_all ()
3685 record_enable_change_all (true);
3689 Session::record_enable_change_all (bool yn)
3691 shared_ptr<RouteList> r = routes.reader ();
3693 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3696 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3697 at->set_record_enable (yn, this);
3701 /* since we don't keep rec-enable state, don't mark session dirty */
3705 Session::add_redirect (Redirect* redirect)
3709 PortInsert* port_insert;
3710 PluginInsert* plugin_insert;
3712 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3713 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3714 _port_inserts.insert (_port_inserts.begin(), port_insert);
3715 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3716 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3718 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3721 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3722 _sends.insert (_sends.begin(), send);
3724 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3728 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3734 Session::remove_redirect (Redirect* redirect)
3738 PortInsert* port_insert;
3739 PluginInsert* plugin_insert;
3741 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3742 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3743 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3744 if (x != _port_inserts.end()) {
3745 insert_bitset[port_insert->bit_slot()] = false;
3746 _port_inserts.erase (x);
3748 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3749 _plugin_inserts.remove (plugin_insert);
3751 fatal << string_compose (_("programming error: %1"),
3752 X_("unknown type of Insert deleted!"))
3756 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3757 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3758 if (x != _sends.end()) {
3759 send_bitset[send->bit_slot()] = false;
3763 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3771 Session::available_capture_duration ()
3773 float sample_bytes_on_disk = 4.0; // keep gcc happy
3775 switch (Config->get_native_file_data_format()) {
3777 sample_bytes_on_disk = 4.0;
3781 sample_bytes_on_disk = 3.0;
3785 sample_bytes_on_disk = 2.0;
3789 /* impossible, but keep some gcc versions happy */
3790 fatal << string_compose (_("programming error: %1"),
3791 X_("illegal native file data format"))
3796 double scale = 4096.0 / sample_bytes_on_disk;
3798 if (_total_free_4k_blocks * scale > (double) max_frames) {
3802 return (nframes_t) floor (_total_free_4k_blocks * scale);
3806 Session::add_connection (ARDOUR::Connection* connection)
3809 Glib::Mutex::Lock guard (connection_lock);
3810 _connections.push_back (connection);
3813 ConnectionAdded (connection); /* EMIT SIGNAL */
3819 Session::remove_connection (ARDOUR::Connection* connection)
3821 bool removed = false;
3824 Glib::Mutex::Lock guard (connection_lock);
3825 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3827 if (i != _connections.end()) {
3828 _connections.erase (i);
3834 ConnectionRemoved (connection); /* EMIT SIGNAL */
3840 ARDOUR::Connection *
3841 Session::connection_by_name (string name) const
3843 Glib::Mutex::Lock lm (connection_lock);
3845 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3846 if ((*i)->name() == name) {
3855 Session::tempo_map_changed (Change ignored)
3859 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3860 (*i)->update_after_tempo_map_change ();
3863 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3864 (*i)->update_after_tempo_map_change ();
3871 Session::ensure_passthru_buffers (uint32_t howmany)
3873 if (current_block_size == 0) {
3877 while (howmany > _passthru_buffers.size()) {
3879 #ifdef NO_POSIX_MEMALIGN
3880 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3882 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3883 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3884 current_block_size, sizeof (Sample), strerror (errno))
3889 _passthru_buffers.push_back (p);
3893 #ifdef NO_POSIX_MEMALIGN
3894 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3896 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3897 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3898 current_block_size, sizeof (Sample), strerror (errno))
3903 memset (p, 0, sizeof (Sample) * current_block_size);
3904 _silent_buffers.push_back (p);
3908 #ifdef NO_POSIX_MEMALIGN
3909 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3911 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3913 memset (p, 0, sizeof (Sample) * current_block_size);
3914 _send_buffers.push_back (p);
3917 allocate_pan_automation_buffers (current_block_size, howmany, false);
3921 Session::next_insert_id ()
3923 /* this doesn't really loop forever. just think about it */
3926 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3927 if (!insert_bitset[n]) {
3928 insert_bitset[n] = true;
3934 /* none available, so resize and try again */
3936 insert_bitset.resize (insert_bitset.size() + 16, false);
3941 Session::next_send_id ()
3943 /* this doesn't really loop forever. just think about it */
3946 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3947 if (!send_bitset[n]) {
3948 send_bitset[n] = true;
3954 /* none available, so resize and try again */
3956 send_bitset.resize (send_bitset.size() + 16, false);
3961 Session::mark_send_id (uint32_t id)
3963 if (id >= send_bitset.size()) {
3964 send_bitset.resize (id+16, false);
3966 if (send_bitset[id]) {
3967 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3969 send_bitset[id] = true;
3973 Session::mark_insert_id (uint32_t id)
3975 if (id >= insert_bitset.size()) {
3976 insert_bitset.resize (id+16, false);
3978 if (insert_bitset[id]) {
3979 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3981 insert_bitset[id] = true;
3984 /* Named Selection management */
3987 Session::named_selection_by_name (string name)
3989 Glib::Mutex::Lock lm (named_selection_lock);
3990 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3991 if ((*i)->name == name) {
3999 Session::add_named_selection (NamedSelection* named_selection)
4002 Glib::Mutex::Lock lm (named_selection_lock);
4003 named_selections.insert (named_selections.begin(), named_selection);
4006 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4012 NamedSelectionAdded (); /* EMIT SIGNAL */
4016 Session::remove_named_selection (NamedSelection* named_selection)
4018 bool removed = false;
4021 Glib::Mutex::Lock lm (named_selection_lock);
4023 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4025 if (i != named_selections.end()) {
4027 named_selections.erase (i);
4034 NamedSelectionRemoved (); /* EMIT SIGNAL */
4039 Session::reset_native_file_format ()
4041 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4043 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4044 (*i)->reset_write_sources (false);
4049 Session::route_name_unique (string n) const
4051 shared_ptr<RouteList> r = routes.reader ();
4053 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4054 if ((*i)->name() == n) {
4063 Session::n_playlists () const
4065 Glib::Mutex::Lock lm (playlist_lock);
4066 return playlists.size();
4070 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4072 if (!force && howmany <= _npan_buffers) {
4076 if (_pan_automation_buffer) {
4078 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4079 delete [] _pan_automation_buffer[i];
4082 delete [] _pan_automation_buffer;
4085 _pan_automation_buffer = new pan_t*[howmany];
4087 for (uint32_t i = 0; i < howmany; ++i) {
4088 _pan_automation_buffer[i] = new pan_t[nframes];
4091 _npan_buffers = howmany;
4095 Session::freeze (InterThreadInfo& itt)
4097 shared_ptr<RouteList> r = routes.reader ();
4099 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4103 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4104 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4114 boost::shared_ptr<Region>
4115 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
4116 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt, bool enable_processing)
4118 boost::shared_ptr<Region> result;
4119 boost::shared_ptr<Playlist> playlist;
4120 boost::shared_ptr<AudioFileSource> fsource;
4122 char buf[PATH_MAX+1];
4126 nframes_t this_chunk;
4128 nframes_t len = end - start;
4129 vector<Sample*> buffers;
4132 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4133 end, start) << endmsg;
4137 // any bigger than this seems to cause stack overflows in called functions
4138 const nframes_t chunk_size = (128 * 1024)/4;
4140 g_atomic_int_set (&processing_prohibited, 1);
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 g_atomic_int_set (&processing_prohibited, 0);
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