2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
37 #include <glibmm/fileutils.h>
39 #include <pbd/error.h>
40 #include <glibmm/thread.h>
41 #include <pbd/pathscanner.h>
42 #include <pbd/stl_delete.h>
43 #include <pbd/basename.h>
44 #include <pbd/stacktrace.h>
46 #include <ardour/audioengine.h>
47 #include <ardour/configuration.h>
48 #include <ardour/session.h>
49 #include <ardour/analyser.h>
50 #include <ardour/audio_diskstream.h>
51 #include <ardour/utils.h>
52 #include <ardour/audioplaylist.h>
53 #include <ardour/audioregion.h>
54 #include <ardour/audiofilesource.h>
55 #include <ardour/auditioner.h>
56 #include <ardour/recent_sessions.h>
57 #include <ardour/redirect.h>
58 #include <ardour/send.h>
59 #include <ardour/insert.h>
60 #include <ardour/connection.h>
61 #include <ardour/slave.h>
62 #include <ardour/tempo.h>
63 #include <ardour/audio_track.h>
64 #include <ardour/cycle_timer.h>
65 #include <ardour/named_selection.h>
66 #include <ardour/crossfade.h>
67 #include <ardour/playlist.h>
68 #include <ardour/click.h>
69 #include <ardour/data_type.h>
70 #include <ardour/source_factory.h>
71 #include <ardour/region_factory.h>
74 #include <ardour/osc.h>
80 using namespace ARDOUR;
82 using boost::shared_ptr;
85 static const int CPU_CACHE_ALIGN = 64;
87 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
90 const char* Session::_template_suffix = X_(".template");
91 const char* Session::_statefile_suffix = X_(".ardour");
92 const char* Session::_pending_suffix = X_(".pending");
93 const char* Session::old_sound_dir_name = X_("sounds");
94 const char* Session::sound_dir_name = X_("audiofiles");
95 const char* Session::peak_dir_name = X_("peaks");
96 const char* Session::dead_sound_dir_name = X_("dead_sounds");
97 const char* Session::interchange_dir_name = X_("interchange");
98 const char* Session::export_dir_name = X_("export");
100 bool Session::_disable_all_loaded_plugins = false;
102 Session::compute_peak_t Session::compute_peak = 0;
103 Session::find_peaks_t Session::find_peaks = 0;
104 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
105 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
106 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
108 sigc::signal<void,std::string> Session::Dialog;
109 sigc::signal<int> Session::AskAboutPendingState;
110 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
111 sigc::signal<void> Session::SendFeedback;
113 sigc::signal<void> Session::SMPTEOffsetChanged;
114 sigc::signal<void> Session::StartTimeChanged;
115 sigc::signal<void> Session::EndTimeChanged;
117 sigc::signal<void> Session::AutoBindingOn;
118 sigc::signal<void> Session::AutoBindingOff;
121 sigc::signal<void, std::string, std::string> Session::Exported;
124 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
127 char buf[PATH_MAX+1];
131 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
132 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
138 /* check to see if it exists, and what it is */
140 if (stat (str.c_str(), &statbuf)) {
141 if (errno == ENOENT) {
144 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
152 /* it exists, so it must either be the name
153 of the directory, or the name of the statefile
157 if (S_ISDIR (statbuf.st_mode)) {
159 string::size_type slash = str.find_last_of ('/');
161 if (slash == string::npos) {
163 /* a subdirectory of cwd, so statefile should be ... */
169 tmp += _statefile_suffix;
173 if (stat (tmp.c_str(), &statbuf)) {
174 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
184 /* some directory someplace in the filesystem.
185 the snapshot name is the directory name
190 snapshot = str.substr (slash+1);
194 } else if (S_ISREG (statbuf.st_mode)) {
196 string::size_type slash = str.find_last_of ('/');
197 string::size_type suffix;
199 /* remove the suffix */
201 if (slash != string::npos) {
202 snapshot = str.substr (slash+1);
207 suffix = snapshot.find (_statefile_suffix);
209 if (suffix == string::npos) {
210 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
216 snapshot = snapshot.substr (0, suffix);
218 if (slash == string::npos) {
220 /* we must be in the directory where the
221 statefile lives. get it using cwd().
224 char cwd[PATH_MAX+1];
226 if (getcwd (cwd, sizeof (cwd)) == 0) {
227 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
236 /* full path to the statefile */
238 path = str.substr (0, slash);
243 /* what type of file is it? */
244 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
250 /* its the name of a new directory. get the name
254 string::size_type slash = str.find_last_of ('/');
256 if (slash == string::npos) {
258 /* no slash, just use the name, but clean it up */
260 path = legalize_for_path (str);
266 snapshot = str.substr (slash+1);
273 Session::Session (AudioEngine &eng,
274 const string& fullpath,
275 const string& snapshot_name,
280 _mmc_port (default_mmc_port),
281 _mtc_port (default_mtc_port),
282 _midi_port (default_midi_port),
283 pending_events (2048),
285 butler_mixdown_buffer (0),
286 butler_gain_buffer (0),
287 midi_thread (pthread_t (0)),
288 midi_requests (128), // the size of this should match the midi request pool size
289 diskstreams (new DiskstreamList),
290 routes (new RouteList),
291 auditioner ((Auditioner*) 0),
292 _total_free_4k_blocks (0),
295 click_emphasis_data (0),
300 if (!eng.connected()) {
301 throw failed_constructor();
304 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
306 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
307 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
309 first_stage_init (fullpath, snapshot_name);
311 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
314 if (create (new_session, mix_template, compute_initial_length())) {
316 throw failed_constructor ();
320 if (second_stage_init (new_session)) {
322 throw failed_constructor ();
325 store_recent_sessions(_name, _path);
327 bool was_dirty = dirty();
329 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
331 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
334 DirtyChanged (); /* EMIT SIGNAL */
338 Session::Session (AudioEngine &eng,
340 string snapshot_name,
341 AutoConnectOption input_ac,
342 AutoConnectOption output_ac,
343 uint32_t control_out_channels,
344 uint32_t master_out_channels,
345 uint32_t requested_physical_in,
346 uint32_t requested_physical_out,
347 nframes_t initial_length)
351 _mmc_port (default_mmc_port),
352 _mtc_port (default_mtc_port),
353 _midi_port (default_midi_port),
354 pending_events (2048),
356 butler_mixdown_buffer (0),
357 butler_gain_buffer (0),
358 midi_thread (pthread_t (0)),
360 diskstreams (new DiskstreamList),
361 routes (new RouteList),
362 auditioner ((Auditioner *) 0),
363 _total_free_4k_blocks (0),
364 _click_io ((IO *) 0),
366 click_emphasis_data (0),
372 if (!eng.connected()) {
373 throw failed_constructor();
376 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
378 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
379 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
381 if (n_physical_audio_inputs) {
382 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
385 if (n_physical_audio_outputs) {
386 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
389 first_stage_init (fullpath, snapshot_name);
391 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
394 if (create (new_session, string(), initial_length)) {
396 throw failed_constructor ();
401 /* set up Master Out and Control Out if necessary */
406 if (control_out_channels) {
407 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
408 r->set_remote_control_id (control_id++);
413 if (master_out_channels) {
414 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
415 r->set_remote_control_id (control_id);
419 /* prohibit auto-connect to master, because there isn't one */
420 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
424 add_routes (rl, false);
429 Config->set_input_auto_connect (input_ac);
430 Config->set_output_auto_connect (output_ac);
432 if (second_stage_init (new_session)) {
434 throw failed_constructor ();
437 store_recent_sessions (_name, _path);
439 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
442 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
453 /* if we got to here, leaving pending capture state around
457 remove_pending_capture_state ();
459 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
461 _engine.remove_session ();
463 GoingAway (); /* EMIT SIGNAL */
469 /* clear history so that no references to objects are held any more */
473 /* clear state tree so that no references to objects are held any more */
476 terminate_butler_thread ();
477 terminate_midi_thread ();
479 if (click_data != default_click) {
480 delete [] click_data;
483 if (click_emphasis_data != default_click_emphasis) {
484 delete [] click_emphasis_data;
489 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
493 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
497 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
501 AudioDiskstream::free_working_buffers();
503 /* this should cause deletion of the auditioner */
505 // auditioner.reset ();
507 #undef TRACK_DESTRUCTION
508 #ifdef TRACK_DESTRUCTION
509 cerr << "delete named selections\n";
510 #endif /* TRACK_DESTRUCTION */
511 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
512 NamedSelectionList::iterator tmp;
521 #ifdef TRACK_DESTRUCTION
522 cerr << "delete playlists\n";
523 #endif /* TRACK_DESTRUCTION */
524 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
525 PlaylistList::iterator tmp;
530 (*i)->drop_references ();
535 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
536 PlaylistList::iterator tmp;
541 (*i)->drop_references ();
547 unused_playlists.clear ();
549 #ifdef TRACK_DESTRUCTION
550 cerr << "delete audio regions\n";
551 #endif /* TRACK_DESTRUCTION */
553 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
554 AudioRegionList::iterator tmp;
559 i->second->drop_references ();
564 audio_regions.clear ();
566 #ifdef TRACK_DESTRUCTION
567 cerr << "delete routes\n";
568 #endif /* TRACK_DESTRUCTION */
570 RCUWriter<RouteList> writer (routes);
571 boost::shared_ptr<RouteList> r = writer.get_copy ();
572 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
573 (*i)->drop_references ();
576 /* writer goes out of scope and updates master */
581 #ifdef TRACK_DESTRUCTION
582 cerr << "delete diskstreams\n";
583 #endif /* TRACK_DESTRUCTION */
585 RCUWriter<DiskstreamList> dwriter (diskstreams);
586 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
587 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
588 (*i)->drop_references ();
592 diskstreams.flush ();
594 #ifdef TRACK_DESTRUCTION
595 cerr << "delete audio sources\n";
596 #endif /* TRACK_DESTRUCTION */
597 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
598 AudioSourceList::iterator tmp;
603 i->second->drop_references ();
607 audio_sources.clear ();
609 #ifdef TRACK_DESTRUCTION
610 cerr << "delete mix groups\n";
611 #endif /* TRACK_DESTRUCTION */
612 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
613 list<RouteGroup*>::iterator tmp;
623 #ifdef TRACK_DESTRUCTION
624 cerr << "delete edit groups\n";
625 #endif /* TRACK_DESTRUCTION */
626 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
627 list<RouteGroup*>::iterator tmp;
637 #ifdef TRACK_DESTRUCTION
638 cerr << "delete connections\n";
639 #endif /* TRACK_DESTRUCTION */
640 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
641 ConnectionList::iterator tmp;
651 delete [] butler_mixdown_buffer;
652 delete [] butler_gain_buffer;
654 Crossfade::set_buffer_size (0);
660 Session::set_worst_io_latencies ()
662 _worst_output_latency = 0;
663 _worst_input_latency = 0;
665 if (!_engine.connected()) {
669 boost::shared_ptr<RouteList> r = routes.reader ();
671 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
672 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
673 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
678 Session::when_engine_running ()
680 /* we don't want to run execute this again */
682 BootMessage (_("Set block size and sample rate"));
684 set_block_size (_engine.frames_per_cycle());
685 set_frame_rate (_engine.frame_rate());
687 BootMessage (_("Using configuration"));
689 Config->map_parameters (mem_fun (*this, &Session::config_changed));
691 /* every time we reconnect, recompute worst case output latencies */
693 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
695 if (synced_to_jack()) {
696 _engine.transport_stop ();
699 if (Config->get_jack_time_master()) {
700 _engine.transport_locate (_transport_frame);
708 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
710 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
712 /* existing state for Click */
714 if (_click_io->set_state (*child->children().front()) == 0) {
716 _clicking = Config->get_clicking ();
720 error << _("could not setup Click I/O") << endmsg;
726 /* default state for Click: dual-mono to first 2 physical outputs */
728 for (int physport = 0; physport < 2; ++physport) {
729 string physical_output = _engine.get_nth_physical_audio_output (physport);
731 if (physical_output.length()) {
732 if (_click_io->add_output_port (physical_output, this)) {
733 // relax, even though its an error
738 if (_click_io->n_outputs() > 0) {
739 _clicking = Config->get_clicking ();
744 catch (failed_constructor& err) {
745 error << _("cannot setup Click I/O") << endmsg;
748 BootMessage (_("Compute I/O Latencies"));
750 set_worst_io_latencies ();
753 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
756 /* Create a set of Connection objects that map
757 to the physical outputs currently available
760 BootMessage (_("Set up standard connections"));
764 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
766 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
768 Connection* c = new OutputConnection (buf, true);
771 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
776 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
778 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
780 Connection* c = new InputConnection (buf, true);
783 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
790 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
792 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
794 Connection* c = new OutputConnection (buf, true);
798 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
799 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
804 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
806 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
808 Connection* c = new InputConnection (buf, true);
812 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
813 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
822 /* create master/control ports */
827 /* force the master to ignore any later call to this */
829 if (_master_out->pending_state_node) {
830 _master_out->ports_became_legal();
833 /* no panner resets till we are through */
835 _master_out->defer_pan_reset ();
837 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
838 if (_master_out->add_input_port ("", this)) {
839 error << _("cannot setup master inputs")
845 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
846 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
847 error << _("cannot setup master outputs")
854 _master_out->allow_pan_reset ();
858 Connection* c = new OutputConnection (_("Master Out"), true);
860 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
862 c->add_connection ((int) n, _master_out->input(n)->name());
867 BootMessage (_("Setup signal flow and plugins"));
871 /* catch up on send+insert cnts */
873 BootMessage (_("Catch up with send/insert state"));
877 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
880 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
881 if (id > insert_cnt) {
889 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
892 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
900 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
902 /* hook us up to the engine */
904 BootMessage (_("Connect to engine"));
906 _engine.set_session (this);
911 BootMessage (_("OSC startup"));
913 osc->set_session (*this);
919 Session::hookup_io ()
921 /* stop graph reordering notifications from
922 causing resorts, etc.
925 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
928 if (auditioner == 0) {
930 /* we delay creating the auditioner till now because
931 it makes its own connections to ports.
932 the engine has to be running for this to work.
936 auditioner.reset (new Auditioner (*this));
939 catch (failed_constructor& err) {
940 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
944 /* Tell all IO objects to create their ports */
950 vector<string> cports;
952 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
953 if (_control_out->add_input_port ("", this)) {
954 error << _("cannot setup control inputs")
960 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
961 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
962 error << _("cannot set up master outputs")
970 uint32_t ni = _control_out->n_inputs();
972 for (n = 0; n < ni; ++n) {
973 cports.push_back (_control_out->input(n)->name());
976 boost::shared_ptr<RouteList> r = routes.reader ();
978 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
979 (*x)->set_control_outs (cports);
983 /* Tell all IO objects to connect themselves together */
985 IO::enable_connecting ();
987 /* Now reset all panners */
989 IO::reset_panners ();
991 /* Anyone who cares about input state, wake up and do something */
993 IOConnectionsComplete (); /* EMIT SIGNAL */
995 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
998 /* now handle the whole enchilada as if it was one
1004 /* update mixer solo state */
1010 Session::playlist_length_changed ()
1012 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1013 if larger. if the playlist used to be the longest playlist,
1014 and its now shorter, we have to decrease end_location->end(). hence,
1015 we have to iterate over all diskstreams and check the
1016 playlists currently in use.
1018 find_current_end ();
1022 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1024 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1031 boost::shared_ptr<Playlist> playlist;
1033 if ((playlist = dstream->playlist()) != 0) {
1034 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1037 /* see comment in playlist_length_changed () */
1038 find_current_end ();
1042 Session::record_enabling_legal () const
1044 /* this used to be in here, but survey says.... we don't need to restrict it */
1045 // if (record_status() == Recording) {
1049 if (Config->get_all_safe()) {
1056 Session::reset_input_monitor_state ()
1058 if (transport_rolling()) {
1060 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1062 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1063 if ((*i)->record_enabled ()) {
1064 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1065 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1069 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1071 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1072 if ((*i)->record_enabled ()) {
1073 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1074 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1081 Session::auto_punch_start_changed (Location* location)
1083 replace_event (Event::PunchIn, location->start());
1085 if (get_record_enabled() && Config->get_punch_in()) {
1086 /* capture start has been changed, so save new pending state */
1087 save_state ("", true);
1092 Session::auto_punch_end_changed (Location* location)
1094 nframes_t when_to_stop = location->end();
1095 // when_to_stop += _worst_output_latency + _worst_input_latency;
1096 replace_event (Event::PunchOut, when_to_stop);
1100 Session::auto_punch_changed (Location* location)
1102 nframes_t when_to_stop = location->end();
1104 replace_event (Event::PunchIn, location->start());
1105 //when_to_stop += _worst_output_latency + _worst_input_latency;
1106 replace_event (Event::PunchOut, when_to_stop);
1110 Session::auto_loop_changed (Location* location)
1112 replace_event (Event::AutoLoop, location->end(), location->start());
1114 if (transport_rolling() && play_loop) {
1116 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1118 if (_transport_frame > location->end()) {
1119 // relocate to beginning of loop
1120 clear_events (Event::LocateRoll);
1122 request_locate (location->start(), true);
1125 else if (Config->get_seamless_loop() && !loop_changing) {
1127 // schedule a locate-roll to refill the diskstreams at the
1128 // previous loop end
1129 loop_changing = true;
1131 if (location->end() > last_loopend) {
1132 clear_events (Event::LocateRoll);
1133 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1140 last_loopend = location->end();
1144 Session::set_auto_punch_location (Location* location)
1148 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1149 auto_punch_start_changed_connection.disconnect();
1150 auto_punch_end_changed_connection.disconnect();
1151 auto_punch_changed_connection.disconnect();
1152 existing->set_auto_punch (false, this);
1153 remove_event (existing->start(), Event::PunchIn);
1154 clear_events (Event::PunchOut);
1155 auto_punch_location_changed (0);
1160 if (location == 0) {
1164 if (location->end() <= location->start()) {
1165 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1169 auto_punch_start_changed_connection.disconnect();
1170 auto_punch_end_changed_connection.disconnect();
1171 auto_punch_changed_connection.disconnect();
1173 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1174 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1175 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1177 location->set_auto_punch (true, this);
1180 auto_punch_changed (location);
1182 auto_punch_location_changed (location);
1186 Session::set_auto_loop_location (Location* location)
1190 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1191 auto_loop_start_changed_connection.disconnect();
1192 auto_loop_end_changed_connection.disconnect();
1193 auto_loop_changed_connection.disconnect();
1194 existing->set_auto_loop (false, this);
1195 remove_event (existing->end(), Event::AutoLoop);
1196 auto_loop_location_changed (0);
1201 if (location == 0) {
1205 if (location->end() <= location->start()) {
1206 error << _("Session: you can't use a mark for auto loop") << endmsg;
1210 last_loopend = location->end();
1212 auto_loop_start_changed_connection.disconnect();
1213 auto_loop_end_changed_connection.disconnect();
1214 auto_loop_changed_connection.disconnect();
1216 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1217 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1218 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1220 location->set_auto_loop (true, this);
1222 /* take care of our stuff first */
1224 auto_loop_changed (location);
1226 /* now tell everyone else */
1228 auto_loop_location_changed (location);
1232 Session::locations_added (Location* ignored)
1238 Session::locations_changed ()
1240 _locations.apply (*this, &Session::handle_locations_changed);
1244 Session::handle_locations_changed (Locations::LocationList& locations)
1246 Locations::LocationList::iterator i;
1248 bool set_loop = false;
1249 bool set_punch = false;
1251 for (i = locations.begin(); i != locations.end(); ++i) {
1255 if (location->is_auto_punch()) {
1256 set_auto_punch_location (location);
1259 if (location->is_auto_loop()) {
1260 set_auto_loop_location (location);
1264 if (location->is_start()) {
1265 start_location = location;
1267 if (location->is_end()) {
1268 end_location = location;
1273 set_auto_loop_location (0);
1276 set_auto_punch_location (0);
1283 Session::enable_record ()
1285 /* XXX really atomic compare+swap here */
1286 if (g_atomic_int_get (&_record_status) != Recording) {
1287 g_atomic_int_set (&_record_status, Recording);
1288 _last_record_location = _transport_frame;
1289 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1291 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1292 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1293 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1294 if ((*i)->record_enabled ()) {
1295 (*i)->monitor_input (true);
1300 RecordStateChanged ();
1305 Session::disable_record (bool rt_context, bool force)
1309 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1311 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1312 g_atomic_int_set (&_record_status, Disabled);
1314 if (rs == Recording) {
1315 g_atomic_int_set (&_record_status, Enabled);
1319 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1321 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1325 if ((*i)->record_enabled ()) {
1326 (*i)->monitor_input (false);
1331 RecordStateChanged (); /* emit signal */
1334 remove_pending_capture_state ();
1340 Session::step_back_from_record ()
1342 /* XXX really atomic compare+swap here */
1343 if (g_atomic_int_get (&_record_status) == Recording) {
1344 g_atomic_int_set (&_record_status, Enabled);
1346 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1347 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1349 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1350 if ((*i)->record_enabled ()) {
1351 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1352 (*i)->monitor_input (false);
1360 Session::maybe_enable_record ()
1362 g_atomic_int_set (&_record_status, Enabled);
1364 /* this function is currently called from somewhere other than an RT thread.
1365 this save_state() call therefore doesn't impact anything.
1368 save_state ("", true);
1370 if (_transport_speed) {
1371 if (!Config->get_punch_in()) {
1375 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1376 RecordStateChanged (); /* EMIT SIGNAL */
1383 Session::audible_frame () const
1389 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1390 return last_stop_frame;
1393 /* the first of these two possible settings for "offset"
1394 mean that the audible frame is stationary until
1395 audio emerges from the latency compensation
1398 the second means that the audible frame is stationary
1399 until audio would emerge from a physical port
1400 in the absence of any plugin latency compensation
1403 offset = _worst_output_latency;
1405 if (offset > current_block_size) {
1406 offset -= current_block_size;
1408 /* XXX is this correct? if we have no external
1409 physical connections and everything is internal
1410 then surely this is zero? still, how
1411 likely is that anyway?
1413 offset = current_block_size;
1416 if (synced_to_jack()) {
1417 tf = _engine.transport_frame();
1419 tf = _transport_frame;
1424 if (!non_realtime_work_pending()) {
1428 /* check to see if we have passed the first guaranteed
1429 audible frame past our last stopping position. if not,
1430 the return that last stopping point because in terms
1431 of audible frames, we have not moved yet.
1434 if (_transport_speed > 0.0f) {
1436 if (!play_loop || !have_looped) {
1437 if (tf < last_stop_frame + offset) {
1438 return last_stop_frame;
1447 } else if (_transport_speed < 0.0f) {
1449 /* XXX wot? no backward looping? */
1451 if (tf > last_stop_frame - offset) {
1452 return last_stop_frame;
1464 Session::set_frame_rate (nframes_t frames_per_second)
1466 /** \fn void Session::set_frame_size(nframes_t)
1467 the AudioEngine object that calls this guarantees
1468 that it will not be called while we are also in
1469 ::process(). Its fine to do things that block
1473 _base_frame_rate = frames_per_second;
1477 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1481 // XXX we need some equivalent to this, somehow
1482 // SndFileSource::setup_standard_crossfades (frames_per_second);
1486 /* XXX need to reset/reinstantiate all LADSPA plugins */
1490 Session::set_block_size (nframes_t nframes)
1492 /* the AudioEngine guarantees
1493 that it will not be called while we are also in
1494 ::process(). It is therefore fine to do things that block
1499 vector<Sample*>::iterator i;
1502 current_block_size = nframes;
1504 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1508 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1512 _passthru_buffers.clear ();
1513 _silent_buffers.clear ();
1515 ensure_passthru_buffers (np);
1517 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1521 #ifdef NO_POSIX_MEMALIGN
1522 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1524 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1528 memset (*i, 0, sizeof (Sample) * current_block_size);
1532 if (_gain_automation_buffer) {
1533 delete [] _gain_automation_buffer;
1535 _gain_automation_buffer = new gain_t[nframes];
1537 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1539 boost::shared_ptr<RouteList> r = routes.reader ();
1541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1542 (*i)->set_block_size (nframes);
1545 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1546 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1547 (*i)->set_block_size (nframes);
1550 set_worst_io_latencies ();
1555 Session::set_default_fade (float steepness, float fade_msecs)
1558 nframes_t fade_frames;
1560 /* Don't allow fade of less 1 frame */
1562 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1569 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1573 default_fade_msecs = fade_msecs;
1574 default_fade_steepness = steepness;
1577 // jlc, WTF is this!
1578 Glib::RWLock::ReaderLock lm (route_lock);
1579 AudioRegion::set_default_fade (steepness, fade_frames);
1584 /* XXX have to do this at some point */
1585 /* foreach region using default fade, reset, then
1586 refill_all_diskstream_buffers ();
1591 struct RouteSorter {
1592 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1593 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1595 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1598 if (r1->fed_by.empty()) {
1599 if (r2->fed_by.empty()) {
1600 /* no ardour-based connections inbound to either route. just use signal order */
1601 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1603 /* r2 has connections, r1 does not; run r1 early */
1607 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1614 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1616 shared_ptr<Route> r2;
1618 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1619 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1623 /* make a copy of the existing list of routes that feed r1 */
1625 set<shared_ptr<Route> > existing = r1->fed_by;
1627 /* for each route that feeds r1, recurse, marking it as feeding
1631 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1634 /* r2 is a route that feeds r1 which somehow feeds base. mark
1635 base as being fed by r2
1638 rbase->fed_by.insert (r2);
1642 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1646 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1650 /* now recurse, so that we can mark base as being fed by
1651 all routes that feed r2
1654 trace_terminal (r2, rbase);
1661 Session::resort_routes ()
1663 /* don't do anything here with signals emitted
1664 by Routes while we are being destroyed.
1667 if (_state_of_the_state & Deletion) {
1674 RCUWriter<RouteList> writer (routes);
1675 shared_ptr<RouteList> r = writer.get_copy ();
1676 resort_routes_using (r);
1677 /* writer goes out of scope and forces update */
1682 Session::resort_routes_using (shared_ptr<RouteList> r)
1684 RouteList::iterator i, j;
1686 for (i = r->begin(); i != r->end(); ++i) {
1688 (*i)->fed_by.clear ();
1690 for (j = r->begin(); j != r->end(); ++j) {
1692 /* although routes can feed themselves, it will
1693 cause an endless recursive descent if we
1694 detect it. so don't bother checking for
1702 if ((*j)->feeds (*i)) {
1703 (*i)->fed_by.insert (*j);
1708 for (i = r->begin(); i != r->end(); ++i) {
1709 trace_terminal (*i, *i);
1715 /* don't leave dangling references to routes in Route::fed_by */
1717 for (i = r->begin(); i != r->end(); ++i) {
1718 (*i)->fed_by.clear ();
1722 cerr << "finished route resort\n";
1724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1725 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1732 list<boost::shared_ptr<AudioTrack> >
1733 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1735 char track_name[32];
1736 uint32_t track_id = 0;
1738 uint32_t channels_used = 0;
1740 RouteList new_routes;
1741 list<boost::shared_ptr<AudioTrack> > ret;
1742 uint32_t control_id;
1744 /* count existing audio tracks */
1747 shared_ptr<RouteList> r = routes.reader ();
1749 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1750 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1751 if (!(*i)->hidden()) {
1753 channels_used += (*i)->n_inputs();
1759 vector<string> physinputs;
1760 vector<string> physoutputs;
1761 uint32_t nphysical_in;
1762 uint32_t nphysical_out;
1764 _engine.get_physical_audio_outputs (physoutputs);
1765 _engine.get_physical_audio_inputs (physinputs);
1766 control_id = ntracks() + nbusses() + 1;
1770 /* check for duplicate route names, since we might have pre-existing
1771 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1772 save, close,restart,add new route - first named route is now
1780 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1782 if (route_by_name (track_name) == 0) {
1786 } while (track_id < (UINT_MAX-1));
1788 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1789 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1794 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1795 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1800 shared_ptr<AudioTrack> track;
1803 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1805 if (track->ensure_io (input_channels, output_channels, false, this)) {
1806 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1807 input_channels, output_channels)
1813 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1817 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1818 port = physinputs[(channels_used+x)%nphysical_in];
1821 if (port.length() && track->connect_input (track->input (x), port, this)) {
1827 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1831 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1832 port = physoutputs[(channels_used+x)%nphysical_out];
1833 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1835 port = _master_out->input (x%_master_out->n_inputs())->name();
1839 if (port.length() && track->connect_output (track->output (x), port, this)) {
1844 channels_used += track->n_inputs ();
1846 track->audio_diskstream()->non_realtime_input_change();
1848 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1849 track->set_remote_control_id (control_id);
1852 new_routes.push_back (track);
1853 ret.push_back (track);
1857 catch (failed_constructor &err) {
1858 error << _("Session: could not create new audio track.") << endmsg;
1861 /* we need to get rid of this, since the track failed to be created */
1862 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1865 RCUWriter<DiskstreamList> writer (diskstreams);
1866 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1867 ds->remove (track->audio_diskstream());
1874 catch (AudioEngine::PortRegistrationFailure& pfe) {
1876 error << pfe.what() << endmsg;
1879 /* we need to get rid of this, since the track failed to be created */
1880 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1883 RCUWriter<DiskstreamList> writer (diskstreams);
1884 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1885 ds->remove (track->audio_diskstream());
1896 if (!new_routes.empty()) {
1897 add_routes (new_routes, true);
1904 Session::set_remote_control_ids ()
1906 RemoteModel m = Config->get_remote_model();
1908 shared_ptr<RouteList> r = routes.reader ();
1910 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1911 if ( MixerOrdered == m) {
1912 long order = (*i)->order_key(N_("signal"));
1913 (*i)->set_remote_control_id( order+1 );
1914 } else if ( EditorOrdered == m) {
1915 long order = (*i)->order_key(N_("editor"));
1916 (*i)->set_remote_control_id( order+1 );
1917 } else if ( UserOrdered == m) {
1918 //do nothing ... only changes to remote id's are initiated by user
1925 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1928 uint32_t bus_id = 1;
1932 uint32_t control_id;
1934 /* count existing audio busses */
1937 shared_ptr<RouteList> r = routes.reader ();
1939 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1940 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1941 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1948 vector<string> physinputs;
1949 vector<string> physoutputs;
1951 _engine.get_physical_audio_outputs (physoutputs);
1952 _engine.get_physical_audio_inputs (physinputs);
1953 control_id = ntracks() + nbusses() + 1;
1958 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1962 if (route_by_name (bus_name) == 0) {
1966 } while (bus_id < (UINT_MAX-1));
1969 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1971 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1972 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1973 input_channels, output_channels)
1978 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1982 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1983 port = physinputs[((n+x)%n_physical_audio_inputs)];
1986 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1991 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1995 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1996 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1997 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1999 port = _master_out->input (x%_master_out->n_inputs())->name();
2003 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2008 bus->set_remote_control_id (control_id);
2011 ret.push_back (bus);
2015 catch (failed_constructor &err) {
2016 error << _("Session: could not create new audio route.") << endmsg;
2020 catch (AudioEngine::PortRegistrationFailure& pfe) {
2021 error << pfe.what() << endmsg;
2031 add_routes (ret, true);
2039 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2043 uint32_t control_id;
2045 uint32_t number = 1;
2047 if (!tree.read (template_path.c_str())) {
2051 XMLNode* node = tree.root();
2053 control_id = ntracks() + nbusses() + 1;
2057 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2059 std::string node_name = IO::name_from_state (*node_copy.children().front());
2061 /* generate a new name by adding a number to the end of the template name */
2064 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2068 if (route_by_name (name) == 0) {
2072 } while (number < UINT_MAX);
2074 if (number == UINT_MAX) {
2075 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2079 IO::set_name_in_state (*node_copy.children().front(), name);
2081 Track::zero_diskstream_id_in_xml (node_copy);
2084 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2087 error << _("Session: cannot create track/bus from template description") << endmsg;
2091 if (boost::dynamic_pointer_cast<Track>(route)) {
2092 /* force input/output change signals so that the new diskstream
2093 picks up the configuration of the route. During session
2094 loading this normally happens in a different way.
2096 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2097 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2100 route->set_remote_control_id (control_id);
2103 ret.push_back (route);
2106 catch (failed_constructor &err) {
2107 error << _("Session: could not create new route from template") << endmsg;
2111 catch (AudioEngine::PortRegistrationFailure& pfe) {
2112 error << pfe.what() << endmsg;
2121 add_routes (ret, true);
2127 boost::shared_ptr<Route>
2128 Session::new_video_track (string name)
2130 uint32_t control_id = ntracks() + nbusses() + 1;
2131 shared_ptr<Route> new_route (
2132 new Route ( *this, name, -1, -1, -1, -1, Route::Flag(0), ARDOUR::DataType::NIL));
2133 new_route->set_remote_control_id (control_id);
2136 rl.push_back (new_route);
2138 RCUWriter<RouteList> writer (routes);
2139 shared_ptr<RouteList> r = writer.get_copy ();
2140 r->insert (r->end(), rl.begin(), rl.end());
2141 resort_routes_using (r);
2147 Session::add_routes (RouteList& new_routes, bool save)
2150 RCUWriter<RouteList> writer (routes);
2151 shared_ptr<RouteList> r = writer.get_copy ();
2152 r->insert (r->end(), new_routes.begin(), new_routes.end());
2153 resort_routes_using (r);
2156 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2158 boost::weak_ptr<Route> wpr (*x);
2160 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2161 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2162 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2163 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2165 if ((*x)->master()) {
2169 if ((*x)->control()) {
2170 _control_out = (*x);
2174 if (_control_out && IO::connecting_legal) {
2176 vector<string> cports;
2177 uint32_t ni = _control_out->n_inputs();
2180 for (n = 0; n < ni; ++n) {
2181 cports.push_back (_control_out->input(n)->name());
2184 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2185 (*x)->set_control_outs (cports);
2192 save_state (_current_snapshot_name);
2195 RouteAdded (new_routes); /* EMIT SIGNAL */
2199 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2201 /* need to do this in case we're rolling at the time, to prevent false underruns */
2202 dstream->do_refill_with_alloc ();
2204 dstream->set_block_size (current_block_size);
2207 RCUWriter<DiskstreamList> writer (diskstreams);
2208 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2209 ds->push_back (dstream);
2210 /* writer goes out of scope, copies ds back to main */
2213 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2214 boost::weak_ptr<Diskstream> (dstream)));
2215 /* this will connect to future changes, and check the current length */
2216 diskstream_playlist_changed (dstream);
2218 dstream->prepare ();
2222 Session::remove_route (shared_ptr<Route> route)
2225 RCUWriter<RouteList> writer (routes);
2226 shared_ptr<RouteList> rs = writer.get_copy ();
2230 /* deleting the master out seems like a dumb
2231 idea, but its more of a UI policy issue
2235 if (route == _master_out) {
2236 _master_out = shared_ptr<Route> ();
2239 if (route == _control_out) {
2240 _control_out = shared_ptr<Route> ();
2242 /* cancel control outs for all routes */
2244 vector<string> empty;
2246 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2247 (*r)->set_control_outs (empty);
2251 update_route_solo_state ();
2253 /* writer goes out of scope, forces route list update */
2256 // FIXME: audio specific
2258 boost::shared_ptr<AudioDiskstream> ds;
2260 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2261 ds = at->audio_diskstream();
2267 RCUWriter<DiskstreamList> dsl (diskstreams);
2268 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2272 diskstreams.flush ();
2275 find_current_end ();
2277 // We need to disconnect the routes inputs and outputs
2279 route->disconnect_inputs (0);
2280 route->disconnect_outputs (0);
2282 update_latency_compensation (false, false);
2285 /* get rid of it from the dead wood collection in the route list manager */
2287 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2291 /* try to cause everyone to drop their references */
2293 route->drop_references ();
2295 sync_order_keys (N_("session"));
2297 /* save the new state of the world */
2299 if (save_state (_current_snapshot_name)) {
2300 save_history (_current_snapshot_name);
2305 Session::route_mute_changed (void* src)
2311 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2313 if (solo_update_disabled) {
2319 boost::shared_ptr<Route> route = wpr.lock ();
2322 /* should not happen */
2323 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2327 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2329 shared_ptr<RouteList> r = routes.reader ();
2331 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2333 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2337 /* don't mess with busses */
2339 if (boost::dynamic_pointer_cast<AudioTrack>(*i) == 0) {
2345 /* don't mess with tracks */
2347 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
2352 if ((*i) != route &&
2353 ((*i)->mix_group () == 0 ||
2354 (*i)->mix_group () != route->mix_group () ||
2355 !route->mix_group ()->is_active())) {
2357 if ((*i)->soloed()) {
2359 /* if its already soloed, and solo latching is enabled,
2360 then leave it as it is.
2363 if (Config->get_solo_latched()) {
2370 solo_update_disabled = true;
2371 (*i)->set_solo (false, src);
2372 solo_update_disabled = false;
2376 bool something_soloed = false;
2377 bool same_thing_soloed = false;
2378 bool signal = false;
2380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381 if ((*i)->soloed()) {
2382 something_soloed = true;
2383 if (dynamic_cast<AudioTrack*>((*i).get())) {
2385 same_thing_soloed = true;
2390 same_thing_soloed = true;
2398 if (something_soloed != currently_soloing) {
2400 currently_soloing = something_soloed;
2403 modify_solo_mute (is_track, same_thing_soloed);
2406 SoloActive (currently_soloing); /* EMIT SIGNAL */
2409 SoloChanged (); /* EMIT SIGNAL */
2415 Session::update_route_solo_state ()
2418 bool is_track = false;
2419 bool signal = false;
2421 /* this is where we actually implement solo by changing
2422 the solo mute setting of each track.
2425 shared_ptr<RouteList> r = routes.reader ();
2427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2428 if ((*i)->soloed()) {
2430 if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2437 if (mute != currently_soloing) {
2439 currently_soloing = mute;
2442 if (!is_track && !mute) {
2444 /* nothing is soloed */
2446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2447 (*i)->set_solo_mute (false);
2457 modify_solo_mute (is_track, mute);
2460 SoloActive (currently_soloing);
2465 Session::modify_solo_mute (bool is_track, bool mute)
2467 shared_ptr<RouteList> r = routes.reader ();
2469 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2473 /* only alter track solo mute */
2475 if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2476 if ((*i)->soloed()) {
2477 (*i)->set_solo_mute (!mute);
2479 (*i)->set_solo_mute (mute);
2485 /* only alter bus solo mute */
2487 if (!boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2489 if ((*i)->soloed()) {
2491 (*i)->set_solo_mute (false);
2495 /* don't mute master or control outs
2496 in response to another bus solo
2499 if ((*i) != _master_out &&
2500 (*i) != _control_out) {
2501 (*i)->set_solo_mute (mute);
2512 Session::catch_up_on_solo ()
2514 /* this is called after set_state() to catch the full solo
2515 state, which can't be correctly determined on a per-route
2516 basis, but needs the global overview that only the session
2519 update_route_solo_state();
2523 Session::catch_up_on_solo_mute_override ()
2525 if (Config->get_solo_model() != InverseMute) {
2529 /* this is called whenever the param solo-mute-override is
2532 shared_ptr<RouteList> r = routes.reader ();
2534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2535 (*i)->catch_up_on_solo_mute_override ();
2540 Session::route_by_name (string name)
2542 shared_ptr<RouteList> r = routes.reader ();
2544 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2545 if ((*i)->name() == name) {
2550 return shared_ptr<Route> ((Route*) 0);
2554 Session::route_by_id (PBD::ID id)
2556 shared_ptr<RouteList> r = routes.reader ();
2558 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2559 if ((*i)->id() == id) {
2564 return shared_ptr<Route> ((Route*) 0);
2568 Session::route_by_remote_id (uint32_t id)
2570 shared_ptr<RouteList> r = routes.reader ();
2572 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2573 if ((*i)->remote_control_id() == id) {
2578 return shared_ptr<Route> ((Route*) 0);
2582 Session::find_current_end ()
2584 if (_state_of_the_state & Loading) {
2588 nframes_t max = get_maximum_extent ();
2590 if (max > end_location->end()) {
2591 end_location->set_end (max);
2593 DurationChanged(); /* EMIT SIGNAL */
2598 Session::get_maximum_extent () const
2603 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2605 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2606 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2608 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2609 if ((me = pl->get_maximum_extent()) > max) {
2617 boost::shared_ptr<Diskstream>
2618 Session::diskstream_by_name (string name)
2620 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2622 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2623 if ((*i)->name() == name) {
2628 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2631 boost::shared_ptr<Diskstream>
2632 Session::diskstream_by_id (const PBD::ID& id)
2634 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2636 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2637 if ((*i)->id() == id) {
2642 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2645 /* AudioRegion management */
2648 Session::new_region_name (string old)
2650 string::size_type last_period;
2652 string::size_type len = old.length() + 64;
2655 if ((last_period = old.find_last_of ('.')) == string::npos) {
2657 /* no period present - add one explicitly */
2660 last_period = old.length() - 1;
2665 number = atoi (old.substr (last_period+1).c_str());
2669 while (number < (UINT_MAX-1)) {
2671 AudioRegionList::const_iterator i;
2676 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2679 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2680 if (i->second->name() == sbuf) {
2685 if (i == audio_regions.end()) {
2690 if (number != (UINT_MAX-1)) {
2694 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2699 Session::region_name (string& result, string base, bool newlevel)
2706 Glib::Mutex::Lock lm (region_lock);
2708 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2717 string::size_type pos;
2719 pos = base.find_last_of ('.');
2721 /* pos may be npos, but then we just use entire base */
2723 subbase = base.substr (0, pos);
2728 Glib::Mutex::Lock lm (region_lock);
2730 map<string,uint32_t>::iterator x;
2734 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2736 region_name_map[subbase] = 1;
2739 snprintf (buf, sizeof (buf), ".%d", x->second);
2749 Session::add_region (boost::shared_ptr<Region> region)
2751 vector<boost::shared_ptr<Region> > v;
2752 v.push_back (region);
2757 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2759 boost::shared_ptr<AudioRegion> ar;
2760 boost::shared_ptr<AudioRegion> oar;
2764 Glib::Mutex::Lock lm (region_lock);
2766 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2768 boost::shared_ptr<Region> region = *ii;
2772 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2774 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2776 AudioRegionList::iterator x;
2778 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2780 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2782 if (ar->region_list_equivalent (oar)) {
2787 if (x == audio_regions.end()) {
2789 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2791 entry.first = region->id();
2794 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2805 fatal << _("programming error: ")
2806 << X_("unknown region type passed to Session::add_region()")
2814 /* mark dirty because something has changed even if we didn't
2815 add the region to the region list.
2822 vector<boost::weak_ptr<AudioRegion> > v;
2823 boost::shared_ptr<AudioRegion> first_ar;
2825 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2827 boost::shared_ptr<Region> region = *ii;
2828 boost::shared_ptr<AudioRegion> ar;
2832 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2834 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2842 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2843 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2845 update_region_name_map (region);
2849 AudioRegionsAdded (v); /* EMIT SIGNAL */
2855 Session::update_region_name_map (boost::shared_ptr<Region> region)
2857 string::size_type last_period = region->name().find_last_of ('.');
2859 if (last_period != string::npos && last_period < region->name().length() - 1) {
2861 string base = region->name().substr (0, last_period);
2862 string number = region->name().substr (last_period+1);
2863 map<string,uint32_t>::iterator x;
2865 /* note that if there is no number, we get zero from atoi,
2869 region_name_map[base] = atoi (number);
2874 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2876 boost::shared_ptr<Region> region (weak_region.lock ());
2882 if (what_changed & Region::HiddenChanged) {
2883 /* relay hidden changes */
2884 RegionHiddenChange (region);
2887 if (what_changed & NameChanged) {
2888 update_region_name_map (region);
2893 Session::remove_region (boost::weak_ptr<Region> weak_region)
2895 AudioRegionList::iterator i;
2896 boost::shared_ptr<Region> region (weak_region.lock ());
2902 boost::shared_ptr<AudioRegion> ar;
2903 bool removed = false;
2906 Glib::Mutex::Lock lm (region_lock);
2908 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2909 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2910 audio_regions.erase (i);
2916 fatal << _("programming error: ")
2917 << X_("unknown region type passed to Session::remove_region()")
2923 /* mark dirty because something has changed even if we didn't
2924 remove the region from the region list.
2930 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2934 boost::shared_ptr<AudioRegion>
2935 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2937 AudioRegionList::iterator i;
2938 boost::shared_ptr<AudioRegion> region;
2939 Glib::Mutex::Lock lm (region_lock);
2941 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2945 if (region->whole_file()) {
2947 if (child->source_equivalent (region)) {
2953 return boost::shared_ptr<AudioRegion> ();
2957 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2959 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2960 (*i)->get_region_list_equivalent_regions (region, result);
2964 Session::destroy_region (boost::shared_ptr<Region> region)
2966 vector<boost::shared_ptr<Source> > srcs;
2969 boost::shared_ptr<AudioRegion> aregion;
2971 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2975 if (aregion->playlist()) {
2976 aregion->playlist()->destroy_region (region);
2979 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2980 srcs.push_back (aregion->source (n));
2984 region->drop_references ();
2986 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2988 if (!(*i)->used()) {
2989 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2992 (afs)->mark_for_remove ();
2995 (*i)->drop_references ();
2997 cerr << "source was not used by any playlist\n";
3005 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3007 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3008 destroy_region (*i);
3014 Session::remove_last_capture ()
3016 list<boost::shared_ptr<Region> > r;
3018 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3020 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3021 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3024 r.insert (r.end(), l.begin(), l.end());
3029 destroy_regions (r);
3031 save_state (_current_snapshot_name);
3037 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3043 /* Source Management */
3046 Session::add_source (boost::shared_ptr<Source> source)
3048 boost::shared_ptr<AudioFileSource> afs;
3050 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3052 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3053 pair<AudioSourceList::iterator,bool> result;
3055 entry.first = source->id();
3059 Glib::Mutex::Lock lm (audio_source_lock);
3060 result = audio_sources.insert (entry);
3063 if (result.second) {
3064 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3068 if (Config->get_auto_analyse_audio()) {
3069 Analyser::queue_source_for_analysis (source, false);
3075 Session::remove_source (boost::weak_ptr<Source> src)
3077 AudioSourceList::iterator i;
3078 boost::shared_ptr<Source> source = src.lock();
3085 Glib::Mutex::Lock lm (audio_source_lock);
3087 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3088 audio_sources.erase (i);
3092 if (!_state_of_the_state & InCleanup) {
3094 /* save state so we don't end up with a session file
3095 referring to non-existent sources.
3098 save_state (_current_snapshot_name);
3102 boost::shared_ptr<Source>
3103 Session::source_by_id (const PBD::ID& id)
3105 Glib::Mutex::Lock lm (audio_source_lock);
3106 AudioSourceList::iterator i;
3107 boost::shared_ptr<Source> source;
3109 if ((i = audio_sources.find (id)) != audio_sources.end()) {
3113 /* XXX search MIDI or other searches here */
3119 boost::shared_ptr<Source>
3120 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3122 Glib::Mutex::Lock lm (audio_source_lock);
3124 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3125 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3127 if (afs && afs->path() == path && chn == afs->channel()) {
3132 return boost::shared_ptr<Source>();
3136 Session::peak_path (Glib::ustring base) const
3138 return Glib::build_filename(peak_dir (), base + ".peak");
3142 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3145 string old_basename = PBD::basename_nosuffix (oldname);
3146 string new_legalized = legalize_for_path (newname);
3148 /* note: we know (or assume) the old path is already valid */
3152 /* destructive file sources have a name of the form:
3154 /path/to/Tnnnn-NAME(%[LR])?.wav
3156 the task here is to replace NAME with the new name.
3159 /* find last slash */
3163 string::size_type slash;
3164 string::size_type dash;
3166 if ((slash = path.find_last_of ('/')) == string::npos) {
3170 dir = path.substr (0, slash+1);
3172 /* '-' is not a legal character for the NAME part of the path */
3174 if ((dash = path.find_last_of ('-')) == string::npos) {
3178 prefix = path.substr (slash+1, dash-(slash+1));
3183 path += new_legalized;
3184 path += ".wav"; /* XXX gag me with a spoon */
3188 /* non-destructive file sources have a name of the form:
3190 /path/to/NAME-nnnnn(%[LR])?.wav
3192 the task here is to replace NAME with the new name.
3197 string::size_type slash;
3198 string::size_type dash;
3199 string::size_type postfix;
3201 /* find last slash */
3203 if ((slash = path.find_last_of ('/')) == string::npos) {
3207 dir = path.substr (0, slash+1);
3209 /* '-' is not a legal character for the NAME part of the path */
3211 if ((dash = path.find_last_of ('-')) == string::npos) {
3215 suffix = path.substr (dash+1);
3217 // Suffix is now everything after the dash. Now we need to eliminate
3218 // the nnnnn part, which is done by either finding a '%' or a '.'
3220 postfix = suffix.find_last_of ("%");
3221 if (postfix == string::npos) {
3222 postfix = suffix.find_last_of ('.');
3225 if (postfix != string::npos) {
3226 suffix = suffix.substr (postfix);
3228 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3232 const uint32_t limit = 10000;
3233 char buf[PATH_MAX+1];
3235 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3237 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3239 if (access (buf, F_OK) != 0) {
3247 error << "FATAL ERROR! Could not find a " << endl;
3256 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3260 char buf[PATH_MAX+1];
3261 const uint32_t limit = 10000;
3265 legalized = legalize_for_path (name);
3267 /* find a "version" of the file name that doesn't exist in
3268 any of the possible directories.
3271 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3273 vector<space_and_path>::iterator i;
3274 uint32_t existing = 0;
3276 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3280 spath += sound_dir (false);
3284 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3285 } else if (nchan == 2) {
3287 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3289 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3291 } else if (nchan < 26) {
3292 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3294 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3303 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3304 } else if (nchan == 2) {
3306 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3308 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3310 } else if (nchan < 26) {
3311 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3313 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3317 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3323 if (existing == 0) {
3328 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3330 throw failed_constructor();
3334 /* we now have a unique name for the file, but figure out where to
3340 spath = discover_best_sound_dir ();
3343 string::size_type pos = foo.find_last_of ('/');
3345 if (pos == string::npos) {
3348 spath += foo.substr (pos + 1);
3354 boost::shared_ptr<AudioFileSource>
3355 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3357 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3358 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3361 /* Playlist management */
3363 boost::shared_ptr<Playlist>
3364 Session::playlist_by_name (string name)
3366 Glib::Mutex::Lock lm (playlist_lock);
3367 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3368 if ((*i)->name() == name) {
3372 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3373 if ((*i)->name() == name) {
3378 return boost::shared_ptr<Playlist>();
3382 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3384 if (playlist->hidden()) {
3389 Glib::Mutex::Lock lm (playlist_lock);
3390 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3391 playlists.insert (playlists.begin(), playlist);
3392 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3393 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3399 PlaylistAdded (playlist); /* EMIT SIGNAL */
3403 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3406 Glib::Mutex::Lock lm (playlist_lock);
3407 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3410 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3417 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3419 boost::shared_ptr<Playlist> pl(wpl.lock());
3425 PlaylistList::iterator x;
3428 /* its not supposed to be visible */
3433 Glib::Mutex::Lock lm (playlist_lock);
3437 unused_playlists.insert (pl);
3439 if ((x = playlists.find (pl)) != playlists.end()) {
3440 playlists.erase (x);
3446 playlists.insert (pl);
3448 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3449 unused_playlists.erase (x);
3456 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3458 if (_state_of_the_state & Deletion) {
3462 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3469 Glib::Mutex::Lock lm (playlist_lock);
3471 PlaylistList::iterator i;
3473 i = find (playlists.begin(), playlists.end(), playlist);
3474 if (i != playlists.end()) {
3475 playlists.erase (i);
3478 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3479 if (i != unused_playlists.end()) {
3480 unused_playlists.erase (i);
3487 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3491 Session::set_audition (boost::shared_ptr<Region> r)
3493 pending_audition_region = r;
3494 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3495 schedule_butler_transport_work ();
3499 Session::audition_playlist ()
3501 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3502 ev->region.reset ();
3507 Session::non_realtime_set_audition ()
3509 if (!pending_audition_region) {
3510 auditioner->audition_current_playlist ();
3512 auditioner->audition_region (pending_audition_region);
3513 pending_audition_region.reset ();
3515 AuditionActive (true); /* EMIT SIGNAL */
3519 Session::audition_region (boost::shared_ptr<Region> r)
3521 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3527 Session::cancel_audition ()
3529 if (auditioner->active()) {
3530 auditioner->cancel_audition ();
3531 AuditionActive (false); /* EMIT SIGNAL */
3536 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3538 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3542 Session::remove_empty_sounds ()
3544 PathScanner scanner;
3546 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3548 Glib::Mutex::Lock lm (audio_source_lock);
3550 regex_t compiled_tape_track_pattern;
3553 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3557 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3559 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3563 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3565 /* never remove files that appear to be a tape track */
3567 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3572 if (AudioFileSource::is_empty (*this, **i)) {
3574 unlink ((*i)->c_str());
3576 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3577 unlink (peakpath.c_str());
3583 delete possible_audiofiles;
3587 Session::is_auditioning () const
3589 /* can be called before we have an auditioner object */
3591 return auditioner->active();
3598 Session::set_all_solo (bool yn)
3600 shared_ptr<RouteList> r = routes.reader ();
3602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3603 if (!(*i)->hidden()) {
3604 (*i)->set_solo (yn, this);
3612 Session::set_all_mute (bool yn)
3614 shared_ptr<RouteList> r = routes.reader ();
3616 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3617 if (!(*i)->hidden()) {
3618 (*i)->set_mute (yn, this);
3626 Session::n_diskstreams () const
3630 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3632 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3633 if (!(*i)->hidden()) {
3641 Session::graph_reordered ()
3643 /* don't do this stuff if we are setting up connections
3644 from a set_state() call or creating new tracks.
3647 if (_state_of_the_state & InitialConnecting) {
3651 /* every track/bus asked for this to be handled but it was deferred because
3652 we were connecting. do it now.
3655 request_input_change_handling ();
3659 /* force all diskstreams to update their capture offset values to
3660 reflect any changes in latencies within the graph.
3663 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3665 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3666 (*i)->set_capture_offset ();
3671 Session::record_disenable_all ()
3673 record_enable_change_all (false);
3677 Session::record_enable_all ()
3679 record_enable_change_all (true);
3683 Session::record_enable_change_all (bool yn)
3685 shared_ptr<RouteList> r = routes.reader ();
3687 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3690 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3691 at->set_record_enable (yn, this);
3695 /* since we don't keep rec-enable state, don't mark session dirty */
3699 Session::add_redirect (Redirect* redirect)
3703 PortInsert* port_insert;
3704 PluginInsert* plugin_insert;
3706 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3707 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3708 _port_inserts.insert (_port_inserts.begin(), port_insert);
3709 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3710 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3712 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3715 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3716 _sends.insert (_sends.begin(), send);
3718 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3722 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3728 Session::remove_redirect (Redirect* redirect)
3732 PortInsert* port_insert;
3733 PluginInsert* plugin_insert;
3735 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3736 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3737 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3738 if (x != _port_inserts.end()) {
3739 insert_bitset[port_insert->bit_slot()] = false;
3740 _port_inserts.erase (x);
3742 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3743 _plugin_inserts.remove (plugin_insert);
3745 fatal << string_compose (_("programming error: %1"),
3746 X_("unknown type of Insert deleted!"))
3750 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3751 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3752 if (x != _sends.end()) {
3753 send_bitset[send->bit_slot()] = false;
3757 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3765 Session::available_capture_duration ()
3767 float sample_bytes_on_disk = 4.0; // keep gcc happy
3769 switch (Config->get_native_file_data_format()) {
3771 sample_bytes_on_disk = 4.0;
3775 sample_bytes_on_disk = 3.0;
3779 sample_bytes_on_disk = 2.0;
3783 /* impossible, but keep some gcc versions happy */
3784 fatal << string_compose (_("programming error: %1"),
3785 X_("illegal native file data format"))
3790 double scale = 4096.0 / sample_bytes_on_disk;
3792 if (_total_free_4k_blocks * scale > (double) max_frames) {
3796 return (nframes_t) floor (_total_free_4k_blocks * scale);
3800 Session::add_connection (ARDOUR::Connection* connection)
3803 Glib::Mutex::Lock guard (connection_lock);
3804 _connections.push_back (connection);
3807 ConnectionAdded (connection); /* EMIT SIGNAL */
3813 Session::remove_connection (ARDOUR::Connection* connection)
3815 bool removed = false;
3818 Glib::Mutex::Lock guard (connection_lock);
3819 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3821 if (i != _connections.end()) {
3822 _connections.erase (i);
3828 ConnectionRemoved (connection); /* EMIT SIGNAL */
3834 ARDOUR::Connection *
3835 Session::connection_by_name (string name) const
3837 Glib::Mutex::Lock lm (connection_lock);
3839 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3840 if ((*i)->name() == name) {
3849 Session::tempo_map_changed (Change ignored)
3853 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3854 (*i)->update_after_tempo_map_change ();
3857 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3858 (*i)->update_after_tempo_map_change ();
3865 Session::ensure_passthru_buffers (uint32_t howmany)
3867 if (current_block_size == 0) {
3871 while (howmany > _passthru_buffers.size()) {
3873 #ifdef NO_POSIX_MEMALIGN
3874 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3876 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3877 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3878 current_block_size, sizeof (Sample), strerror (errno))
3883 _passthru_buffers.push_back (p);
3887 #ifdef NO_POSIX_MEMALIGN
3888 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3890 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3891 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3892 current_block_size, sizeof (Sample), strerror (errno))
3897 memset (p, 0, sizeof (Sample) * current_block_size);
3898 _silent_buffers.push_back (p);
3902 #ifdef NO_POSIX_MEMALIGN
3903 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3905 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3907 memset (p, 0, sizeof (Sample) * current_block_size);
3908 _send_buffers.push_back (p);
3911 allocate_pan_automation_buffers (current_block_size, howmany, false);
3915 Session::next_insert_id ()
3917 /* this doesn't really loop forever. just think about it */
3920 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3921 if (!insert_bitset[n]) {
3922 insert_bitset[n] = true;
3928 /* none available, so resize and try again */
3930 insert_bitset.resize (insert_bitset.size() + 16, false);
3935 Session::next_send_id ()
3937 /* this doesn't really loop forever. just think about it */
3940 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3941 if (!send_bitset[n]) {
3942 send_bitset[n] = true;
3948 /* none available, so resize and try again */
3950 send_bitset.resize (send_bitset.size() + 16, false);
3955 Session::mark_send_id (uint32_t id)
3957 if (id >= send_bitset.size()) {
3958 send_bitset.resize (id+16, false);
3960 if (send_bitset[id]) {
3961 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3963 send_bitset[id] = true;
3967 Session::mark_insert_id (uint32_t id)
3969 if (id >= insert_bitset.size()) {
3970 insert_bitset.resize (id+16, false);
3972 if (insert_bitset[id]) {
3973 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3975 insert_bitset[id] = true;
3978 /* Named Selection management */
3981 Session::named_selection_by_name (string name)
3983 Glib::Mutex::Lock lm (named_selection_lock);
3984 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3985 if ((*i)->name == name) {
3993 Session::add_named_selection (NamedSelection* named_selection)
3996 Glib::Mutex::Lock lm (named_selection_lock);
3997 named_selections.insert (named_selections.begin(), named_selection);
4000 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4006 NamedSelectionAdded (); /* EMIT SIGNAL */
4010 Session::remove_named_selection (NamedSelection* named_selection)
4012 bool removed = false;
4015 Glib::Mutex::Lock lm (named_selection_lock);
4017 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4019 if (i != named_selections.end()) {
4021 named_selections.erase (i);
4028 NamedSelectionRemoved (); /* EMIT SIGNAL */
4033 Session::reset_native_file_format ()
4035 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4037 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4038 (*i)->reset_write_sources (false);
4043 Session::route_name_unique (string n) const
4045 shared_ptr<RouteList> r = routes.reader ();
4047 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4048 if ((*i)->name() == n) {
4057 Session::n_playlists () const
4059 Glib::Mutex::Lock lm (playlist_lock);
4060 return playlists.size();
4064 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4066 if (!force && howmany <= _npan_buffers) {
4070 if (_pan_automation_buffer) {
4072 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4073 delete [] _pan_automation_buffer[i];
4076 delete [] _pan_automation_buffer;
4079 _pan_automation_buffer = new pan_t*[howmany];
4081 for (uint32_t i = 0; i < howmany; ++i) {
4082 _pan_automation_buffer[i] = new pan_t[nframes];
4085 _npan_buffers = howmany;
4089 Session::freeze (InterThreadInfo& itt)
4091 shared_ptr<RouteList> r = routes.reader ();
4093 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4097 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4098 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4108 boost::shared_ptr<Region>
4109 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
4110 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt, bool enable_processing)
4112 boost::shared_ptr<Region> result;
4113 boost::shared_ptr<Playlist> playlist;
4114 boost::shared_ptr<AudioFileSource> fsource;
4116 char buf[PATH_MAX+1];
4120 nframes_t this_chunk;
4122 nframes_t len = end - start;
4123 vector<Sample*> buffers;
4126 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4127 end, start) << endmsg;
4131 // any bigger than this seems to cause stack overflows in called functions
4132 const nframes_t chunk_size = (128 * 1024)/4;
4134 // block all process callback handling
4136 block_processing ();
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, enable_processing)) {
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 unblock_processing ();
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