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 _send_smpte_update (false),
286 midi_thread (pthread_t (0)),
287 midi_requests (128), // the size of this should match the midi request pool size
288 diskstreams (new DiskstreamList),
289 routes (new RouteList),
290 auditioner ((Auditioner*) 0),
291 _total_free_4k_blocks (0),
294 click_emphasis_data (0),
299 if (!eng.connected()) {
300 throw failed_constructor();
303 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
305 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
306 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
308 first_stage_init (fullpath, snapshot_name);
310 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
313 if (create (new_session, mix_template, compute_initial_length())) {
315 throw failed_constructor ();
319 if (second_stage_init (new_session)) {
321 throw failed_constructor ();
324 store_recent_sessions(_name, _path);
326 bool was_dirty = dirty();
328 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
330 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
333 DirtyChanged (); /* EMIT SIGNAL */
337 Session::Session (AudioEngine &eng,
339 string snapshot_name,
340 AutoConnectOption input_ac,
341 AutoConnectOption output_ac,
342 uint32_t control_out_channels,
343 uint32_t master_out_channels,
344 uint32_t requested_physical_in,
345 uint32_t requested_physical_out,
346 nframes_t initial_length)
350 _mmc_port (default_mmc_port),
351 _mtc_port (default_mtc_port),
352 _midi_port (default_midi_port),
353 pending_events (2048),
355 _send_smpte_update (false),
356 midi_thread (pthread_t (0)),
358 diskstreams (new DiskstreamList),
359 routes (new RouteList),
360 auditioner ((Auditioner *) 0),
361 _total_free_4k_blocks (0),
362 _click_io ((IO *) 0),
364 click_emphasis_data (0),
370 if (!eng.connected()) {
371 throw failed_constructor();
374 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
376 n_physical_audio_outputs = _engine.n_physical_audio_outputs();
377 n_physical_audio_inputs = _engine.n_physical_audio_inputs();
379 if (n_physical_audio_inputs) {
380 n_physical_audio_inputs = max (requested_physical_in, n_physical_audio_inputs);
383 if (n_physical_audio_outputs) {
384 n_physical_audio_outputs = max (requested_physical_out, n_physical_audio_outputs);
387 first_stage_init (fullpath, snapshot_name);
389 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
392 if (create (new_session, string(), initial_length)) {
394 throw failed_constructor ();
399 /* set up Master Out and Control Out if necessary */
404 if (control_out_channels) {
405 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
406 r->set_remote_control_id (control_id++);
411 if (master_out_channels) {
412 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
413 r->set_remote_control_id (control_id);
417 /* prohibit auto-connect to master, because there isn't one */
418 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
422 add_routes (rl, false);
427 Config->set_input_auto_connect (input_ac);
428 Config->set_output_auto_connect (output_ac);
430 if (second_stage_init (new_session)) {
432 throw failed_constructor ();
435 store_recent_sessions (_name, _path);
437 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
440 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
451 /* if we got to here, leaving pending capture state around
455 remove_pending_capture_state ();
457 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
459 _engine.remove_session ();
461 GoingAway (); /* EMIT SIGNAL */
467 /* clear history so that no references to objects are held any more */
471 /* clear state tree so that no references to objects are held any more */
474 terminate_butler_thread ();
475 terminate_midi_thread ();
477 if (click_data != default_click) {
478 delete [] click_data;
481 if (click_emphasis_data != default_click_emphasis) {
482 delete [] click_emphasis_data;
487 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
491 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
495 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
499 AudioDiskstream::free_working_buffers();
501 /* this should cause deletion of the auditioner */
503 // auditioner.reset ();
505 #undef TRACK_DESTRUCTION
506 #ifdef TRACK_DESTRUCTION
507 cerr << "delete named selections\n";
508 #endif /* TRACK_DESTRUCTION */
509 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
510 NamedSelectionList::iterator tmp;
519 #ifdef TRACK_DESTRUCTION
520 cerr << "delete playlists\n";
521 #endif /* TRACK_DESTRUCTION */
522 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
523 PlaylistList::iterator tmp;
528 (*i)->drop_references ();
533 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
534 PlaylistList::iterator tmp;
539 (*i)->drop_references ();
545 unused_playlists.clear ();
547 #ifdef TRACK_DESTRUCTION
548 cerr << "delete audio regions\n";
549 #endif /* TRACK_DESTRUCTION */
551 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
552 AudioRegionList::iterator tmp;
557 i->second->drop_references ();
562 audio_regions.clear ();
564 #ifdef TRACK_DESTRUCTION
565 cerr << "delete routes\n";
566 #endif /* TRACK_DESTRUCTION */
568 RCUWriter<RouteList> writer (routes);
569 boost::shared_ptr<RouteList> r = writer.get_copy ();
570 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
571 (*i)->drop_references ();
574 /* writer goes out of scope and updates master */
579 #ifdef TRACK_DESTRUCTION
580 cerr << "delete diskstreams\n";
581 #endif /* TRACK_DESTRUCTION */
583 RCUWriter<DiskstreamList> dwriter (diskstreams);
584 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
585 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
586 (*i)->drop_references ();
590 diskstreams.flush ();
592 #ifdef TRACK_DESTRUCTION
593 cerr << "delete audio sources\n";
594 #endif /* TRACK_DESTRUCTION */
595 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
596 AudioSourceList::iterator tmp;
601 i->second->drop_references ();
605 audio_sources.clear ();
607 #ifdef TRACK_DESTRUCTION
608 cerr << "delete mix groups\n";
609 #endif /* TRACK_DESTRUCTION */
610 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
611 list<RouteGroup*>::iterator tmp;
621 #ifdef TRACK_DESTRUCTION
622 cerr << "delete edit groups\n";
623 #endif /* TRACK_DESTRUCTION */
624 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
625 list<RouteGroup*>::iterator tmp;
635 #ifdef TRACK_DESTRUCTION
636 cerr << "delete connections\n";
637 #endif /* TRACK_DESTRUCTION */
638 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
639 ConnectionList::iterator tmp;
649 Crossfade::set_buffer_size (0);
655 Session::set_worst_io_latencies ()
657 _worst_output_latency = 0;
658 _worst_input_latency = 0;
660 if (!_engine.connected()) {
664 boost::shared_ptr<RouteList> r = routes.reader ();
666 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
667 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
668 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
673 Session::when_engine_running ()
675 /* we don't want to run execute this again */
677 BootMessage (_("Set block size and sample rate"));
679 set_block_size (_engine.frames_per_cycle());
680 set_frame_rate (_engine.frame_rate());
682 BootMessage (_("Using configuration"));
684 Config->map_parameters (mem_fun (*this, &Session::config_changed));
686 /* every time we reconnect, recompute worst case output latencies */
688 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
690 if (synced_to_jack()) {
691 _engine.transport_stop ();
694 if (Config->get_jack_time_master()) {
695 _engine.transport_locate (_transport_frame);
703 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
705 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
707 /* existing state for Click */
709 if (_click_io->set_state (*child->children().front()) == 0) {
711 _clicking = Config->get_clicking ();
715 error << _("could not setup Click I/O") << endmsg;
721 /* default state for Click: dual-mono to first 2 physical outputs */
723 for (int physport = 0; physport < 2; ++physport) {
724 string physical_output = _engine.get_nth_physical_audio_output (physport);
726 if (physical_output.length()) {
727 if (_click_io->add_output_port (physical_output, this)) {
728 // relax, even though its an error
733 if (_click_io->n_outputs() > 0) {
734 _clicking = Config->get_clicking ();
739 catch (failed_constructor& err) {
740 error << _("cannot setup Click I/O") << endmsg;
743 BootMessage (_("Compute I/O Latencies"));
745 set_worst_io_latencies ();
748 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
751 /* Create a set of Connection objects that map
752 to the physical outputs currently available
755 BootMessage (_("Set up standard connections"));
759 for (uint32_t np = 0; np < n_physical_audio_outputs; ++np) {
761 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
763 Connection* c = new OutputConnection (buf, true);
766 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
771 for (uint32_t np = 0; np < n_physical_audio_inputs; ++np) {
773 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
775 Connection* c = new InputConnection (buf, true);
778 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
785 for (uint32_t np = 0; np < n_physical_audio_outputs; np +=2) {
787 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
789 Connection* c = new OutputConnection (buf, true);
793 c->add_connection (0, _engine.get_nth_physical_audio_output (np));
794 c->add_connection (1, _engine.get_nth_physical_audio_output (np+1));
799 for (uint32_t np = 0; np < n_physical_audio_inputs; np +=2) {
801 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
803 Connection* c = new InputConnection (buf, true);
807 c->add_connection (0, _engine.get_nth_physical_audio_input (np));
808 c->add_connection (1, _engine.get_nth_physical_audio_input (np+1));
817 /* create master/control ports */
822 /* force the master to ignore any later call to this */
824 if (_master_out->pending_state_node) {
825 _master_out->ports_became_legal();
828 /* no panner resets till we are through */
830 _master_out->defer_pan_reset ();
832 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
833 if (_master_out->add_input_port ("", this)) {
834 error << _("cannot setup master inputs")
840 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
841 if (_master_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
842 error << _("cannot setup master outputs")
849 _master_out->allow_pan_reset ();
853 Connection* c = new OutputConnection (_("Master Out"), true);
855 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
857 c->add_connection ((int) n, _master_out->input(n)->name());
862 BootMessage (_("Setup signal flow and plugins"));
866 /* catch up on send+insert cnts */
868 BootMessage (_("Catch up with send/insert state"));
872 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
875 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
876 if (id > insert_cnt) {
884 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
887 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
895 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
897 /* hook us up to the engine */
899 BootMessage (_("Connect to engine"));
901 _engine.set_session (this);
906 BootMessage (_("OSC startup"));
908 osc->set_session (*this);
914 Session::hookup_io ()
916 /* stop graph reordering notifications from
917 causing resorts, etc.
920 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
923 if (auditioner == 0) {
925 /* we delay creating the auditioner till now because
926 it makes its own connections to ports.
927 the engine has to be running for this to work.
931 auditioner.reset (new Auditioner (*this));
934 catch (failed_constructor& err) {
935 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
939 /* Tell all IO objects to create their ports */
945 vector<string> cports;
947 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
948 if (_control_out->add_input_port ("", this)) {
949 error << _("cannot setup control inputs")
955 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
956 if (_control_out->add_output_port (_engine.get_nth_physical_audio_output (n), this)) {
957 error << _("cannot set up master outputs")
965 uint32_t ni = _control_out->n_inputs();
967 for (n = 0; n < ni; ++n) {
968 cports.push_back (_control_out->input(n)->name());
971 boost::shared_ptr<RouteList> r = routes.reader ();
973 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
974 (*x)->set_control_outs (cports);
978 /* Tell all IO objects to connect themselves together */
980 IO::enable_connecting ();
982 /* Now reset all panners */
984 IO::reset_panners ();
986 /* Anyone who cares about input state, wake up and do something */
988 IOConnectionsComplete (); /* EMIT SIGNAL */
990 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
993 /* now handle the whole enchilada as if it was one
999 /* update mixer solo state */
1005 Session::playlist_length_changed ()
1007 /* we can't just increase end_location->end() if pl->get_maximum_extent()
1008 if larger. if the playlist used to be the longest playlist,
1009 and its now shorter, we have to decrease end_location->end(). hence,
1010 we have to iterate over all diskstreams and check the
1011 playlists currently in use.
1013 find_current_end ();
1017 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wptr)
1019 boost::shared_ptr<Diskstream> dstream = wptr.lock();
1026 boost::shared_ptr<Playlist> playlist;
1028 if ((playlist = dstream->playlist()) != 0) {
1029 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
1032 /* see comment in playlist_length_changed () */
1033 find_current_end ();
1037 Session::record_enabling_legal () const
1039 /* this used to be in here, but survey says.... we don't need to restrict it */
1040 // if (record_status() == Recording) {
1044 if (Config->get_all_safe()) {
1051 Session::reset_input_monitor_state ()
1053 if (transport_rolling()) {
1055 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1057 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1058 if ((*i)->record_enabled ()) {
1059 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1060 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1064 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1066 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1067 if ((*i)->record_enabled ()) {
1068 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1069 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1076 Session::auto_punch_start_changed (Location* location)
1078 replace_event (Event::PunchIn, location->start());
1080 if (get_record_enabled() && Config->get_punch_in()) {
1081 /* capture start has been changed, so save new pending state */
1082 save_state ("", true);
1087 Session::auto_punch_end_changed (Location* location)
1089 nframes_t when_to_stop = location->end();
1090 // when_to_stop += _worst_output_latency + _worst_input_latency;
1091 replace_event (Event::PunchOut, when_to_stop);
1095 Session::auto_punch_changed (Location* location)
1097 nframes_t when_to_stop = location->end();
1099 replace_event (Event::PunchIn, location->start());
1100 //when_to_stop += _worst_output_latency + _worst_input_latency;
1101 replace_event (Event::PunchOut, when_to_stop);
1105 Session::auto_loop_changed (Location* location)
1107 replace_event (Event::AutoLoop, location->end(), location->start());
1109 if (transport_rolling() && play_loop) {
1111 // if (_transport_frame > location->end()) {
1113 if (_transport_frame < location->start() || _transport_frame > location->end()) {
1114 // relocate to beginning of loop
1115 clear_events (Event::LocateRoll);
1117 request_locate (location->start(), true);
1120 else if (Config->get_seamless_loop() && !loop_changing) {
1122 // schedule a locate-roll to refill the diskstreams at the
1123 // previous loop end
1124 loop_changing = true;
1126 if (location->end() > last_loopend) {
1127 clear_events (Event::LocateRoll);
1128 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1135 last_loopend = location->end();
1139 Session::set_auto_punch_location (Location* location)
1143 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1144 auto_punch_start_changed_connection.disconnect();
1145 auto_punch_end_changed_connection.disconnect();
1146 auto_punch_changed_connection.disconnect();
1147 existing->set_auto_punch (false, this);
1148 remove_event (existing->start(), Event::PunchIn);
1149 clear_events (Event::PunchOut);
1150 auto_punch_location_changed (0);
1155 if (location == 0) {
1159 if (location->end() <= location->start()) {
1160 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1164 auto_punch_start_changed_connection.disconnect();
1165 auto_punch_end_changed_connection.disconnect();
1166 auto_punch_changed_connection.disconnect();
1168 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1169 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1170 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1172 location->set_auto_punch (true, this);
1175 auto_punch_changed (location);
1177 auto_punch_location_changed (location);
1181 Session::set_auto_loop_location (Location* location)
1185 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1186 auto_loop_start_changed_connection.disconnect();
1187 auto_loop_end_changed_connection.disconnect();
1188 auto_loop_changed_connection.disconnect();
1189 existing->set_auto_loop (false, this);
1190 remove_event (existing->end(), Event::AutoLoop);
1191 auto_loop_location_changed (0);
1196 if (location == 0) {
1200 if (location->end() <= location->start()) {
1201 error << _("Session: you can't use a mark for auto loop") << endmsg;
1205 last_loopend = location->end();
1207 auto_loop_start_changed_connection.disconnect();
1208 auto_loop_end_changed_connection.disconnect();
1209 auto_loop_changed_connection.disconnect();
1211 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1212 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1213 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1215 location->set_auto_loop (true, this);
1217 /* take care of our stuff first */
1219 auto_loop_changed (location);
1221 /* now tell everyone else */
1223 auto_loop_location_changed (location);
1227 Session::locations_added (Location* ignored)
1233 Session::locations_changed ()
1235 _locations.apply (*this, &Session::handle_locations_changed);
1239 Session::handle_locations_changed (Locations::LocationList& locations)
1241 Locations::LocationList::iterator i;
1243 bool set_loop = false;
1244 bool set_punch = false;
1246 for (i = locations.begin(); i != locations.end(); ++i) {
1250 if (location->is_auto_punch()) {
1251 set_auto_punch_location (location);
1254 if (location->is_auto_loop()) {
1255 set_auto_loop_location (location);
1259 if (location->is_start()) {
1260 start_location = location;
1262 if (location->is_end()) {
1263 end_location = location;
1268 set_auto_loop_location (0);
1271 set_auto_punch_location (0);
1278 Session::enable_record ()
1280 /* XXX really atomic compare+swap here */
1281 if (g_atomic_int_get (&_record_status) != Recording) {
1282 g_atomic_int_set (&_record_status, Recording);
1283 _last_record_location = _transport_frame;
1284 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1286 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1287 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1288 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1289 if ((*i)->record_enabled ()) {
1290 (*i)->monitor_input (true);
1295 RecordStateChanged ();
1300 Session::disable_record (bool rt_context, bool force)
1304 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1306 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1307 g_atomic_int_set (&_record_status, Disabled);
1309 if (rs == Recording) {
1310 g_atomic_int_set (&_record_status, Enabled);
1314 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1316 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1317 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1319 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1320 if ((*i)->record_enabled ()) {
1321 (*i)->monitor_input (false);
1326 RecordStateChanged (); /* emit signal */
1329 remove_pending_capture_state ();
1335 Session::step_back_from_record ()
1337 /* XXX really atomic compare+swap here */
1338 if (g_atomic_int_get (&_record_status) == Recording) {
1339 g_atomic_int_set (&_record_status, Enabled);
1341 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1342 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1344 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1345 if ((*i)->record_enabled ()) {
1346 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1347 (*i)->monitor_input (false);
1355 Session::maybe_enable_record ()
1357 g_atomic_int_set (&_record_status, Enabled);
1359 /* this function is currently called from somewhere other than an RT thread.
1360 this save_state() call therefore doesn't impact anything.
1363 save_state ("", true);
1365 if (_transport_speed) {
1366 if (!Config->get_punch_in()) {
1370 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1371 RecordStateChanged (); /* EMIT SIGNAL */
1378 Session::audible_frame () const
1384 if (_transport_speed == 0.0f && non_realtime_work_pending()) {
1385 return last_stop_frame;
1388 /* the first of these two possible settings for "offset"
1389 mean that the audible frame is stationary until
1390 audio emerges from the latency compensation
1393 the second means that the audible frame is stationary
1394 until audio would emerge from a physical port
1395 in the absence of any plugin latency compensation
1398 offset = _worst_output_latency;
1400 if (offset > current_block_size) {
1401 offset -= current_block_size;
1403 /* XXX is this correct? if we have no external
1404 physical connections and everything is internal
1405 then surely this is zero? still, how
1406 likely is that anyway?
1408 offset = current_block_size;
1411 if (synced_to_jack()) {
1412 tf = _engine.transport_frame();
1414 tf = _transport_frame;
1419 if (!non_realtime_work_pending()) {
1423 /* check to see if we have passed the first guaranteed
1424 audible frame past our last stopping position. if not,
1425 the return that last stopping point because in terms
1426 of audible frames, we have not moved yet.
1429 if (_transport_speed > 0.0f) {
1431 if (!play_loop || !have_looped) {
1432 if (tf < last_stop_frame + offset) {
1433 return last_stop_frame;
1442 } else if (_transport_speed < 0.0f) {
1444 /* XXX wot? no backward looping? */
1446 if (tf > last_stop_frame - offset) {
1447 return last_stop_frame;
1459 Session::set_frame_rate (nframes_t frames_per_second)
1461 /** \fn void Session::set_frame_size(nframes_t)
1462 the AudioEngine object that calls this guarantees
1463 that it will not be called while we are also in
1464 ::process(). Its fine to do things that block
1468 _base_frame_rate = frames_per_second;
1472 IO::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1476 // XXX we need some equivalent to this, somehow
1477 // SndFileSource::setup_standard_crossfades (frames_per_second);
1481 /* XXX need to reset/reinstantiate all LADSPA plugins */
1485 Session::set_block_size (nframes_t nframes)
1487 /* the AudioEngine guarantees
1488 that it will not be called while we are also in
1489 ::process(). It is therefore fine to do things that block
1494 vector<Sample*>::iterator i;
1497 current_block_size = nframes;
1499 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1503 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1507 _passthru_buffers.clear ();
1508 _silent_buffers.clear ();
1510 ensure_passthru_buffers (np);
1512 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1516 #ifdef NO_POSIX_MEMALIGN
1517 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1519 posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
1523 memset (*i, 0, sizeof (Sample) * current_block_size);
1527 if (_gain_automation_buffer) {
1528 delete [] _gain_automation_buffer;
1530 _gain_automation_buffer = new gain_t[nframes];
1532 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1534 boost::shared_ptr<RouteList> r = routes.reader ();
1536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1537 (*i)->set_block_size (nframes);
1540 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1541 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1542 (*i)->set_block_size (nframes);
1545 set_worst_io_latencies ();
1550 Session::set_default_fade (float steepness, float fade_msecs)
1553 nframes_t fade_frames;
1555 /* Don't allow fade of less 1 frame */
1557 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1564 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1568 default_fade_msecs = fade_msecs;
1569 default_fade_steepness = steepness;
1572 // jlc, WTF is this!
1573 Glib::RWLock::ReaderLock lm (route_lock);
1574 AudioRegion::set_default_fade (steepness, fade_frames);
1579 /* XXX have to do this at some point */
1580 /* foreach region using default fade, reset, then
1581 refill_all_diskstream_buffers ();
1586 struct RouteSorter {
1587 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1588 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1590 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1593 if (r1->fed_by.empty()) {
1594 if (r2->fed_by.empty()) {
1595 /* no ardour-based connections inbound to either route. just use signal order */
1596 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1598 /* r2 has connections, r1 does not; run r1 early */
1602 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1609 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1611 shared_ptr<Route> r2;
1613 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1614 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1618 /* make a copy of the existing list of routes that feed r1 */
1620 set<shared_ptr<Route> > existing = r1->fed_by;
1622 /* for each route that feeds r1, recurse, marking it as feeding
1626 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1629 /* r2 is a route that feeds r1 which somehow feeds base. mark
1630 base as being fed by r2
1633 rbase->fed_by.insert (r2);
1637 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1641 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1645 /* now recurse, so that we can mark base as being fed by
1646 all routes that feed r2
1649 trace_terminal (r2, rbase);
1656 Session::resort_routes ()
1658 /* don't do anything here with signals emitted
1659 by Routes while we are being destroyed.
1662 if (_state_of_the_state & Deletion) {
1669 RCUWriter<RouteList> writer (routes);
1670 shared_ptr<RouteList> r = writer.get_copy ();
1671 resort_routes_using (r);
1672 /* writer goes out of scope and forces update */
1677 Session::resort_routes_using (shared_ptr<RouteList> r)
1679 RouteList::iterator i, j;
1681 for (i = r->begin(); i != r->end(); ++i) {
1683 (*i)->fed_by.clear ();
1685 for (j = r->begin(); j != r->end(); ++j) {
1687 /* although routes can feed themselves, it will
1688 cause an endless recursive descent if we
1689 detect it. so don't bother checking for
1697 if ((*j)->feeds (*i)) {
1698 (*i)->fed_by.insert (*j);
1703 for (i = r->begin(); i != r->end(); ++i) {
1704 trace_terminal (*i, *i);
1710 /* don't leave dangling references to routes in Route::fed_by */
1712 for (i = r->begin(); i != r->end(); ++i) {
1713 (*i)->fed_by.clear ();
1717 cerr << "finished route resort\n";
1719 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1720 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1727 list<boost::shared_ptr<AudioTrack> >
1728 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1730 char track_name[32];
1731 uint32_t track_id = 0;
1733 uint32_t channels_used = 0;
1735 RouteList new_routes;
1736 list<boost::shared_ptr<AudioTrack> > ret;
1737 uint32_t control_id;
1739 /* count existing audio tracks */
1742 shared_ptr<RouteList> r = routes.reader ();
1744 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1745 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1746 if (!(*i)->hidden()) {
1748 channels_used += (*i)->n_inputs();
1754 vector<string> physinputs;
1755 vector<string> physoutputs;
1756 uint32_t nphysical_in;
1757 uint32_t nphysical_out;
1759 _engine.get_physical_audio_outputs (physoutputs);
1760 _engine.get_physical_audio_inputs (physinputs);
1761 control_id = ntracks() + nbusses() + 1;
1765 /* check for duplicate route names, since we might have pre-existing
1766 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1767 save, close,restart,add new route - first named route is now
1775 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1777 if (route_by_name (track_name) == 0) {
1781 } while (track_id < (UINT_MAX-1));
1783 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1784 nphysical_in = min (n_physical_audio_inputs, (uint32_t) physinputs.size());
1789 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1790 nphysical_out = min (n_physical_audio_outputs, (uint32_t) physinputs.size());
1795 shared_ptr<AudioTrack> track;
1798 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1800 if (track->ensure_io (input_channels, output_channels, false, this)) {
1801 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1802 input_channels, output_channels)
1808 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1812 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1813 port = physinputs[(channels_used+x)%nphysical_in];
1816 if (port.length() && track->connect_input (track->input (x), port, this)) {
1822 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1826 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1827 port = physoutputs[(channels_used+x)%nphysical_out];
1828 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1830 port = _master_out->input (x%_master_out->n_inputs())->name();
1834 if (port.length() && track->connect_output (track->output (x), port, this)) {
1839 channels_used += track->n_inputs ();
1841 track->audio_diskstream()->non_realtime_input_change();
1843 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1844 track->set_remote_control_id (control_id);
1847 new_routes.push_back (track);
1848 ret.push_back (track);
1852 catch (failed_constructor &err) {
1853 error << _("Session: could not create new audio track.") << endmsg;
1856 /* we need to get rid of this, since the track failed to be created */
1857 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1860 RCUWriter<DiskstreamList> writer (diskstreams);
1861 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1862 ds->remove (track->audio_diskstream());
1869 catch (AudioEngine::PortRegistrationFailure& pfe) {
1871 error << pfe.what() << endmsg;
1874 /* we need to get rid of this, since the track failed to be created */
1875 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1878 RCUWriter<DiskstreamList> writer (diskstreams);
1879 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1880 ds->remove (track->audio_diskstream());
1891 if (!new_routes.empty()) {
1892 add_routes (new_routes, true);
1899 Session::set_remote_control_ids ()
1901 RemoteModel m = Config->get_remote_model();
1903 shared_ptr<RouteList> r = routes.reader ();
1905 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1906 if ( MixerOrdered == m) {
1907 long order = (*i)->order_key(N_("signal"));
1908 (*i)->set_remote_control_id( order+1 );
1909 } else if ( EditorOrdered == m) {
1910 long order = (*i)->order_key(N_("editor"));
1911 (*i)->set_remote_control_id( order+1 );
1912 } else if ( UserOrdered == m) {
1913 //do nothing ... only changes to remote id's are initiated by user
1920 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1923 uint32_t bus_id = 1;
1927 uint32_t control_id;
1929 /* count existing audio busses */
1932 shared_ptr<RouteList> r = routes.reader ();
1934 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1935 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1936 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1943 vector<string> physinputs;
1944 vector<string> physoutputs;
1946 _engine.get_physical_audio_outputs (physoutputs);
1947 _engine.get_physical_audio_inputs (physinputs);
1948 control_id = ntracks() + nbusses() + 1;
1953 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1957 if (route_by_name (bus_name) == 0) {
1961 } while (bus_id < (UINT_MAX-1));
1964 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1966 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1967 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1968 input_channels, output_channels)
1973 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1977 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1978 port = physinputs[((n+x)%n_physical_audio_inputs)];
1981 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1986 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs(); ++x) {
1990 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1991 port = physoutputs[((n+x)%n_physical_audio_outputs)];
1992 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1994 port = _master_out->input (x%_master_out->n_inputs())->name();
1998 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2003 bus->set_remote_control_id (control_id);
2006 ret.push_back (bus);
2010 catch (failed_constructor &err) {
2011 error << _("Session: could not create new audio route.") << endmsg;
2015 catch (AudioEngine::PortRegistrationFailure& pfe) {
2016 error << pfe.what() << endmsg;
2026 add_routes (ret, true);
2034 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2038 uint32_t control_id;
2040 uint32_t number = 1;
2042 if (!tree.read (template_path.c_str())) {
2046 XMLNode* node = tree.root();
2048 control_id = ntracks() + nbusses() + 1;
2052 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2054 std::string node_name = IO::name_from_state (*node_copy.children().front());
2056 /* generate a new name by adding a number to the end of the template name */
2059 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2063 if (route_by_name (name) == 0) {
2067 } while (number < UINT_MAX);
2069 if (number == UINT_MAX) {
2070 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2074 IO::set_name_in_state (*node_copy.children().front(), name);
2076 Track::zero_diskstream_id_in_xml (node_copy);
2079 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2082 error << _("Session: cannot create track/bus from template description") << endmsg;
2086 if (boost::dynamic_pointer_cast<Track>(route)) {
2087 /* force input/output change signals so that the new diskstream
2088 picks up the configuration of the route. During session
2089 loading this normally happens in a different way.
2091 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2092 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2095 route->set_remote_control_id (control_id);
2098 ret.push_back (route);
2101 catch (failed_constructor &err) {
2102 error << _("Session: could not create new route from template") << endmsg;
2106 catch (AudioEngine::PortRegistrationFailure& pfe) {
2107 error << pfe.what() << endmsg;
2116 add_routes (ret, true);
2122 boost::shared_ptr<Route>
2123 Session::new_video_track (string name)
2125 uint32_t control_id = ntracks() + nbusses() + 1;
2126 shared_ptr<Route> new_route (
2127 new Route ( *this, name, -1, -1, -1, -1, Route::Flag(0), ARDOUR::DataType::NIL));
2128 new_route->set_remote_control_id (control_id);
2131 rl.push_back (new_route);
2133 RCUWriter<RouteList> writer (routes);
2134 shared_ptr<RouteList> r = writer.get_copy ();
2135 r->insert (r->end(), rl.begin(), rl.end());
2136 resort_routes_using (r);
2142 Session::add_routes (RouteList& new_routes, bool save)
2145 RCUWriter<RouteList> writer (routes);
2146 shared_ptr<RouteList> r = writer.get_copy ();
2147 r->insert (r->end(), new_routes.begin(), new_routes.end());
2148 resort_routes_using (r);
2151 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2153 boost::weak_ptr<Route> wpr (*x);
2155 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2156 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2157 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2158 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2160 if ((*x)->master()) {
2164 if ((*x)->control()) {
2165 _control_out = (*x);
2169 if (_control_out && IO::connecting_legal) {
2171 vector<string> cports;
2172 uint32_t ni = _control_out->n_inputs();
2175 for (n = 0; n < ni; ++n) {
2176 cports.push_back (_control_out->input(n)->name());
2179 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2180 (*x)->set_control_outs (cports);
2187 save_state (_current_snapshot_name);
2190 RouteAdded (new_routes); /* EMIT SIGNAL */
2194 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2196 /* need to do this in case we're rolling at the time, to prevent false underruns */
2197 dstream->do_refill_with_alloc ();
2199 dstream->set_block_size (current_block_size);
2202 RCUWriter<DiskstreamList> writer (diskstreams);
2203 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2204 ds->push_back (dstream);
2205 /* writer goes out of scope, copies ds back to main */
2208 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed),
2209 boost::weak_ptr<Diskstream> (dstream)));
2210 /* this will connect to future changes, and check the current length */
2211 diskstream_playlist_changed (dstream);
2213 dstream->prepare ();
2217 Session::remove_route (shared_ptr<Route> route)
2220 RCUWriter<RouteList> writer (routes);
2221 shared_ptr<RouteList> rs = writer.get_copy ();
2225 /* deleting the master out seems like a dumb
2226 idea, but its more of a UI policy issue
2230 if (route == _master_out) {
2231 _master_out = shared_ptr<Route> ();
2234 if (route == _control_out) {
2235 _control_out = shared_ptr<Route> ();
2237 /* cancel control outs for all routes */
2239 vector<string> empty;
2241 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2242 (*r)->set_control_outs (empty);
2246 update_route_solo_state ();
2248 /* writer goes out of scope, forces route list update */
2251 // FIXME: audio specific
2253 boost::shared_ptr<AudioDiskstream> ds;
2255 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2256 ds = at->audio_diskstream();
2262 RCUWriter<DiskstreamList> dsl (diskstreams);
2263 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2267 diskstreams.flush ();
2270 find_current_end ();
2272 // We need to disconnect the routes inputs and outputs
2274 route->disconnect_inputs (0);
2275 route->disconnect_outputs (0);
2277 update_latency_compensation (false, false);
2280 /* get rid of it from the dead wood collection in the route list manager */
2282 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2286 /* try to cause everyone to drop their references */
2288 route->drop_references ();
2290 sync_order_keys (N_("session"));
2292 /* save the new state of the world */
2294 if (save_state (_current_snapshot_name)) {
2295 save_history (_current_snapshot_name);
2300 Session::route_mute_changed (void* src)
2306 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2308 if (solo_update_disabled) {
2314 boost::shared_ptr<Route> route = wpr.lock ();
2317 /* should not happen */
2318 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2322 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2324 shared_ptr<RouteList> r = routes.reader ();
2326 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2328 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2332 /* don't mess with busses */
2334 if (boost::dynamic_pointer_cast<AudioTrack>(*i) == 0) {
2340 /* don't mess with tracks */
2342 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
2347 if ((*i) != route &&
2348 ((*i)->mix_group () == 0 ||
2349 (*i)->mix_group () != route->mix_group () ||
2350 !route->mix_group ()->is_active())) {
2352 if ((*i)->soloed()) {
2354 /* if its already soloed, and solo latching is enabled,
2355 then leave it as it is.
2358 if (Config->get_solo_latched()) {
2365 solo_update_disabled = true;
2366 (*i)->set_solo (false, src);
2367 solo_update_disabled = false;
2371 bool something_soloed = false;
2372 bool same_thing_soloed = false;
2373 bool signal = false;
2375 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2376 if ((*i)->soloed()) {
2377 something_soloed = true;
2378 if (dynamic_cast<AudioTrack*>((*i).get())) {
2380 same_thing_soloed = true;
2385 same_thing_soloed = true;
2393 if (something_soloed != currently_soloing) {
2395 currently_soloing = something_soloed;
2398 modify_solo_mute (is_track, same_thing_soloed);
2401 SoloActive (currently_soloing); /* EMIT SIGNAL */
2404 SoloChanged (); /* EMIT SIGNAL */
2410 Session::update_route_solo_state ()
2413 bool is_track = false;
2414 bool signal = false;
2416 /* this is where we actually implement solo by changing
2417 the solo mute setting of each track.
2420 shared_ptr<RouteList> r = routes.reader ();
2422 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2423 if ((*i)->soloed()) {
2425 if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2432 if (mute != currently_soloing) {
2434 currently_soloing = mute;
2437 if (!is_track && !mute) {
2439 /* nothing is soloed */
2441 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2442 (*i)->set_solo_mute (false);
2452 modify_solo_mute (is_track, mute);
2455 SoloActive (currently_soloing);
2460 Session::modify_solo_mute (bool is_track, bool mute)
2462 shared_ptr<RouteList> r = routes.reader ();
2464 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2468 /* only alter track solo mute */
2470 if (boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2471 if ((*i)->soloed()) {
2472 (*i)->set_solo_mute (!mute);
2474 (*i)->set_solo_mute (mute);
2480 /* only alter bus solo mute */
2482 if (!boost::dynamic_pointer_cast<AudioTrack>(*i)) {
2484 if ((*i)->soloed()) {
2486 (*i)->set_solo_mute (false);
2490 /* don't mute master or control outs
2491 in response to another bus solo
2494 if ((*i) != _master_out &&
2495 (*i) != _control_out) {
2496 (*i)->set_solo_mute (mute);
2507 Session::catch_up_on_solo ()
2509 /* this is called after set_state() to catch the full solo
2510 state, which can't be correctly determined on a per-route
2511 basis, but needs the global overview that only the session
2514 update_route_solo_state();
2518 Session::catch_up_on_solo_mute_override ()
2520 if (Config->get_solo_model() != InverseMute) {
2524 /* this is called whenever the param solo-mute-override is
2527 shared_ptr<RouteList> r = routes.reader ();
2529 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2530 (*i)->catch_up_on_solo_mute_override ();
2535 Session::route_by_name (string name)
2537 shared_ptr<RouteList> r = routes.reader ();
2539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2540 if ((*i)->name() == name) {
2545 return shared_ptr<Route> ((Route*) 0);
2549 Session::route_by_id (PBD::ID id)
2551 shared_ptr<RouteList> r = routes.reader ();
2553 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2554 if ((*i)->id() == id) {
2559 return shared_ptr<Route> ((Route*) 0);
2563 Session::route_by_remote_id (uint32_t id)
2565 shared_ptr<RouteList> r = routes.reader ();
2567 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2568 if ((*i)->remote_control_id() == id) {
2573 return shared_ptr<Route> ((Route*) 0);
2577 Session::find_current_end ()
2579 if (_state_of_the_state & Loading) {
2583 nframes_t max = get_maximum_extent ();
2585 if (max > end_location->end()) {
2586 end_location->set_end (max);
2588 DurationChanged(); /* EMIT SIGNAL */
2593 Session::get_maximum_extent () const
2598 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2600 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2601 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2603 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2604 if ((me = pl->get_maximum_extent()) > max) {
2612 boost::shared_ptr<Diskstream>
2613 Session::diskstream_by_name (string name)
2615 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2617 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2618 if ((*i)->name() == name) {
2623 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2626 boost::shared_ptr<Diskstream>
2627 Session::diskstream_by_id (const PBD::ID& id)
2629 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2631 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2632 if ((*i)->id() == id) {
2637 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2640 /* AudioRegion management */
2643 Session::new_region_name (string old)
2645 string::size_type last_period;
2647 string::size_type len = old.length() + 64;
2650 if ((last_period = old.find_last_of ('.')) == string::npos) {
2652 /* no period present - add one explicitly */
2655 last_period = old.length() - 1;
2660 number = atoi (old.substr (last_period+1).c_str());
2664 while (number < (UINT_MAX-1)) {
2666 AudioRegionList::const_iterator i;
2671 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2674 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2675 if (i->second->name() == sbuf) {
2680 if (i == audio_regions.end()) {
2685 if (number != (UINT_MAX-1)) {
2689 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2694 Session::region_name (string& result, string base, bool newlevel)
2701 Glib::Mutex::Lock lm (region_lock);
2703 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2712 string::size_type pos;
2714 pos = base.find_last_of ('.');
2716 /* pos may be npos, but then we just use entire base */
2718 subbase = base.substr (0, pos);
2723 Glib::Mutex::Lock lm (region_lock);
2725 map<string,uint32_t>::iterator x;
2729 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2731 region_name_map[subbase] = 1;
2734 snprintf (buf, sizeof (buf), ".%d", x->second);
2744 Session::add_region (boost::shared_ptr<Region> region)
2746 vector<boost::shared_ptr<Region> > v;
2747 v.push_back (region);
2752 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2754 boost::shared_ptr<AudioRegion> ar;
2755 boost::shared_ptr<AudioRegion> oar;
2759 Glib::Mutex::Lock lm (region_lock);
2761 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2763 boost::shared_ptr<Region> region = *ii;
2767 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2769 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2771 AudioRegionList::iterator x;
2773 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2775 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2777 if (ar->region_list_equivalent (oar)) {
2782 if (x == audio_regions.end()) {
2784 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2786 entry.first = region->id();
2789 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2800 fatal << _("programming error: ")
2801 << X_("unknown region type passed to Session::add_region()")
2809 /* mark dirty because something has changed even if we didn't
2810 add the region to the region list.
2817 vector<boost::weak_ptr<AudioRegion> > v;
2818 boost::shared_ptr<AudioRegion> first_ar;
2820 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2822 boost::shared_ptr<Region> region = *ii;
2823 boost::shared_ptr<AudioRegion> ar;
2827 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2829 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2837 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2838 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2840 update_region_name_map (region);
2844 AudioRegionsAdded (v); /* EMIT SIGNAL */
2850 Session::update_region_name_map (boost::shared_ptr<Region> region)
2852 string::size_type last_period = region->name().find_last_of ('.');
2854 if (last_period != string::npos && last_period < region->name().length() - 1) {
2856 string base = region->name().substr (0, last_period);
2857 string number = region->name().substr (last_period+1);
2858 map<string,uint32_t>::iterator x;
2860 /* note that if there is no number, we get zero from atoi,
2864 region_name_map[base] = atoi (number);
2869 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2871 boost::shared_ptr<Region> region (weak_region.lock ());
2877 if (what_changed & Region::HiddenChanged) {
2878 /* relay hidden changes */
2879 RegionHiddenChange (region);
2882 if (what_changed & NameChanged) {
2883 update_region_name_map (region);
2888 Session::remove_region (boost::weak_ptr<Region> weak_region)
2890 AudioRegionList::iterator i;
2891 boost::shared_ptr<Region> region (weak_region.lock ());
2897 boost::shared_ptr<AudioRegion> ar;
2898 bool removed = false;
2901 Glib::Mutex::Lock lm (region_lock);
2903 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2904 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2905 audio_regions.erase (i);
2911 fatal << _("programming error: ")
2912 << X_("unknown region type passed to Session::remove_region()")
2918 /* mark dirty because something has changed even if we didn't
2919 remove the region from the region list.
2925 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2929 boost::shared_ptr<AudioRegion>
2930 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2932 AudioRegionList::iterator i;
2933 boost::shared_ptr<AudioRegion> region;
2934 Glib::Mutex::Lock lm (region_lock);
2936 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2940 if (region->whole_file()) {
2942 if (child->source_equivalent (region)) {
2948 return boost::shared_ptr<AudioRegion> ();
2952 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2954 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2955 (*i)->get_region_list_equivalent_regions (region, result);
2959 Session::destroy_region (boost::shared_ptr<Region> region)
2961 vector<boost::shared_ptr<Source> > srcs;
2964 boost::shared_ptr<AudioRegion> aregion;
2966 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2970 if (aregion->playlist()) {
2971 aregion->playlist()->destroy_region (region);
2974 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2975 srcs.push_back (aregion->source (n));
2979 region->drop_references ();
2981 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2983 if (!(*i)->used()) {
2984 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2987 (afs)->mark_for_remove ();
2990 (*i)->drop_references ();
2992 cerr << "source was not used by any playlist\n";
3000 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3002 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3003 destroy_region (*i);
3009 Session::remove_last_capture ()
3011 list<boost::shared_ptr<Region> > r;
3013 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3015 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3016 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3019 r.insert (r.end(), l.begin(), l.end());
3024 destroy_regions (r);
3026 save_state (_current_snapshot_name);
3032 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3038 /* Source Management */
3041 Session::add_source (boost::shared_ptr<Source> source)
3043 boost::shared_ptr<AudioFileSource> afs;
3045 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3047 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3048 pair<AudioSourceList::iterator,bool> result;
3050 entry.first = source->id();
3054 Glib::Mutex::Lock lm (audio_source_lock);
3055 result = audio_sources.insert (entry);
3058 if (result.second) {
3059 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3063 if (Config->get_auto_analyse_audio()) {
3064 Analyser::queue_source_for_analysis (source, false);
3070 Session::remove_source (boost::weak_ptr<Source> src)
3072 AudioSourceList::iterator i;
3073 boost::shared_ptr<Source> source = src.lock();
3080 Glib::Mutex::Lock lm (audio_source_lock);
3082 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3083 audio_sources.erase (i);
3087 if (!_state_of_the_state & InCleanup) {
3089 /* save state so we don't end up with a session file
3090 referring to non-existent sources.
3093 save_state (_current_snapshot_name);
3097 boost::shared_ptr<Source>
3098 Session::source_by_id (const PBD::ID& id)
3100 Glib::Mutex::Lock lm (audio_source_lock);
3101 AudioSourceList::iterator i;
3102 boost::shared_ptr<Source> source;
3104 if ((i = audio_sources.find (id)) != audio_sources.end()) {
3108 /* XXX search MIDI or other searches here */
3114 boost::shared_ptr<Source>
3115 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3117 Glib::Mutex::Lock lm (audio_source_lock);
3119 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3120 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3122 if (afs && afs->path() == path && chn == afs->channel()) {
3127 return boost::shared_ptr<Source>();
3131 Session::peak_path (Glib::ustring base) const
3133 return Glib::build_filename(peak_dir (), base + ".peak");
3137 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3140 string old_basename = PBD::basename_nosuffix (oldname);
3141 string new_legalized = legalize_for_path (newname);
3143 /* note: we know (or assume) the old path is already valid */
3147 /* destructive file sources have a name of the form:
3149 /path/to/Tnnnn-NAME(%[LR])?.wav
3151 the task here is to replace NAME with the new name.
3154 /* find last slash */
3158 string::size_type slash;
3159 string::size_type dash;
3161 if ((slash = path.find_last_of ('/')) == string::npos) {
3165 dir = path.substr (0, slash+1);
3167 /* '-' is not a legal character for the NAME part of the path */
3169 if ((dash = path.find_last_of ('-')) == string::npos) {
3173 prefix = path.substr (slash+1, dash-(slash+1));
3178 path += new_legalized;
3179 path += ".wav"; /* XXX gag me with a spoon */
3183 /* non-destructive file sources have a name of the form:
3185 /path/to/NAME-nnnnn(%[LR])?.wav
3187 the task here is to replace NAME with the new name.
3192 string::size_type slash;
3193 string::size_type dash;
3194 string::size_type postfix;
3196 /* find last slash */
3198 if ((slash = path.find_last_of ('/')) == string::npos) {
3202 dir = path.substr (0, slash+1);
3204 /* '-' is not a legal character for the NAME part of the path */
3206 if ((dash = path.find_last_of ('-')) == string::npos) {
3210 suffix = path.substr (dash+1);
3212 // Suffix is now everything after the dash. Now we need to eliminate
3213 // the nnnnn part, which is done by either finding a '%' or a '.'
3215 postfix = suffix.find_last_of ("%");
3216 if (postfix == string::npos) {
3217 postfix = suffix.find_last_of ('.');
3220 if (postfix != string::npos) {
3221 suffix = suffix.substr (postfix);
3223 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3227 const uint32_t limit = 10000;
3228 char buf[PATH_MAX+1];
3230 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3232 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3234 if (access (buf, F_OK) != 0) {
3242 error << "FATAL ERROR! Could not find a " << endl;
3251 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3255 char buf[PATH_MAX+1];
3256 const uint32_t limit = 10000;
3260 legalized = legalize_for_path (name);
3262 /* find a "version" of the file name that doesn't exist in
3263 any of the possible directories.
3266 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3268 vector<space_and_path>::iterator i;
3269 uint32_t existing = 0;
3271 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3275 spath += sound_dir (false);
3279 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3280 } else if (nchan == 2) {
3282 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3284 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3286 } else if (nchan < 26) {
3287 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3289 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3298 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3299 } else if (nchan == 2) {
3301 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3303 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3305 } else if (nchan < 26) {
3306 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3308 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3312 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3318 if (existing == 0) {
3323 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3325 throw failed_constructor();
3329 /* we now have a unique name for the file, but figure out where to
3335 spath = discover_best_sound_dir ();
3338 string::size_type pos = foo.find_last_of ('/');
3340 if (pos == string::npos) {
3343 spath += foo.substr (pos + 1);
3349 boost::shared_ptr<AudioFileSource>
3350 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3352 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3353 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3356 /* Playlist management */
3358 boost::shared_ptr<Playlist>
3359 Session::playlist_by_name (string name)
3361 Glib::Mutex::Lock lm (playlist_lock);
3362 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3363 if ((*i)->name() == name) {
3367 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3368 if ((*i)->name() == name) {
3373 return boost::shared_ptr<Playlist>();
3377 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3379 if (playlist->hidden()) {
3384 Glib::Mutex::Lock lm (playlist_lock);
3385 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3386 playlists.insert (playlists.begin(), playlist);
3387 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3388 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3394 PlaylistAdded (playlist); /* EMIT SIGNAL */
3398 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3401 Glib::Mutex::Lock lm (playlist_lock);
3402 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3405 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3412 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3414 boost::shared_ptr<Playlist> pl(wpl.lock());
3420 PlaylistList::iterator x;
3423 /* its not supposed to be visible */
3428 Glib::Mutex::Lock lm (playlist_lock);
3432 unused_playlists.insert (pl);
3434 if ((x = playlists.find (pl)) != playlists.end()) {
3435 playlists.erase (x);
3441 playlists.insert (pl);
3443 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3444 unused_playlists.erase (x);
3451 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3453 if (_state_of_the_state & Deletion) {
3457 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3464 Glib::Mutex::Lock lm (playlist_lock);
3466 PlaylistList::iterator i;
3468 i = find (playlists.begin(), playlists.end(), playlist);
3469 if (i != playlists.end()) {
3470 playlists.erase (i);
3473 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3474 if (i != unused_playlists.end()) {
3475 unused_playlists.erase (i);
3482 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3486 Session::set_audition (boost::shared_ptr<Region> r)
3488 pending_audition_region = r;
3489 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3490 schedule_butler_transport_work ();
3494 Session::audition_playlist ()
3496 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3497 ev->region.reset ();
3502 Session::non_realtime_set_audition ()
3504 if (!pending_audition_region) {
3505 auditioner->audition_current_playlist ();
3507 auditioner->audition_region (pending_audition_region);
3508 pending_audition_region.reset ();
3510 AuditionActive (true); /* EMIT SIGNAL */
3514 Session::audition_region (boost::shared_ptr<Region> r)
3516 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3522 Session::cancel_audition ()
3524 if (auditioner->active()) {
3525 auditioner->cancel_audition ();
3526 AuditionActive (false); /* EMIT SIGNAL */
3531 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3533 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3537 Session::remove_empty_sounds ()
3539 PathScanner scanner;
3541 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3543 Glib::Mutex::Lock lm (audio_source_lock);
3545 regex_t compiled_tape_track_pattern;
3548 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3552 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3554 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3558 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3560 /* never remove files that appear to be a tape track */
3562 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3567 if (AudioFileSource::is_empty (*this, **i)) {
3569 unlink ((*i)->c_str());
3571 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3572 unlink (peakpath.c_str());
3578 delete possible_audiofiles;
3582 Session::is_auditioning () const
3584 /* can be called before we have an auditioner object */
3586 return auditioner->active();
3593 Session::set_all_solo (bool yn)
3595 shared_ptr<RouteList> r = routes.reader ();
3597 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3598 if (!(*i)->hidden()) {
3599 (*i)->set_solo (yn, this);
3607 Session::set_all_mute (bool yn)
3609 shared_ptr<RouteList> r = routes.reader ();
3611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3612 if (!(*i)->hidden()) {
3613 (*i)->set_mute (yn, this);
3621 Session::n_diskstreams () const
3625 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3627 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3628 if (!(*i)->hidden()) {
3636 Session::graph_reordered ()
3638 /* don't do this stuff if we are setting up connections
3639 from a set_state() call or creating new tracks.
3642 if (_state_of_the_state & InitialConnecting) {
3646 /* every track/bus asked for this to be handled but it was deferred because
3647 we were connecting. do it now.
3650 request_input_change_handling ();
3654 /* force all diskstreams to update their capture offset values to
3655 reflect any changes in latencies within the graph.
3658 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3660 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3661 (*i)->set_capture_offset ();
3666 Session::record_disenable_all ()
3668 record_enable_change_all (false);
3672 Session::record_enable_all ()
3674 record_enable_change_all (true);
3678 Session::record_enable_change_all (bool yn)
3680 shared_ptr<RouteList> r = routes.reader ();
3682 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3685 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3686 at->set_record_enable (yn, this);
3690 /* since we don't keep rec-enable state, don't mark session dirty */
3694 Session::add_redirect (Redirect* redirect)
3698 PortInsert* port_insert;
3699 PluginInsert* plugin_insert;
3701 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3702 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3703 _port_inserts.insert (_port_inserts.begin(), port_insert);
3704 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3705 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3707 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3710 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3711 _sends.insert (_sends.begin(), send);
3713 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3717 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3723 Session::remove_redirect (Redirect* redirect)
3727 PortInsert* port_insert;
3728 PluginInsert* plugin_insert;
3730 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3731 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3732 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3733 if (x != _port_inserts.end()) {
3734 insert_bitset[port_insert->bit_slot()] = false;
3735 _port_inserts.erase (x);
3737 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3738 _plugin_inserts.remove (plugin_insert);
3740 fatal << string_compose (_("programming error: %1"),
3741 X_("unknown type of Insert deleted!"))
3745 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3746 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3747 if (x != _sends.end()) {
3748 send_bitset[send->bit_slot()] = false;
3752 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3760 Session::available_capture_duration ()
3762 float sample_bytes_on_disk = 4.0; // keep gcc happy
3764 switch (Config->get_native_file_data_format()) {
3766 sample_bytes_on_disk = 4.0;
3770 sample_bytes_on_disk = 3.0;
3774 sample_bytes_on_disk = 2.0;
3778 /* impossible, but keep some gcc versions happy */
3779 fatal << string_compose (_("programming error: %1"),
3780 X_("illegal native file data format"))
3785 double scale = 4096.0 / sample_bytes_on_disk;
3787 if (_total_free_4k_blocks * scale > (double) max_frames) {
3791 return (nframes_t) floor (_total_free_4k_blocks * scale);
3795 Session::add_connection (ARDOUR::Connection* connection)
3798 Glib::Mutex::Lock guard (connection_lock);
3799 _connections.push_back (connection);
3802 ConnectionAdded (connection); /* EMIT SIGNAL */
3808 Session::remove_connection (ARDOUR::Connection* connection)
3810 bool removed = false;
3813 Glib::Mutex::Lock guard (connection_lock);
3814 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3816 if (i != _connections.end()) {
3817 _connections.erase (i);
3823 ConnectionRemoved (connection); /* EMIT SIGNAL */
3829 ARDOUR::Connection *
3830 Session::connection_by_name (string name) const
3832 Glib::Mutex::Lock lm (connection_lock);
3834 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3835 if ((*i)->name() == name) {
3844 Session::tempo_map_changed (Change ignored)
3848 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3849 (*i)->update_after_tempo_map_change ();
3852 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3853 (*i)->update_after_tempo_map_change ();
3860 Session::ensure_passthru_buffers (uint32_t howmany)
3862 if (current_block_size == 0) {
3866 while (howmany > _passthru_buffers.size()) {
3868 #ifdef NO_POSIX_MEMALIGN
3869 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3871 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3872 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3873 current_block_size, sizeof (Sample), strerror (errno))
3878 _passthru_buffers.push_back (p);
3882 #ifdef NO_POSIX_MEMALIGN
3883 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3885 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3886 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3887 current_block_size, sizeof (Sample), strerror (errno))
3892 memset (p, 0, sizeof (Sample) * current_block_size);
3893 _silent_buffers.push_back (p);
3897 #ifdef NO_POSIX_MEMALIGN
3898 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3900 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3902 memset (p, 0, sizeof (Sample) * current_block_size);
3903 _send_buffers.push_back (p);
3906 allocate_pan_automation_buffers (current_block_size, howmany, false);
3910 Session::next_insert_id ()
3912 /* this doesn't really loop forever. just think about it */
3915 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3916 if (!insert_bitset[n]) {
3917 insert_bitset[n] = true;
3923 /* none available, so resize and try again */
3925 insert_bitset.resize (insert_bitset.size() + 16, false);
3930 Session::next_send_id ()
3932 /* this doesn't really loop forever. just think about it */
3935 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3936 if (!send_bitset[n]) {
3937 send_bitset[n] = true;
3943 /* none available, so resize and try again */
3945 send_bitset.resize (send_bitset.size() + 16, false);
3950 Session::mark_send_id (uint32_t id)
3952 if (id >= send_bitset.size()) {
3953 send_bitset.resize (id+16, false);
3955 if (send_bitset[id]) {
3956 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3958 send_bitset[id] = true;
3962 Session::mark_insert_id (uint32_t id)
3964 if (id >= insert_bitset.size()) {
3965 insert_bitset.resize (id+16, false);
3967 if (insert_bitset[id]) {
3968 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3970 insert_bitset[id] = true;
3973 /* Named Selection management */
3976 Session::named_selection_by_name (string name)
3978 Glib::Mutex::Lock lm (named_selection_lock);
3979 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3980 if ((*i)->name == name) {
3988 Session::add_named_selection (NamedSelection* named_selection)
3991 Glib::Mutex::Lock lm (named_selection_lock);
3992 named_selections.insert (named_selections.begin(), named_selection);
3995 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4001 NamedSelectionAdded (); /* EMIT SIGNAL */
4005 Session::remove_named_selection (NamedSelection* named_selection)
4007 bool removed = false;
4010 Glib::Mutex::Lock lm (named_selection_lock);
4012 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4014 if (i != named_selections.end()) {
4016 named_selections.erase (i);
4023 NamedSelectionRemoved (); /* EMIT SIGNAL */
4028 Session::reset_native_file_format ()
4030 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4032 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4033 (*i)->reset_write_sources (false);
4038 Session::route_name_unique (string n) const
4040 shared_ptr<RouteList> r = routes.reader ();
4042 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4043 if ((*i)->name() == n) {
4052 Session::n_playlists () const
4054 Glib::Mutex::Lock lm (playlist_lock);
4055 return playlists.size();
4059 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4061 if (!force && howmany <= _npan_buffers) {
4065 if (_pan_automation_buffer) {
4067 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4068 delete [] _pan_automation_buffer[i];
4071 delete [] _pan_automation_buffer;
4074 _pan_automation_buffer = new pan_t*[howmany];
4076 for (uint32_t i = 0; i < howmany; ++i) {
4077 _pan_automation_buffer[i] = new pan_t[nframes];
4080 _npan_buffers = howmany;
4084 Session::freeze (InterThreadInfo& itt)
4086 shared_ptr<RouteList> r = routes.reader ();
4088 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4092 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4093 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4103 boost::shared_ptr<Region>
4104 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
4105 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt, bool enable_processing)
4107 boost::shared_ptr<Region> result;
4108 boost::shared_ptr<Playlist> playlist;
4109 boost::shared_ptr<AudioFileSource> fsource;
4111 char buf[PATH_MAX+1];
4115 nframes_t this_chunk;
4117 nframes_t len = end - start;
4118 vector<Sample*> buffers;
4121 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4122 end, start) << endmsg;
4126 // any bigger than this seems to cause stack overflows in called functions
4127 const nframes_t chunk_size = (128 * 1024)/4;
4129 // block all process callback handling
4131 block_processing ();
4133 /* call tree *MUST* hold route_lock */
4135 if ((playlist = track.diskstream()->playlist()) == 0) {
4139 /* external redirects will be a problem */
4141 if (track.has_external_redirects()) {
4145 nchans = track.audio_diskstream()->n_channels();
4147 dir = discover_best_sound_dir ();
4149 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
4151 for (x = 0; x < 99999; ++x) {
4152 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4153 if (access (buf, F_OK) != 0) {
4159 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4164 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
4167 catch (failed_constructor& err) {
4168 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4172 srcs.push_back (fsource);
4175 /* XXX need to flush all redirects */
4180 /* create a set of reasonably-sized buffers */
4182 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4184 #ifdef NO_POSIX_MEMALIGN
4185 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4187 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4189 buffers.push_back (b);
4192 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4193 (*src)->prepare_for_peakfile_writes ();
4196 while (to_do && !itt.cancel) {
4198 this_chunk = min (to_do, chunk_size);
4200 if (track.export_stuff (buffers, nchans, start, this_chunk, enable_processing)) {
4205 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4206 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4209 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4215 start += this_chunk;
4216 to_do -= this_chunk;
4218 itt.progress = (float) (1.0 - ((double) to_do / len));
4227 xnow = localtime (&now);
4229 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4230 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4233 afs->update_header (position, *xnow, now);
4234 afs->flush_header ();
4238 /* construct a region to represent the bounced material */
4240 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4241 region_name_from_path (srcs.front()->name(), true));
4246 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4247 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4250 afs->mark_for_remove ();
4253 (*src)->drop_references ();
4257 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4258 (*src)->done_with_peakfile_writes ();
4262 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4266 unblock_processing ();
4274 Session::get_silent_buffers (uint32_t howmany)
4276 if (howmany > _silent_buffers.size()) {
4278 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4279 howmany, _silent_buffers.size()) << endmsg;
4281 if (howmany > 1000) {
4282 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4286 while (howmany > _silent_buffers.size()) {
4289 #ifdef NO_POSIX_MEMALIGN
4290 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4292 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
4293 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4294 current_block_size, sizeof (Sample), strerror (errno))
4299 _silent_buffers.push_back (p);
4303 for (uint32_t i = 0; i < howmany; ++i) {
4304 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4307 return _silent_buffers;
4311 Session::ntracks () const
4314 shared_ptr<RouteList> r = routes.reader ();
4316 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4317 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4326 Session::nbusses () const
4329 shared_ptr<RouteList> r = routes.reader ();
4331 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4332 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4341 Session::add_automation_list(AutomationList *al)
4343 automation_lists[al->id()] = al;
4347 Session::compute_initial_length ()
4349 return _engine.frame_rate() * 60 * 5;
4353 Session::sync_order_keys (const char* base)
4355 if (!Config->get_sync_all_route_ordering()) {
4356 /* leave order keys as they are */
4360 boost::shared_ptr<RouteList> r = routes.reader ();
4362 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4363 (*i)->sync_order_keys (base);
4366 Route::SyncOrderKeys (base); // EMIT SIGNAL