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::io_name_is_legal (const std::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) {
2544 if ((*i)->has_io_redirect_named (name)) {
2553 Session::route_by_name (const std::string& name)
2555 shared_ptr<RouteList> r = routes.reader ();
2557 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2558 if ((*i)->name() == name) {
2563 return shared_ptr<Route> ((Route*) 0);
2567 Session::route_by_id (PBD::ID id)
2569 shared_ptr<RouteList> r = routes.reader ();
2571 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2572 if ((*i)->id() == id) {
2577 return shared_ptr<Route> ((Route*) 0);
2581 Session::route_by_remote_id (uint32_t id)
2583 shared_ptr<RouteList> r = routes.reader ();
2585 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2586 if ((*i)->remote_control_id() == id) {
2591 return shared_ptr<Route> ((Route*) 0);
2595 Session::find_current_end ()
2597 if (_state_of_the_state & Loading) {
2601 nframes_t max = get_maximum_extent ();
2603 if (max > end_location->end()) {
2604 end_location->set_end (max);
2606 DurationChanged(); /* EMIT SIGNAL */
2611 Session::get_maximum_extent () const
2616 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2618 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2619 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2621 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2622 if ((me = pl->get_maximum_extent()) > max) {
2630 boost::shared_ptr<Diskstream>
2631 Session::diskstream_by_name (string name)
2633 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2635 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2636 if ((*i)->name() == name) {
2641 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2644 boost::shared_ptr<Diskstream>
2645 Session::diskstream_by_id (const PBD::ID& id)
2647 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2649 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2650 if ((*i)->id() == id) {
2655 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2658 /* AudioRegion management */
2661 Session::new_region_name (string old)
2663 string::size_type last_period;
2665 string::size_type len = old.length() + 64;
2668 if ((last_period = old.find_last_of ('.')) == string::npos) {
2670 /* no period present - add one explicitly */
2673 last_period = old.length() - 1;
2678 number = atoi (old.substr (last_period+1).c_str());
2682 while (number < (UINT_MAX-1)) {
2684 AudioRegionList::const_iterator i;
2689 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2692 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2693 if (i->second->name() == sbuf) {
2698 if (i == audio_regions.end()) {
2703 if (number != (UINT_MAX-1)) {
2707 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2712 Session::region_name (string& result, string base, bool newlevel)
2719 Glib::Mutex::Lock lm (region_lock);
2721 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2730 string::size_type pos;
2732 pos = base.find_last_of ('.');
2734 /* pos may be npos, but then we just use entire base */
2736 subbase = base.substr (0, pos);
2741 Glib::Mutex::Lock lm (region_lock);
2743 map<string,uint32_t>::iterator x;
2747 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2749 region_name_map[subbase] = 1;
2752 snprintf (buf, sizeof (buf), ".%d", x->second);
2762 Session::add_region (boost::shared_ptr<Region> region)
2764 vector<boost::shared_ptr<Region> > v;
2765 v.push_back (region);
2770 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2772 boost::shared_ptr<AudioRegion> ar;
2773 boost::shared_ptr<AudioRegion> oar;
2777 Glib::Mutex::Lock lm (region_lock);
2779 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2781 boost::shared_ptr<Region> region = *ii;
2785 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2787 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2789 AudioRegionList::iterator x;
2791 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2793 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2795 if (ar->region_list_equivalent (oar)) {
2800 if (x == audio_regions.end()) {
2802 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2804 entry.first = region->id();
2807 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2818 fatal << _("programming error: ")
2819 << X_("unknown region type passed to Session::add_region()")
2827 /* mark dirty because something has changed even if we didn't
2828 add the region to the region list.
2835 vector<boost::weak_ptr<AudioRegion> > v;
2836 boost::shared_ptr<AudioRegion> first_ar;
2838 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2840 boost::shared_ptr<Region> region = *ii;
2841 boost::shared_ptr<AudioRegion> ar;
2845 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2847 } else if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2855 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2856 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2858 update_region_name_map (region);
2862 AudioRegionsAdded (v); /* EMIT SIGNAL */
2868 Session::update_region_name_map (boost::shared_ptr<Region> region)
2870 string::size_type last_period = region->name().find_last_of ('.');
2872 if (last_period != string::npos && last_period < region->name().length() - 1) {
2874 string base = region->name().substr (0, last_period);
2875 string number = region->name().substr (last_period+1);
2876 map<string,uint32_t>::iterator x;
2878 /* note that if there is no number, we get zero from atoi,
2882 region_name_map[base] = atoi (number);
2887 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2889 boost::shared_ptr<Region> region (weak_region.lock ());
2895 if (what_changed & Region::HiddenChanged) {
2896 /* relay hidden changes */
2897 RegionHiddenChange (region);
2900 if (what_changed & NameChanged) {
2901 update_region_name_map (region);
2906 Session::remove_region (boost::weak_ptr<Region> weak_region)
2908 AudioRegionList::iterator i;
2909 boost::shared_ptr<Region> region (weak_region.lock ());
2915 boost::shared_ptr<AudioRegion> ar;
2916 bool removed = false;
2919 Glib::Mutex::Lock lm (region_lock);
2921 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2922 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2923 audio_regions.erase (i);
2929 fatal << _("programming error: ")
2930 << X_("unknown region type passed to Session::remove_region()")
2936 /* mark dirty because something has changed even if we didn't
2937 remove the region from the region list.
2943 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2947 boost::shared_ptr<AudioRegion>
2948 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2950 AudioRegionList::iterator i;
2951 boost::shared_ptr<AudioRegion> region;
2952 Glib::Mutex::Lock lm (region_lock);
2954 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2958 if (region->whole_file()) {
2960 if (child->source_equivalent (region)) {
2966 return boost::shared_ptr<AudioRegion> ();
2970 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2972 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2973 (*i)->get_region_list_equivalent_regions (region, result);
2977 Session::destroy_region (boost::shared_ptr<Region> region)
2979 vector<boost::shared_ptr<Source> > srcs;
2982 boost::shared_ptr<AudioRegion> aregion;
2984 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2988 if (aregion->playlist()) {
2989 aregion->playlist()->destroy_region (region);
2992 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2993 srcs.push_back (aregion->source (n));
2997 region->drop_references ();
2999 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
3001 if (!(*i)->used()) {
3002 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
3005 (afs)->mark_for_remove ();
3008 (*i)->drop_references ();
3010 cerr << "source was not used by any playlist\n";
3018 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
3020 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
3021 destroy_region (*i);
3027 Session::remove_last_capture ()
3029 list<boost::shared_ptr<Region> > r;
3031 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3033 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3034 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
3037 r.insert (r.end(), l.begin(), l.end());
3042 destroy_regions (r);
3044 save_state (_current_snapshot_name);
3050 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3056 /* Source Management */
3059 Session::add_source (boost::shared_ptr<Source> source)
3061 boost::shared_ptr<AudioFileSource> afs;
3063 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3065 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
3066 pair<AudioSourceList::iterator,bool> result;
3068 entry.first = source->id();
3072 Glib::Mutex::Lock lm (audio_source_lock);
3073 result = audio_sources.insert (entry);
3076 if (result.second) {
3077 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3081 if (Config->get_auto_analyse_audio()) {
3082 Analyser::queue_source_for_analysis (source, false);
3088 Session::remove_source (boost::weak_ptr<Source> src)
3090 AudioSourceList::iterator i;
3091 boost::shared_ptr<Source> source = src.lock();
3098 Glib::Mutex::Lock lm (audio_source_lock);
3100 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
3101 audio_sources.erase (i);
3105 if (!_state_of_the_state & InCleanup) {
3107 /* save state so we don't end up with a session file
3108 referring to non-existent sources.
3111 save_state (_current_snapshot_name);
3115 boost::shared_ptr<Source>
3116 Session::source_by_id (const PBD::ID& id)
3118 Glib::Mutex::Lock lm (audio_source_lock);
3119 AudioSourceList::iterator i;
3120 boost::shared_ptr<Source> source;
3122 if ((i = audio_sources.find (id)) != audio_sources.end()) {
3126 /* XXX search MIDI or other searches here */
3132 boost::shared_ptr<Source>
3133 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3135 Glib::Mutex::Lock lm (audio_source_lock);
3137 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3138 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3140 if (afs && afs->path() == path && chn == afs->channel()) {
3145 return boost::shared_ptr<Source>();
3149 Session::peak_path (Glib::ustring base) const
3151 return Glib::build_filename(peak_dir (), base + ".peak");
3155 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
3158 string old_basename = PBD::basename_nosuffix (oldname);
3159 string new_legalized = legalize_for_path (newname);
3161 /* note: we know (or assume) the old path is already valid */
3165 /* destructive file sources have a name of the form:
3167 /path/to/Tnnnn-NAME(%[LR])?.wav
3169 the task here is to replace NAME with the new name.
3172 /* find last slash */
3176 string::size_type slash;
3177 string::size_type dash;
3179 if ((slash = path.find_last_of ('/')) == string::npos) {
3183 dir = path.substr (0, slash+1);
3185 /* '-' is not a legal character for the NAME part of the path */
3187 if ((dash = path.find_last_of ('-')) == string::npos) {
3191 prefix = path.substr (slash+1, dash-(slash+1));
3196 path += new_legalized;
3197 path += ".wav"; /* XXX gag me with a spoon */
3201 /* non-destructive file sources have a name of the form:
3203 /path/to/NAME-nnnnn(%[LR])?.wav
3205 the task here is to replace NAME with the new name.
3210 string::size_type slash;
3211 string::size_type dash;
3212 string::size_type postfix;
3214 /* find last slash */
3216 if ((slash = path.find_last_of ('/')) == string::npos) {
3220 dir = path.substr (0, slash+1);
3222 /* '-' is not a legal character for the NAME part of the path */
3224 if ((dash = path.find_last_of ('-')) == string::npos) {
3228 suffix = path.substr (dash+1);
3230 // Suffix is now everything after the dash. Now we need to eliminate
3231 // the nnnnn part, which is done by either finding a '%' or a '.'
3233 postfix = suffix.find_last_of ("%");
3234 if (postfix == string::npos) {
3235 postfix = suffix.find_last_of ('.');
3238 if (postfix != string::npos) {
3239 suffix = suffix.substr (postfix);
3241 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
3245 const uint32_t limit = 10000;
3246 char buf[PATH_MAX+1];
3248 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3250 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3252 if (access (buf, F_OK) != 0) {
3260 error << "FATAL ERROR! Could not find a " << endl;
3269 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3273 char buf[PATH_MAX+1];
3274 const uint32_t limit = 10000;
3278 legalized = legalize_for_path (name);
3280 /* find a "version" of the file name that doesn't exist in
3281 any of the possible directories.
3284 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3286 vector<space_and_path>::iterator i;
3287 uint32_t existing = 0;
3289 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3293 spath += sound_dir (false);
3297 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3298 } else if (nchan == 2) {
3300 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3302 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3304 } else if (nchan < 26) {
3305 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3307 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3316 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3317 } else if (nchan == 2) {
3319 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3321 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3323 } else if (nchan < 26) {
3324 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3326 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3330 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3336 if (existing == 0) {
3341 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3343 throw failed_constructor();
3347 /* we now have a unique name for the file, but figure out where to
3353 spath = discover_best_sound_dir ();
3356 string::size_type pos = foo.find_last_of ('/');
3358 if (pos == string::npos) {
3361 spath += foo.substr (pos + 1);
3367 boost::shared_ptr<AudioFileSource>
3368 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3370 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3371 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3374 /* Playlist management */
3376 boost::shared_ptr<Playlist>
3377 Session::playlist_by_name (string name)
3379 Glib::Mutex::Lock lm (playlist_lock);
3380 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3381 if ((*i)->name() == name) {
3385 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3386 if ((*i)->name() == name) {
3391 return boost::shared_ptr<Playlist>();
3395 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3397 if (playlist->hidden()) {
3402 Glib::Mutex::Lock lm (playlist_lock);
3403 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3404 playlists.insert (playlists.begin(), playlist);
3405 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3406 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3412 PlaylistAdded (playlist); /* EMIT SIGNAL */
3416 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3419 Glib::Mutex::Lock lm (playlist_lock);
3420 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3423 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3430 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3432 boost::shared_ptr<Playlist> pl(wpl.lock());
3438 PlaylistList::iterator x;
3441 /* its not supposed to be visible */
3446 Glib::Mutex::Lock lm (playlist_lock);
3450 unused_playlists.insert (pl);
3452 if ((x = playlists.find (pl)) != playlists.end()) {
3453 playlists.erase (x);
3459 playlists.insert (pl);
3461 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3462 unused_playlists.erase (x);
3469 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3471 if (_state_of_the_state & Deletion) {
3475 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3482 Glib::Mutex::Lock lm (playlist_lock);
3484 PlaylistList::iterator i;
3486 i = find (playlists.begin(), playlists.end(), playlist);
3487 if (i != playlists.end()) {
3488 playlists.erase (i);
3491 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3492 if (i != unused_playlists.end()) {
3493 unused_playlists.erase (i);
3500 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3504 Session::set_audition (boost::shared_ptr<Region> r)
3506 pending_audition_region = r;
3507 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3508 schedule_butler_transport_work ();
3512 Session::audition_playlist ()
3514 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3515 ev->region.reset ();
3520 Session::non_realtime_set_audition ()
3522 if (!pending_audition_region) {
3523 auditioner->audition_current_playlist ();
3525 auditioner->audition_region (pending_audition_region);
3526 pending_audition_region.reset ();
3528 AuditionActive (true); /* EMIT SIGNAL */
3532 Session::audition_region (boost::shared_ptr<Region> r)
3534 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3540 Session::cancel_audition ()
3542 if (auditioner->active()) {
3543 auditioner->cancel_audition ();
3544 AuditionActive (false); /* EMIT SIGNAL */
3549 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3551 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3555 Session::remove_empty_sounds ()
3557 PathScanner scanner;
3559 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64|L|R)$", false, true);
3561 Glib::Mutex::Lock lm (audio_source_lock);
3563 regex_t compiled_tape_track_pattern;
3566 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3570 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3572 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3576 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3578 /* never remove files that appear to be a tape track */
3580 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3585 if (AudioFileSource::is_empty (*this, **i)) {
3587 unlink ((*i)->c_str());
3589 Glib::ustring peakpath = peak_path (PBD::basename_nosuffix (**i));
3590 unlink (peakpath.c_str());
3596 delete possible_audiofiles;
3600 Session::is_auditioning () const
3602 /* can be called before we have an auditioner object */
3604 return auditioner->active();
3611 Session::set_all_solo (bool yn)
3613 shared_ptr<RouteList> r = routes.reader ();
3615 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3616 if (!(*i)->hidden()) {
3617 (*i)->set_solo (yn, this);
3625 Session::set_all_mute (bool yn)
3627 shared_ptr<RouteList> r = routes.reader ();
3629 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3630 if (!(*i)->hidden()) {
3631 (*i)->set_mute (yn, this);
3639 Session::n_diskstreams () const
3643 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3645 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3646 if (!(*i)->hidden()) {
3654 Session::graph_reordered ()
3656 /* don't do this stuff if we are setting up connections
3657 from a set_state() call or creating new tracks.
3660 if (_state_of_the_state & InitialConnecting) {
3664 /* every track/bus asked for this to be handled but it was deferred because
3665 we were connecting. do it now.
3668 request_input_change_handling ();
3672 /* force all diskstreams to update their capture offset values to
3673 reflect any changes in latencies within the graph.
3676 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3678 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3679 (*i)->set_capture_offset ();
3684 Session::record_disenable_all ()
3686 record_enable_change_all (false);
3690 Session::record_enable_all ()
3692 record_enable_change_all (true);
3696 Session::record_enable_change_all (bool yn)
3698 shared_ptr<RouteList> r = routes.reader ();
3700 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3703 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3704 at->set_record_enable (yn, this);
3708 /* since we don't keep rec-enable state, don't mark session dirty */
3712 Session::add_redirect (Redirect* redirect)
3716 PortInsert* port_insert;
3717 PluginInsert* plugin_insert;
3719 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3720 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3721 _port_inserts.insert (_port_inserts.begin(), port_insert);
3722 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3723 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3725 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3728 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3729 _sends.insert (_sends.begin(), send);
3731 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3735 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3741 Session::remove_redirect (Redirect* redirect)
3745 PortInsert* port_insert;
3746 PluginInsert* plugin_insert;
3748 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3749 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3750 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3751 if (x != _port_inserts.end()) {
3752 insert_bitset[port_insert->bit_slot()] = false;
3753 _port_inserts.erase (x);
3755 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3756 _plugin_inserts.remove (plugin_insert);
3758 fatal << string_compose (_("programming error: %1"),
3759 X_("unknown type of Insert deleted!"))
3763 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3764 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3765 if (x != _sends.end()) {
3766 send_bitset[send->bit_slot()] = false;
3770 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3778 Session::available_capture_duration ()
3780 float sample_bytes_on_disk = 4.0; // keep gcc happy
3782 switch (Config->get_native_file_data_format()) {
3784 sample_bytes_on_disk = 4.0;
3788 sample_bytes_on_disk = 3.0;
3792 sample_bytes_on_disk = 2.0;
3796 /* impossible, but keep some gcc versions happy */
3797 fatal << string_compose (_("programming error: %1"),
3798 X_("illegal native file data format"))
3803 double scale = 4096.0 / sample_bytes_on_disk;
3805 if (_total_free_4k_blocks * scale > (double) max_frames) {
3809 return (nframes_t) floor (_total_free_4k_blocks * scale);
3813 Session::add_connection (ARDOUR::Connection* connection)
3816 Glib::Mutex::Lock guard (connection_lock);
3817 _connections.push_back (connection);
3820 ConnectionAdded (connection); /* EMIT SIGNAL */
3826 Session::remove_connection (ARDOUR::Connection* connection)
3828 bool removed = false;
3831 Glib::Mutex::Lock guard (connection_lock);
3832 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3834 if (i != _connections.end()) {
3835 _connections.erase (i);
3841 ConnectionRemoved (connection); /* EMIT SIGNAL */
3847 ARDOUR::Connection *
3848 Session::connection_by_name (string name) const
3850 Glib::Mutex::Lock lm (connection_lock);
3852 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3853 if ((*i)->name() == name) {
3862 Session::tempo_map_changed (Change ignored)
3866 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3867 (*i)->update_after_tempo_map_change ();
3870 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3871 (*i)->update_after_tempo_map_change ();
3878 Session::ensure_passthru_buffers (uint32_t howmany)
3880 if (current_block_size == 0) {
3884 while (howmany > _passthru_buffers.size()) {
3886 #ifdef NO_POSIX_MEMALIGN
3887 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3889 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3890 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3891 current_block_size, sizeof (Sample), strerror (errno))
3896 _passthru_buffers.push_back (p);
3900 #ifdef NO_POSIX_MEMALIGN
3901 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3903 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
3904 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
3905 current_block_size, sizeof (Sample), strerror (errno))
3910 memset (p, 0, sizeof (Sample) * current_block_size);
3911 _silent_buffers.push_back (p);
3915 #ifdef NO_POSIX_MEMALIGN
3916 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3918 posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample));
3920 memset (p, 0, sizeof (Sample) * current_block_size);
3921 _send_buffers.push_back (p);
3924 allocate_pan_automation_buffers (current_block_size, howmany, false);
3928 Session::next_insert_id ()
3930 /* this doesn't really loop forever. just think about it */
3933 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3934 if (!insert_bitset[n]) {
3935 insert_bitset[n] = true;
3941 /* none available, so resize and try again */
3943 insert_bitset.resize (insert_bitset.size() + 16, false);
3948 Session::next_send_id ()
3950 /* this doesn't really loop forever. just think about it */
3953 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3954 if (!send_bitset[n]) {
3955 send_bitset[n] = true;
3961 /* none available, so resize and try again */
3963 send_bitset.resize (send_bitset.size() + 16, false);
3968 Session::mark_send_id (uint32_t id)
3970 if (id >= send_bitset.size()) {
3971 send_bitset.resize (id+16, false);
3973 if (send_bitset[id]) {
3974 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3976 send_bitset[id] = true;
3980 Session::mark_insert_id (uint32_t id)
3982 if (id >= insert_bitset.size()) {
3983 insert_bitset.resize (id+16, false);
3985 if (insert_bitset[id]) {
3986 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3988 insert_bitset[id] = true;
3991 /* Named Selection management */
3994 Session::named_selection_by_name (string name)
3996 Glib::Mutex::Lock lm (named_selection_lock);
3997 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3998 if ((*i)->name == name) {
4006 Session::add_named_selection (NamedSelection* named_selection)
4009 Glib::Mutex::Lock lm (named_selection_lock);
4010 named_selections.insert (named_selections.begin(), named_selection);
4013 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4019 NamedSelectionAdded (); /* EMIT SIGNAL */
4023 Session::remove_named_selection (NamedSelection* named_selection)
4025 bool removed = false;
4028 Glib::Mutex::Lock lm (named_selection_lock);
4030 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4032 if (i != named_selections.end()) {
4034 named_selections.erase (i);
4041 NamedSelectionRemoved (); /* EMIT SIGNAL */
4046 Session::reset_native_file_format ()
4048 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4050 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4051 (*i)->reset_write_sources (false);
4056 Session::route_name_unique (string n) const
4058 shared_ptr<RouteList> r = routes.reader ();
4060 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4061 if ((*i)->name() == n) {
4070 Session::n_playlists () const
4072 Glib::Mutex::Lock lm (playlist_lock);
4073 return playlists.size();
4077 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4079 if (!force && howmany <= _npan_buffers) {
4083 if (_pan_automation_buffer) {
4085 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4086 delete [] _pan_automation_buffer[i];
4089 delete [] _pan_automation_buffer;
4092 _pan_automation_buffer = new pan_t*[howmany];
4094 for (uint32_t i = 0; i < howmany; ++i) {
4095 _pan_automation_buffer[i] = new pan_t[nframes];
4098 _npan_buffers = howmany;
4102 Session::freeze (InterThreadInfo& itt)
4104 shared_ptr<RouteList> r = routes.reader ();
4106 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4110 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
4111 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4121 boost::shared_ptr<Region>
4122 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t end,
4123 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt, bool enable_processing)
4125 boost::shared_ptr<Region> result;
4126 boost::shared_ptr<Playlist> playlist;
4127 boost::shared_ptr<AudioFileSource> fsource;
4129 char buf[PATH_MAX+1];
4133 nframes_t this_chunk;
4135 nframes_t len = end - start;
4136 vector<Sample*> buffers;
4139 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4140 end, start) << endmsg;
4144 // any bigger than this seems to cause stack overflows in called functions
4145 const nframes_t chunk_size = (128 * 1024)/4;
4147 // block all process callback handling
4149 block_processing ();
4151 /* call tree *MUST* hold route_lock */
4153 if ((playlist = track.diskstream()->playlist()) == 0) {
4157 /* external redirects will be a problem */
4159 if (track.has_external_redirects()) {
4163 nchans = track.audio_diskstream()->n_channels();
4165 dir = discover_best_sound_dir ();
4167 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
4169 for (x = 0; x < 99999; ++x) {
4170 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4171 if (access (buf, F_OK) != 0) {
4177 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4182 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
4185 catch (failed_constructor& err) {
4186 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4190 srcs.push_back (fsource);
4193 /* XXX need to flush all redirects */
4198 /* create a set of reasonably-sized buffers */
4200 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
4202 #ifdef NO_POSIX_MEMALIGN
4203 b = (Sample *) malloc(chunk_size * sizeof(Sample));
4205 posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample));
4207 buffers.push_back (b);
4210 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4211 (*src)->prepare_for_peakfile_writes ();
4214 while (to_do && !itt.cancel) {
4216 this_chunk = min (to_do, chunk_size);
4218 if (track.export_stuff (buffers, nchans, start, this_chunk, enable_processing)) {
4223 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4224 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4227 if (afs->write (buffers[n], this_chunk) != this_chunk) {
4233 start += this_chunk;
4234 to_do -= this_chunk;
4236 itt.progress = (float) (1.0 - ((double) to_do / len));
4245 xnow = localtime (&now);
4247 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4248 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4251 afs->update_header (position, *xnow, now);
4252 afs->flush_header ();
4256 /* construct a region to represent the bounced material */
4258 result = RegionFactory::create (srcs, 0, srcs.front()->length(),
4259 region_name_from_path (srcs.front()->name(), true));
4264 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4265 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4268 afs->mark_for_remove ();
4271 (*src)->drop_references ();
4275 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4276 (*src)->done_with_peakfile_writes ();
4280 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
4284 unblock_processing ();
4292 Session::get_silent_buffers (uint32_t howmany)
4294 if (howmany > _silent_buffers.size()) {
4296 error << string_compose (_("Programming error: get_silent_buffers() called for %1 buffers but only %2 exist"),
4297 howmany, _silent_buffers.size()) << endmsg;
4299 if (howmany > 1000) {
4300 cerr << "ABSURD: more than 1000 silent buffers requested!\n";
4304 while (howmany > _silent_buffers.size()) {
4307 #ifdef NO_POSIX_MEMALIGN
4308 p = (Sample *) malloc(current_block_size * sizeof(Sample));
4310 if (posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)) != 0) {
4311 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
4312 current_block_size, sizeof (Sample), strerror (errno))
4317 _silent_buffers.push_back (p);
4321 for (uint32_t i = 0; i < howmany; ++i) {
4322 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
4325 return _silent_buffers;
4329 Session::ntracks () const
4332 shared_ptr<RouteList> r = routes.reader ();
4334 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4335 if (dynamic_cast<AudioTrack*> ((*i).get())) {
4344 Session::nbusses () const
4347 shared_ptr<RouteList> r = routes.reader ();
4349 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4350 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
4359 Session::add_automation_list(AutomationList *al)
4361 automation_lists[al->id()] = al;
4365 Session::compute_initial_length ()
4367 return _engine.frame_rate() * 60 * 5;
4371 Session::sync_order_keys (const char* base)
4373 if (!Config->get_sync_all_route_ordering()) {
4374 /* leave order keys as they are */
4378 boost::shared_ptr<RouteList> r = routes.reader ();
4380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4381 (*i)->sync_order_keys (base);
4384 Route::SyncOrderKeys (base); // EMIT SIGNAL