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 */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
47 #include "ardour/amp.h"
48 #include "ardour/analyser.h"
49 #include "ardour/audio_buffer.h"
50 #include "ardour/audio_diskstream.h"
51 #include "ardour/audio_port.h"
52 #include "ardour/audio_track.h"
53 #include "ardour/audioengine.h"
54 #include "ardour/audiofilesource.h"
55 #include "ardour/audioplaylist.h"
56 #include "ardour/audioregion.h"
57 #include "ardour/auditioner.h"
58 #include "ardour/buffer_set.h"
59 #include "ardour/bundle.h"
60 #include "ardour/butler.h"
61 #include "ardour/click.h"
62 #include "ardour/configuration.h"
63 #include "ardour/crossfade.h"
64 #include "ardour/cycle_timer.h"
65 #include "ardour/data_type.h"
66 #include "ardour/debug.h"
67 #include "ardour/filename_extensions.h"
68 #include "ardour/internal_send.h"
69 #include "ardour/io_processor.h"
70 #include "ardour/midi_diskstream.h"
71 #include "ardour/midi_playlist.h"
72 #include "ardour/midi_region.h"
73 #include "ardour/midi_track.h"
74 #include "ardour/midi_ui.h"
75 #include "ardour/named_selection.h"
76 #include "ardour/playlist.h"
77 #include "ardour/plugin_insert.h"
78 #include "ardour/port_insert.h"
79 #include "ardour/processor.h"
80 #include "ardour/rc_configuration.h"
81 #include "ardour/recent_sessions.h"
82 #include "ardour/region_factory.h"
83 #include "ardour/return.h"
84 #include "ardour/route_group.h"
85 #include "ardour/send.h"
86 #include "ardour/session.h"
87 #include "ardour/session_directory.h"
88 #include "ardour/session_directory.h"
89 #include "ardour/session_metadata.h"
90 #include "ardour/session_playlists.h"
91 #include "ardour/slave.h"
92 #include "ardour/smf_source.h"
93 #include "ardour/source_factory.h"
94 #include "ardour/tape_file_matcher.h"
95 #include "ardour/tempo.h"
96 #include "ardour/utils.h"
101 using namespace ARDOUR;
103 using boost::shared_ptr;
104 using boost::weak_ptr;
106 bool Session::_disable_all_loaded_plugins = false;
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::TimecodeOffsetChanged;
114 sigc::signal<void> Session::StartTimeChanged;
115 sigc::signal<void> Session::EndTimeChanged;
116 sigc::signal<void> Session::AutoBindingOn;
117 sigc::signal<void> Session::AutoBindingOff;
118 sigc::signal<void, std::string, std::string> Session::Exported;
120 Session::Session (AudioEngine &eng,
121 const string& fullpath,
122 const string& snapshot_name,
126 _target_transport_speed (0.0),
127 _requested_return_frame (-1),
128 _scratch_buffers(new BufferSet()),
129 _silent_buffers(new BufferSet()),
130 _mix_buffers(new BufferSet()),
132 _mmc_port (default_mmc_port),
133 _mtc_port (default_mtc_port),
134 _midi_port (default_midi_port),
135 _midi_clock_port (default_midi_clock_port),
136 _session_dir (new SessionDirectory(fullpath)),
138 _butler (new Butler (this)),
139 _post_transport_work (0),
140 _send_timecode_update (false),
141 diskstreams (new DiskstreamList),
142 routes (new RouteList),
143 _total_free_4k_blocks (0),
144 _bundles (new BundleList),
145 _bundle_xml_node (0),
148 click_emphasis_data (0),
150 _metadata (new SessionMetadata()),
151 _have_rec_enabled_diskstream (false)
154 playlists.reset (new SessionPlaylists);
158 interpolation.add_channel_to (0, 0);
160 if (!eng.connected()) {
161 throw failed_constructor();
164 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
166 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
167 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
169 first_stage_init (fullpath, snapshot_name);
171 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
174 if (create (new_session, mix_template, compute_initial_length())) {
176 throw failed_constructor ();
180 if (second_stage_init (new_session)) {
182 throw failed_constructor ();
185 store_recent_sessions(_name, _path);
187 bool was_dirty = dirty();
189 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
191 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
192 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
195 DirtyChanged (); /* EMIT SIGNAL */
199 Session::Session (AudioEngine &eng,
201 string snapshot_name,
202 AutoConnectOption input_ac,
203 AutoConnectOption output_ac,
204 uint32_t control_out_channels,
205 uint32_t master_out_channels,
206 uint32_t requested_physical_in,
207 uint32_t requested_physical_out,
208 nframes_t initial_length)
211 _target_transport_speed (0.0),
212 _requested_return_frame (-1),
213 _scratch_buffers(new BufferSet()),
214 _silent_buffers(new BufferSet()),
215 _mix_buffers(new BufferSet()),
217 _mmc_port (default_mmc_port),
218 _mtc_port (default_mtc_port),
219 _midi_port (default_midi_port),
220 _midi_clock_port (default_midi_clock_port),
221 _session_dir ( new SessionDirectory(fullpath)),
223 _butler (new Butler (this)),
224 _post_transport_work (0),
225 _send_timecode_update (false),
226 diskstreams (new DiskstreamList),
227 routes (new RouteList),
228 _total_free_4k_blocks (0),
229 _bundles (new BundleList),
230 _bundle_xml_node (0),
231 _click_io ((IO *) 0),
233 click_emphasis_data (0),
235 _metadata (new SessionMetadata()),
236 _have_rec_enabled_diskstream (false)
238 playlists.reset (new SessionPlaylists);
242 interpolation.add_channel_to (0, 0);
244 if (!eng.connected()) {
245 throw failed_constructor();
248 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
250 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
251 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
253 if (n_physical_inputs) {
254 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
257 if (n_physical_outputs) {
258 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
261 first_stage_init (fullpath, snapshot_name);
263 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
266 if (create (new_session, string(), initial_length)) {
268 throw failed_constructor ();
273 /* set up Master Out and Control Out if necessary */
278 if (master_out_channels) {
279 ChanCount count(DataType::AUDIO, master_out_channels);
280 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
281 r->input()->ensure_io (count, false, this);
282 r->output()->ensure_io (count, false, this);
283 r->set_remote_control_id (control_id);
287 /* prohibit auto-connect to master, because there isn't one */
288 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
291 if (control_out_channels) {
292 ChanCount count(DataType::AUDIO, control_out_channels);
293 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
294 r->input()->ensure_io (count, false, this);
295 r->output()->ensure_io (count, false, this);
296 r->set_remote_control_id (control_id++);
302 add_routes (rl, false);
307 if (no_auto_connect()) {
308 input_ac = AutoConnectOption (0);
309 output_ac = AutoConnectOption (0);
312 Config->set_input_auto_connect (input_ac);
313 Config->set_output_auto_connect (output_ac);
315 if (second_stage_init (new_session)) {
317 throw failed_constructor ();
320 store_recent_sessions (_name, _path);
322 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
324 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
335 vector<void*> debug_pointers;
337 /* if we got to here, leaving pending capture state around
341 remove_pending_capture_state ();
343 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
345 _engine.remove_session ();
347 GoingAway (); /* EMIT SIGNAL */
353 /* clear history so that no references to objects are held any more */
357 /* clear state tree so that no references to objects are held any more */
361 /* reset dynamic state version back to default */
363 Stateful::loading_state_version = 0;
365 _butler->terminate_thread ();
367 delete midi_control_ui;
369 if (click_data != default_click) {
370 delete [] click_data;
373 if (click_emphasis_data != default_click_emphasis) {
374 delete [] click_emphasis_data;
379 delete _scratch_buffers;
380 delete _silent_buffers;
383 /* clear out any pending dead wood from RCU managed objects */
386 diskstreams.flush ();
389 AudioDiskstream::free_working_buffers();
391 Route::SyncOrderKeys.clear();
393 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
394 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
395 NamedSelectionList::iterator tmp;
404 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
405 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
406 RegionList::iterator tmp;
411 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 (%2); pre-ref = %2\n", i->second->name(), i->second.get(), i->second.use_count()));
412 i->second->drop_references ();
413 DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count()));
419 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
421 /* reset these three references to special routes before we do the usual route delete thing */
424 _master_out.reset ();
425 _control_out.reset ();
428 RCUWriter<RouteList> writer (routes);
429 boost::shared_ptr<RouteList> r = writer.get_copy ();
430 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
431 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
432 (*i)->drop_references ();
435 /* writer goes out of scope and updates master */
439 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
441 RCUWriter<DiskstreamList> dwriter (diskstreams);
442 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
443 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
444 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
445 (*i)->drop_references ();
449 diskstreams.flush ();
451 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
452 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
453 SourceMap::iterator tmp;
458 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
459 i->second->drop_references ();
467 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
468 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
472 Crossfade::set_buffer_size (0);
476 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
479 boost_debug_list_ptrs ();
481 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
485 Session::set_worst_io_latencies ()
487 _worst_output_latency = 0;
488 _worst_input_latency = 0;
490 if (!_engine.connected()) {
494 boost::shared_ptr<RouteList> r = routes.reader ();
496 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
497 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
498 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
503 Session::when_engine_running ()
505 string first_physical_output;
507 BootMessage (_("Set block size and sample rate"));
509 set_block_size (_engine.frames_per_cycle());
510 set_frame_rate (_engine.frame_rate());
512 BootMessage (_("Using configuration"));
514 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
515 config.map_parameters (bind (mem_fun (*this, &Session::config_changed), true));
517 /* every time we reconnect, recompute worst case output latencies */
519 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
521 if (synced_to_jack()) {
522 _engine.transport_stop ();
525 if (config.get_jack_time_master()) {
526 _engine.transport_locate (_transport_frame);
534 _click_io.reset (new ClickIO (*this, "click"));
536 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
538 /* existing state for Click */
541 if (Stateful::loading_state_version < 3000) {
542 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
544 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
549 _clicking = Config->get_clicking ();
553 error << _("could not setup Click I/O") << endmsg;
560 /* default state for Click: dual-mono to first 2 physical outputs */
562 for (int physport = 0; physport < 2; ++physport) {
563 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
565 if (physical_output.length()) {
566 if (_click_io->add_port (physical_output, this)) {
567 // relax, even though its an error
572 if (_click_io->n_ports () > ChanCount::ZERO) {
573 _clicking = Config->get_clicking ();
578 catch (failed_constructor& err) {
579 error << _("cannot setup Click I/O") << endmsg;
582 BootMessage (_("Compute I/O Latencies"));
584 set_worst_io_latencies ();
587 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
590 BootMessage (_("Set up standard connections"));
592 /* Create a set of Bundle objects that map
593 to the physical I/O currently available. We create both
594 mono and stereo bundles, so that the common cases of mono
595 and stereo tracks get bundles to put in their mixer strip
596 in / out menus. There may be a nicer way of achieving that;
597 it doesn't really scale that well to higher channel counts
600 /* mono output bundles */
602 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
604 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
606 shared_ptr<Bundle> c (new Bundle (buf, true));
607 c->add_channel (_("mono"));
608 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
613 /* stereo output bundles */
615 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
616 if (np + 1 < n_physical_outputs) {
618 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
619 shared_ptr<Bundle> c (new Bundle (buf, true));
620 c->add_channel (_("L"));
621 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
622 c->add_channel (_("R"));
623 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
629 /* mono input bundles */
631 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
633 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
635 shared_ptr<Bundle> c (new Bundle (buf, false));
636 c->add_channel (_("mono"));
637 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
642 /* stereo input bundles */
644 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
645 if (np + 1 < n_physical_inputs) {
647 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
649 shared_ptr<Bundle> c (new Bundle (buf, false));
650 c->add_channel (_("L"));
651 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
652 c->add_channel (_("R"));
653 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
659 BootMessage (_("Setup signal flow and plugins"));
663 if (!no_auto_connect()) {
665 if (_master_out && Config->get_auto_connect_standard_busses()) {
667 /* if requested auto-connect the outputs to the first N physical ports.
670 uint32_t limit = _master_out->n_outputs().n_total();
672 for (uint32_t n = 0; n < limit; ++n) {
673 Port* p = _master_out->output()->nth (n);
674 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
676 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
677 if (_master_out->output()->connect (p, connect_to, this)) {
678 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
688 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
689 are undefined, at best.
692 /* control out listens to master bus (but ignores it
693 under some conditions)
696 uint32_t limit = _control_out->n_inputs().n_audio();
699 for (uint32_t n = 0; n < limit; ++n) {
700 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
701 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
704 string connect_to = o->name();
705 if (_control_out->input()->connect (p, connect_to, this)) {
706 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
714 /* if control out is not connected,
715 connect control out to physical outs, but use ones after the master if possible
718 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
720 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
722 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
725 _control_out->output()->connect_ports_to_bundle (b, this);
727 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
728 Config->get_monitor_bus_preferred_bundle())
734 /* XXX this logic is wrong for mixed port types */
736 uint32_t shift = _master_out->n_outputs().n_audio();
737 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
738 limit = _control_out->n_outputs().n_audio();
740 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
742 for (uint32_t n = 0; n < limit; ++n) {
744 Port* p = _control_out->output()->nth (n);
745 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
747 if (!connect_to.empty()) {
748 if (_control_out->output()->connect (p, connect_to, this)) {
749 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
760 /* catch up on send+insert cnts */
762 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
764 /* hook us up to the engine */
766 BootMessage (_("Connect to engine"));
768 _engine.set_session (this);
772 Session::hookup_io ()
774 /* stop graph reordering notifications from
775 causing resorts, etc.
778 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
783 /* we delay creating the auditioner till now because
784 it makes its own connections to ports.
785 the engine has to be running for this to work.
789 auditioner.reset (new Auditioner (*this));
792 catch (failed_constructor& err) {
793 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
797 /* load bundles, which we may have postponed earlier on */
798 if (_bundle_xml_node) {
799 load_bundles (*_bundle_xml_node);
800 delete _bundle_xml_node;
803 /* Tell all IO objects to connect themselves together */
805 IO::enable_connecting ();
807 /* Now reset all panners */
809 Delivery::reset_panners ();
811 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
815 boost::shared_ptr<RouteList> r = routes.reader ();
817 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
819 if ((*x)->is_control() || (*x)->is_master()) {
823 (*x)->listen_via (_control_out,
824 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
829 /* Anyone who cares about input state, wake up and do something */
831 IOConnectionsComplete (); /* EMIT SIGNAL */
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
835 /* now handle the whole enchilada as if it was one
841 /* update the full solo state, which can't be
842 correctly determined on a per-route basis, but
843 needs the global overview that only the session
847 update_route_solo_state ();
851 Session::playlist_length_changed ()
853 /* we can't just increase end_location->end() if pl->get_maximum_extent()
854 if larger. if the playlist used to be the longest playlist,
855 and its now shorter, we have to decrease end_location->end(). hence,
856 we have to iterate over all diskstreams and check the
857 playlists currently in use.
863 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
865 boost::shared_ptr<Diskstream> dstream = wp.lock ();
870 boost::shared_ptr<Playlist> playlist;
872 if ((playlist = dstream->playlist()) != 0) {
873 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
876 /* see comment in playlist_length_changed () */
881 Session::record_enabling_legal () const
883 /* this used to be in here, but survey says.... we don't need to restrict it */
884 // if (record_status() == Recording) {
888 if (Config->get_all_safe()) {
895 Session::reset_input_monitor_state ()
897 if (transport_rolling()) {
899 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
901 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
902 if ((*i)->record_enabled ()) {
903 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
904 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
908 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
910 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
911 if ((*i)->record_enabled ()) {
912 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
913 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
920 Session::auto_punch_start_changed (Location* location)
922 replace_event (SessionEvent::PunchIn, location->start());
924 if (get_record_enabled() && config.get_punch_in()) {
925 /* capture start has been changed, so save new pending state */
926 save_state ("", true);
931 Session::auto_punch_end_changed (Location* location)
933 nframes_t when_to_stop = location->end();
934 // when_to_stop += _worst_output_latency + _worst_input_latency;
935 replace_event (SessionEvent::PunchOut, when_to_stop);
939 Session::auto_punch_changed (Location* location)
941 nframes_t when_to_stop = location->end();
943 replace_event (SessionEvent::PunchIn, location->start());
944 //when_to_stop += _worst_output_latency + _worst_input_latency;
945 replace_event (SessionEvent::PunchOut, when_to_stop);
949 Session::auto_loop_changed (Location* location)
951 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
953 if (transport_rolling() && play_loop) {
956 // if (_transport_frame > location->end()) {
958 if (_transport_frame < location->start() || _transport_frame > location->end()) {
959 // relocate to beginning of loop
960 clear_events (SessionEvent::LocateRoll);
962 request_locate (location->start(), true);
965 else if (Config->get_seamless_loop() && !loop_changing) {
967 // schedule a locate-roll to refill the diskstreams at the
969 loop_changing = true;
971 if (location->end() > last_loopend) {
972 clear_events (SessionEvent::LocateRoll);
973 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
980 last_loopend = location->end();
984 Session::set_auto_punch_location (Location* location)
988 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
989 auto_punch_start_changed_connection.disconnect();
990 auto_punch_end_changed_connection.disconnect();
991 auto_punch_changed_connection.disconnect();
992 existing->set_auto_punch (false, this);
993 remove_event (existing->start(), SessionEvent::PunchIn);
994 clear_events (SessionEvent::PunchOut);
995 auto_punch_location_changed (0);
1000 if (location == 0) {
1004 if (location->end() <= location->start()) {
1005 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1009 auto_punch_start_changed_connection.disconnect();
1010 auto_punch_end_changed_connection.disconnect();
1011 auto_punch_changed_connection.disconnect();
1013 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1014 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1015 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1017 location->set_auto_punch (true, this);
1020 auto_punch_changed (location);
1022 auto_punch_location_changed (location);
1026 Session::set_auto_loop_location (Location* location)
1030 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1031 auto_loop_start_changed_connection.disconnect();
1032 auto_loop_end_changed_connection.disconnect();
1033 auto_loop_changed_connection.disconnect();
1034 existing->set_auto_loop (false, this);
1035 remove_event (existing->end(), SessionEvent::AutoLoop);
1036 auto_loop_location_changed (0);
1041 if (location == 0) {
1045 if (location->end() <= location->start()) {
1046 error << _("Session: you can't use a mark for auto loop") << endmsg;
1050 last_loopend = location->end();
1052 auto_loop_start_changed_connection.disconnect();
1053 auto_loop_end_changed_connection.disconnect();
1054 auto_loop_changed_connection.disconnect();
1056 auto_loop_start_changed_connection = location->start_changed.connect (
1057 mem_fun (this, &Session::auto_loop_changed));
1058 auto_loop_end_changed_connection = location->end_changed.connect (
1059 mem_fun (this, &Session::auto_loop_changed));
1060 auto_loop_changed_connection = location->changed.connect (
1061 mem_fun (this, &Session::auto_loop_changed));
1063 location->set_auto_loop (true, this);
1065 /* take care of our stuff first */
1067 auto_loop_changed (location);
1069 /* now tell everyone else */
1071 auto_loop_location_changed (location);
1075 Session::locations_added (Location *)
1081 Session::locations_changed ()
1083 _locations.apply (*this, &Session::handle_locations_changed);
1087 Session::handle_locations_changed (Locations::LocationList& locations)
1089 Locations::LocationList::iterator i;
1091 bool set_loop = false;
1092 bool set_punch = false;
1094 for (i = locations.begin(); i != locations.end(); ++i) {
1098 if (location->is_auto_punch()) {
1099 set_auto_punch_location (location);
1102 if (location->is_auto_loop()) {
1103 set_auto_loop_location (location);
1107 if (location->is_start()) {
1108 start_location = location;
1110 if (location->is_end()) {
1111 end_location = location;
1116 set_auto_loop_location (0);
1119 set_auto_punch_location (0);
1126 Session::enable_record ()
1128 /* XXX really atomic compare+swap here */
1129 if (g_atomic_int_get (&_record_status) != Recording) {
1130 g_atomic_int_set (&_record_status, Recording);
1131 _last_record_location = _transport_frame;
1132 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1134 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1135 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1136 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1137 if ((*i)->record_enabled ()) {
1138 (*i)->monitor_input (true);
1143 RecordStateChanged ();
1148 Session::disable_record (bool rt_context, bool force)
1152 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1154 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1155 g_atomic_int_set (&_record_status, Disabled);
1157 if (rs == Recording) {
1158 g_atomic_int_set (&_record_status, Enabled);
1162 // FIXME: timestamp correct? [DR]
1163 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1164 // does this /need/ to be sent in all cases?
1166 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1169 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1170 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1172 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1173 if ((*i)->record_enabled ()) {
1174 (*i)->monitor_input (false);
1179 RecordStateChanged (); /* emit signal */
1182 remove_pending_capture_state ();
1188 Session::step_back_from_record ()
1190 /* XXX really atomic compare+swap here */
1191 if (g_atomic_int_get (&_record_status) == Recording) {
1192 g_atomic_int_set (&_record_status, Enabled);
1194 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1195 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1197 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1198 if ((*i)->record_enabled ()) {
1199 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1200 (*i)->monitor_input (false);
1208 Session::maybe_enable_record ()
1210 g_atomic_int_set (&_record_status, Enabled);
1212 /* this function is currently called from somewhere other than an RT thread.
1213 this save_state() call therefore doesn't impact anything.
1216 save_state ("", true);
1218 if (_transport_speed) {
1219 if (!config.get_punch_in()) {
1223 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1224 RecordStateChanged (); /* EMIT SIGNAL */
1231 Session::audible_frame () const
1237 /* the first of these two possible settings for "offset"
1238 mean that the audible frame is stationary until
1239 audio emerges from the latency compensation
1242 the second means that the audible frame is stationary
1243 until audio would emerge from a physical port
1244 in the absence of any plugin latency compensation
1247 offset = _worst_output_latency;
1249 if (offset > current_block_size) {
1250 offset -= current_block_size;
1252 /* XXX is this correct? if we have no external
1253 physical connections and everything is internal
1254 then surely this is zero? still, how
1255 likely is that anyway?
1257 offset = current_block_size;
1260 if (synced_to_jack()) {
1261 tf = _engine.transport_frame();
1263 tf = _transport_frame;
1268 if (!non_realtime_work_pending()) {
1272 /* check to see if we have passed the first guaranteed
1273 audible frame past our last start position. if not,
1274 return that last start point because in terms
1275 of audible frames, we have not moved yet.
1278 if (_transport_speed > 0.0f) {
1280 if (!play_loop || !have_looped) {
1281 if (tf < _last_roll_location + offset) {
1282 return _last_roll_location;
1290 } else if (_transport_speed < 0.0f) {
1292 /* XXX wot? no backward looping? */
1294 if (tf > _last_roll_location - offset) {
1295 return _last_roll_location;
1307 Session::set_frame_rate (nframes_t frames_per_second)
1309 /** \fn void Session::set_frame_size(nframes_t)
1310 the AudioEngine object that calls this guarantees
1311 that it will not be called while we are also in
1312 ::process(). Its fine to do things that block
1316 _base_frame_rate = frames_per_second;
1320 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1324 // XXX we need some equivalent to this, somehow
1325 // SndFileSource::setup_standard_crossfades (frames_per_second);
1329 /* XXX need to reset/reinstantiate all LADSPA plugins */
1333 Session::set_block_size (nframes_t nframes)
1335 /* the AudioEngine guarantees
1336 that it will not be called while we are also in
1337 ::process(). It is therefore fine to do things that block
1342 current_block_size = nframes;
1344 ensure_buffers(_scratch_buffers->available());
1346 delete [] _gain_automation_buffer;
1347 _gain_automation_buffer = new gain_t[nframes];
1349 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1351 boost::shared_ptr<RouteList> r = routes.reader ();
1353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1354 (*i)->set_block_size (nframes);
1357 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1358 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1359 (*i)->set_block_size (nframes);
1362 set_worst_io_latencies ();
1367 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1370 nframes_t fade_frames;
1372 /* Don't allow fade of less 1 frame */
1374 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1381 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1385 default_fade_msecs = fade_msecs;
1386 default_fade_steepness = steepness;
1389 // jlc, WTF is this!
1390 Glib::RWLock::ReaderLock lm (route_lock);
1391 AudioRegion::set_default_fade (steepness, fade_frames);
1396 /* XXX have to do this at some point */
1397 /* foreach region using default fade, reset, then
1398 refill_all_diskstream_buffers ();
1403 struct RouteSorter {
1404 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1405 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1407 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1410 if (r1->fed_by.empty()) {
1411 if (r2->fed_by.empty()) {
1412 /* no ardour-based connections inbound to either route. just use signal order */
1413 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1415 /* r2 has connections, r1 does not; run r1 early */
1419 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1426 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1428 shared_ptr<Route> r2;
1430 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1431 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1435 /* make a copy of the existing list of routes that feed r1 */
1437 set<weak_ptr<Route> > existing = r1->fed_by;
1439 /* for each route that feeds r1, recurse, marking it as feeding
1443 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1444 if (!(r2 = (*i).lock ())) {
1445 /* (*i) went away, ignore it */
1449 /* r2 is a route that feeds r1 which somehow feeds base. mark
1450 base as being fed by r2
1453 rbase->fed_by.insert (r2);
1457 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1461 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1465 /* now recurse, so that we can mark base as being fed by
1466 all routes that feed r2
1469 trace_terminal (r2, rbase);
1476 Session::resort_routes ()
1478 /* don't do anything here with signals emitted
1479 by Routes while we are being destroyed.
1482 if (_state_of_the_state & Deletion) {
1489 RCUWriter<RouteList> writer (routes);
1490 shared_ptr<RouteList> r = writer.get_copy ();
1491 resort_routes_using (r);
1492 /* writer goes out of scope and forces update */
1497 Session::resort_routes_using (shared_ptr<RouteList> r)
1499 RouteList::iterator i, j;
1501 for (i = r->begin(); i != r->end(); ++i) {
1503 (*i)->fed_by.clear ();
1505 for (j = r->begin(); j != r->end(); ++j) {
1507 /* although routes can feed themselves, it will
1508 cause an endless recursive descent if we
1509 detect it. so don't bother checking for
1517 if ((*j)->feeds (*i)) {
1518 (*i)->fed_by.insert (*j);
1523 for (i = r->begin(); i != r->end(); ++i) {
1524 trace_terminal (*i, *i);
1531 cerr << "finished route resort\n";
1533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1534 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1541 list<boost::shared_ptr<MidiTrack> >
1542 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1544 char track_name[32];
1545 uint32_t track_id = 0;
1548 RouteList new_routes;
1549 list<boost::shared_ptr<MidiTrack> > ret;
1550 //uint32_t control_id;
1552 // FIXME: need physical I/O and autoconnect stuff for MIDI
1554 /* count existing midi tracks */
1557 shared_ptr<RouteList> r = routes.reader ();
1559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1560 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1561 if (!(*i)->is_hidden()) {
1563 //channels_used += (*i)->n_inputs().n_midi();
1569 vector<string> physinputs;
1570 vector<string> physoutputs;
1572 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1573 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1575 // control_id = ntracks() + nbusses();
1579 /* check for duplicate route names, since we might have pre-existing
1580 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1581 save, close,restart,add new route - first named route is now
1589 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1591 if (route_by_name (track_name) == 0) {
1595 } while (track_id < (UINT_MAX-1));
1597 shared_ptr<MidiTrack> track;
1600 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1602 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1603 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1608 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1609 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1615 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1619 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1620 port = physinputs[(channels_used+x)%nphysical_in];
1623 if (port.length() && track->connect_input (track->input (x), port, this)) {
1629 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1633 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1634 port = physoutputs[(channels_used+x)%nphysical_out];
1635 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1637 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1641 if (port.length() && track->connect_output (track->output (x), port, this)) {
1646 channels_used += track->n_inputs ().n_midi();
1650 track->midi_diskstream()->non_realtime_input_change();
1651 track->set_route_group (route_group, 0);
1653 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1654 //track->set_remote_control_id (control_id);
1656 new_routes.push_back (track);
1657 ret.push_back (track);
1660 catch (failed_constructor &err) {
1661 error << _("Session: could not create new midi track.") << endmsg;
1664 /* we need to get rid of this, since the track failed to be created */
1665 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1668 RCUWriter<DiskstreamList> writer (diskstreams);
1669 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1670 ds->remove (track->midi_diskstream());
1677 catch (AudioEngine::PortRegistrationFailure& pfe) {
1679 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1682 /* we need to get rid of this, since the track failed to be created */
1683 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1686 RCUWriter<DiskstreamList> writer (diskstreams);
1687 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1688 ds->remove (track->midi_diskstream());
1699 if (!new_routes.empty()) {
1700 add_routes (new_routes, false);
1701 save_state (_current_snapshot_name);
1707 list<boost::shared_ptr<AudioTrack> >
1708 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1710 char track_name[32];
1711 uint32_t track_id = 0;
1713 uint32_t channels_used = 0;
1715 RouteList new_routes;
1716 list<boost::shared_ptr<AudioTrack> > ret;
1717 uint32_t control_id;
1719 /* count existing audio tracks */
1722 shared_ptr<RouteList> r = routes.reader ();
1724 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1725 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1726 if (!(*i)->is_hidden()) {
1728 channels_used += (*i)->n_inputs().n_audio();
1734 vector<string> physinputs;
1735 vector<string> physoutputs;
1737 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1738 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1740 control_id = ntracks() + nbusses() + 1;
1744 /* check for duplicate route names, since we might have pre-existing
1745 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1746 save, close,restart,add new route - first named route is now
1754 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1756 if (route_by_name (track_name) == 0) {
1760 } while (track_id < (UINT_MAX-1));
1762 shared_ptr<AudioTrack> track;
1765 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1766 // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1767 track = boost::shared_ptr<AudioTrack>(at);
1769 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1770 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1771 input_channels, output_channels)
1776 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1777 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1778 input_channels, output_channels)
1783 if (!physinputs.empty()) {
1784 uint32_t nphysical_in = physinputs.size();
1786 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1790 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1791 port = physinputs[(channels_used+x)%nphysical_in];
1794 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1800 if (!physoutputs.empty()) {
1801 uint32_t nphysical_out = physoutputs.size();
1803 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1806 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1807 port = physoutputs[(channels_used+x)%nphysical_out];
1808 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1809 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1810 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1814 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1820 channels_used += track->n_inputs ().n_audio();
1822 track->set_route_group (route_group, 0);
1824 track->audio_diskstream()->non_realtime_input_change();
1826 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1827 track->set_remote_control_id (control_id);
1830 new_routes.push_back (track);
1831 ret.push_back (track);
1834 catch (failed_constructor &err) {
1835 error << _("Session: could not create new audio track.") << endmsg;
1838 /* we need to get rid of this, since the track failed to be created */
1839 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1842 RCUWriter<DiskstreamList> writer (diskstreams);
1843 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1844 ds->remove (track->audio_diskstream());
1851 catch (AudioEngine::PortRegistrationFailure& pfe) {
1853 error << pfe.what() << 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());
1873 if (!new_routes.empty()) {
1874 add_routes (new_routes, true);
1881 Session::set_remote_control_ids ()
1883 RemoteModel m = Config->get_remote_model();
1885 shared_ptr<RouteList> r = routes.reader ();
1887 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1888 if ( MixerOrdered == m) {
1889 long order = (*i)->order_key(N_("signal"));
1890 (*i)->set_remote_control_id( order+1 );
1891 } else if ( EditorOrdered == m) {
1892 long order = (*i)->order_key(N_("editor"));
1893 (*i)->set_remote_control_id( order+1 );
1894 } else if ( UserOrdered == m) {
1895 //do nothing ... only changes to remote id's are initiated by user
1902 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1905 uint32_t bus_id = 1;
1907 uint32_t channels_used = 0;
1910 uint32_t control_id;
1912 /* count existing audio busses */
1915 shared_ptr<RouteList> r = routes.reader ();
1917 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1918 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1920 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1923 channels_used += (*i)->n_inputs().n_audio();
1929 vector<string> physinputs;
1930 vector<string> physoutputs;
1932 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1933 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1935 n_physical_audio_outputs = physoutputs.size();
1936 n_physical_audio_inputs = physinputs.size();
1938 control_id = ntracks() + nbusses() + 1;
1943 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1947 if (route_by_name (bus_name) == 0) {
1951 } while (bus_id < (UINT_MAX-1));
1954 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1956 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1957 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1958 input_channels, output_channels)
1964 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1965 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1966 input_channels, output_channels)
1971 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1974 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1975 port = physinputs[((n+x)%n_physical_audio_inputs)];
1978 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1983 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1986 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1987 port = physoutputs[((n+x)%n_physical_outputs)];
1988 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1990 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1994 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1999 channels_used += bus->n_inputs ().n_audio();
2001 bus->set_route_group (route_group, 0);
2002 bus->set_remote_control_id (control_id);
2006 bus->add_internal_return ();
2009 ret.push_back (bus);
2013 catch (failed_constructor &err) {
2014 error << _("Session: could not create new audio route.") << endmsg;
2018 catch (AudioEngine::PortRegistrationFailure& pfe) {
2019 error << pfe.what() << endmsg;
2029 add_routes (ret, true);
2037 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2041 uint32_t control_id;
2043 uint32_t number = 1;
2045 if (!tree.read (template_path.c_str())) {
2049 XMLNode* node = tree.root();
2051 control_id = ntracks() + nbusses() + 1;
2055 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2057 std::string node_name = IO::name_from_state (*node_copy.children().front());
2059 /* generate a new name by adding a number to the end of the template name */
2062 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2066 if (route_by_name (name) == 0) {
2070 } while (number < UINT_MAX);
2072 if (number == UINT_MAX) {
2073 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2077 IO::set_name_in_state (*node_copy.children().front(), name);
2079 Track::zero_diskstream_id_in_xml (node_copy);
2082 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2085 error << _("Session: cannot create track/bus from template description") << endmsg;
2089 if (boost::dynamic_pointer_cast<Track>(route)) {
2090 /* force input/output change signals so that the new diskstream
2091 picks up the configuration of the route. During session
2092 loading this normally happens in a different way.
2094 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2095 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2098 route->set_remote_control_id (control_id);
2101 ret.push_back (route);
2104 catch (failed_constructor &err) {
2105 error << _("Session: could not create new route from template") << endmsg;
2109 catch (AudioEngine::PortRegistrationFailure& pfe) {
2110 error << pfe.what() << endmsg;
2119 add_routes (ret, true);
2126 Session::add_routes (RouteList& new_routes, bool save)
2129 RCUWriter<RouteList> writer (routes);
2130 shared_ptr<RouteList> r = writer.get_copy ();
2131 r->insert (r->end(), new_routes.begin(), new_routes.end());
2134 /* if there is no control out and we're not in the middle of loading,
2135 resort the graph here. if there is a control out, we will resort
2136 toward the end of this method. if we are in the middle of loading,
2137 we will resort when done.
2140 if (!_control_out && IO::connecting_legal) {
2141 resort_routes_using (r);
2145 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2147 boost::weak_ptr<Route> wpr (*x);
2149 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2150 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2151 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2152 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2153 (*x)->processors_changed.connect (mem_fun (*this, &Session::route_processors_changed));
2154 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2156 if ((*x)->is_master()) {
2160 if ((*x)->is_control()) {
2161 _control_out = (*x);
2165 if (_control_out && IO::connecting_legal) {
2167 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2168 if ((*x)->is_control() || (*x)->is_master()) {
2171 (*x)->listen_via (_control_out,
2172 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2182 save_state (_current_snapshot_name);
2185 RouteAdded (new_routes); /* EMIT SIGNAL */
2189 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2191 boost::shared_ptr<RouteList> r = routes.reader ();
2192 boost::shared_ptr<Send> s;
2196 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2197 if (boost::dynamic_pointer_cast<Track>(*i)) {
2198 if ((s = (*i)->internal_send_for (dest)) != 0) {
2199 s->amp()->gain_control()->set_value (0.0);
2206 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2208 boost::shared_ptr<RouteList> r = routes.reader ();
2209 boost::shared_ptr<Send> s;
2213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2214 if (boost::dynamic_pointer_cast<Track>(*i)) {
2215 if ((s = (*i)->internal_send_for (dest)) != 0) {
2216 s->amp()->gain_control()->set_value (1.0);
2223 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2225 boost::shared_ptr<RouteList> r = routes.reader ();
2226 boost::shared_ptr<Send> s;
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if (boost::dynamic_pointer_cast<Track>(*i)) {
2232 if ((s = (*i)->internal_send_for (dest)) != 0) {
2233 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2240 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2242 boost::shared_ptr<RouteList> r = routes.reader ();
2243 boost::shared_ptr<RouteList> t (new RouteList);
2245 /* only send tracks */
2247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 if (boost::dynamic_pointer_cast<Track>(*i)) {
2253 add_internal_sends (dest, p, t);
2257 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2259 if (dest->is_control() || dest->is_master()) {
2263 if (!dest->internal_return()) {
2264 dest->add_internal_return();
2267 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2269 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2273 (*i)->listen_via (dest, p, true, true);
2280 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2282 /* need to do this in case we're rolling at the time, to prevent false underruns */
2283 dstream->do_refill_with_alloc ();
2285 dstream->set_block_size (current_block_size);
2288 RCUWriter<DiskstreamList> writer (diskstreams);
2289 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2290 ds->push_back (dstream);
2291 /* writer goes out of scope, copies ds back to main */
2294 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2295 /* this will connect to future changes, and check the current length */
2296 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2298 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2300 dstream->prepare ();
2305 Session::remove_route (shared_ptr<Route> route)
2308 RCUWriter<RouteList> writer (routes);
2309 shared_ptr<RouteList> rs = writer.get_copy ();
2313 /* deleting the master out seems like a dumb
2314 idea, but its more of a UI policy issue
2318 if (route == _master_out) {
2319 _master_out = shared_ptr<Route> ();
2322 if (route == _control_out) {
2324 /* cancel control outs for all routes */
2326 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2327 (*r)->drop_listen (_control_out);
2330 _control_out.reset ();
2333 update_route_solo_state ();
2335 /* writer goes out of scope, forces route list update */
2338 boost::shared_ptr<Track> t;
2339 boost::shared_ptr<Diskstream> ds;
2341 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2342 ds = t->diskstream();
2348 RCUWriter<DiskstreamList> dsl (diskstreams);
2349 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2354 find_current_end ();
2356 // We need to disconnect the routes inputs and outputs
2358 route->input()->disconnect (0);
2359 route->output()->disconnect (0);
2361 /* if the route had internal sends sending to it, remove them */
2362 if (route->internal_return()) {
2364 boost::shared_ptr<RouteList> r = routes.reader ();
2365 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2366 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2368 (*i)->remove_processor (s);
2373 update_latency_compensation (false, false);
2376 /* get rid of it from the dead wood collection in the route list manager */
2378 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2382 /* try to cause everyone to drop their references */
2384 route->drop_references ();
2386 sync_order_keys (N_("session"));
2388 /* save the new state of the world */
2390 if (save_state (_current_snapshot_name)) {
2391 save_history (_current_snapshot_name);
2396 Session::route_mute_changed (void* /*src*/)
2402 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2404 boost::shared_ptr<Route> route = wpr.lock();
2406 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2410 if (route->listening()) {
2412 } else if (_listen_cnt > 0) {
2418 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2420 if (solo_update_disabled) {
2425 boost::shared_ptr<Route> route = wpr.lock ();
2428 /* should not happen */
2429 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2433 shared_ptr<RouteList> r = routes.reader ();
2436 if (route->self_soloed()) {
2442 /* now mod the solo level of all other routes except master & control outs
2443 so that they will be silent if appropriate.
2446 solo_update_disabled = true;
2448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2449 bool via_sends_only;
2452 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2454 } else if ((*i)->feeds (route, &via_sends_only)) {
2455 if (!via_sends_only) {
2456 (*i)->mod_solo_by_others (delta);
2461 /* make sure master is never muted by solo */
2463 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2464 _master_out->mod_solo_by_others (1);
2467 /* ditto for control outs make sure master is never muted by solo */
2469 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2470 _control_out->mod_solo_by_others (1);
2473 solo_update_disabled = false;
2474 update_route_solo_state (r);
2475 SoloChanged (); /* EMIT SIGNAL */
2480 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2482 /* now figure out if anything that matters is soloed */
2484 bool something_soloed = false;
2487 r = routes.reader();
2490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2491 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2492 something_soloed = true;
2497 if (something_soloed != _non_soloed_outs_muted) {
2498 _non_soloed_outs_muted = something_soloed;
2499 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2503 boost::shared_ptr<RouteList>
2504 Session::get_routes_with_internal_returns() const
2506 shared_ptr<RouteList> r = routes.reader ();
2507 boost::shared_ptr<RouteList> rl (new RouteList);
2509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2510 if ((*i)->internal_return ()) {
2518 Session::route_by_name (string name)
2520 shared_ptr<RouteList> r = routes.reader ();
2522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2523 if ((*i)->name() == name) {
2528 return shared_ptr<Route> ((Route*) 0);
2532 Session::route_by_id (PBD::ID id)
2534 shared_ptr<RouteList> r = routes.reader ();
2536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2537 if ((*i)->id() == id) {
2542 return shared_ptr<Route> ((Route*) 0);
2546 Session::route_by_remote_id (uint32_t id)
2548 shared_ptr<RouteList> r = routes.reader ();
2550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2551 if ((*i)->remote_control_id() == id) {
2556 return shared_ptr<Route> ((Route*) 0);
2560 Session::find_current_end ()
2562 if (_state_of_the_state & Loading) {
2566 nframes_t max = get_maximum_extent ();
2568 if (max > end_location->end()) {
2569 end_location->set_end (max);
2571 DurationChanged(); /* EMIT SIGNAL */
2576 Session::get_maximum_extent () const
2581 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2583 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2584 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2586 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2587 if ((me = pl->get_maximum_extent()) > max) {
2595 boost::shared_ptr<Diskstream>
2596 Session::diskstream_by_name (string name)
2598 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2600 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2601 if ((*i)->name() == name) {
2606 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2609 boost::shared_ptr<Diskstream>
2610 Session::diskstream_by_id (const PBD::ID& id)
2612 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2614 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2615 if ((*i)->id() == id) {
2620 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2623 /* Region management */
2626 Session::new_region_name (string old)
2628 string::size_type last_period;
2630 string::size_type len = old.length() + 64;
2633 if ((last_period = old.find_last_of ('.')) == string::npos) {
2635 /* no period present - add one explicitly */
2638 last_period = old.length() - 1;
2643 number = atoi (old.substr (last_period+1).c_str());
2647 while (number < (UINT_MAX-1)) {
2649 RegionList::const_iterator i;
2654 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2657 for (i = regions.begin(); i != regions.end(); ++i) {
2658 if (i->second->name() == sbuf) {
2663 if (i == regions.end()) {
2668 if (number != (UINT_MAX-1)) {
2672 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2677 Session::region_name (string& result, string base, bool newlevel)
2682 if (base.find("/") != string::npos) {
2683 base = base.substr(base.find_last_of("/") + 1);
2688 Glib::Mutex::Lock lm (region_lock);
2690 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2699 string::size_type pos;
2701 pos = base.find_last_of ('.');
2703 /* pos may be npos, but then we just use entire base */
2705 subbase = base.substr (0, pos);
2710 Glib::Mutex::Lock lm (region_lock);
2712 map<string,uint32_t>::iterator x;
2716 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2718 region_name_map[subbase] = 1;
2721 snprintf (buf, sizeof (buf), ".%d", x->second);
2732 Session::add_region (boost::shared_ptr<Region> region)
2734 vector<boost::shared_ptr<Region> > v;
2735 v.push_back (region);
2740 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2745 Glib::Mutex::Lock lm (region_lock);
2747 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2749 boost::shared_ptr<Region> region = *ii;
2753 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2757 RegionList::iterator x;
2759 for (x = regions.begin(); x != regions.end(); ++x) {
2761 if (region->region_list_equivalent (x->second)) {
2766 if (x == regions.end()) {
2768 pair<RegionList::key_type,RegionList::mapped_type> entry;
2770 entry.first = region->id();
2771 entry.second = region;
2773 pair<RegionList::iterator,bool> x = regions.insert (entry);
2785 /* mark dirty because something has changed even if we didn't
2786 add the region to the region list.
2793 vector<boost::weak_ptr<Region> > v;
2794 boost::shared_ptr<Region> first_r;
2796 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2798 boost::shared_ptr<Region> region = *ii;
2802 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2805 v.push_back (region);
2812 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2813 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2815 update_region_name_map (region);
2819 RegionsAdded (v); /* EMIT SIGNAL */
2825 Session::update_region_name_map (boost::shared_ptr<Region> region)
2827 string::size_type last_period = region->name().find_last_of ('.');
2829 if (last_period != string::npos && last_period < region->name().length() - 1) {
2831 string base = region->name().substr (0, last_period);
2832 string number = region->name().substr (last_period+1);
2833 map<string,uint32_t>::iterator x;
2835 /* note that if there is no number, we get zero from atoi,
2839 region_name_map[base] = atoi (number);
2844 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2846 boost::shared_ptr<Region> region (weak_region.lock ());
2852 if (what_changed & Region::HiddenChanged) {
2853 /* relay hidden changes */
2854 RegionHiddenChange (region);
2857 if (what_changed & NameChanged) {
2858 update_region_name_map (region);
2863 Session::remove_region (boost::weak_ptr<Region> weak_region)
2865 RegionList::iterator i;
2866 boost::shared_ptr<Region> region (weak_region.lock ());
2872 bool removed = false;
2875 Glib::Mutex::Lock lm (region_lock);
2877 if ((i = regions.find (region->id())) != regions.end()) {
2883 /* mark dirty because something has changed even if we didn't
2884 remove the region from the region list.
2890 RegionRemoved(region); /* EMIT SIGNAL */
2894 boost::shared_ptr<Region>
2895 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2897 RegionList::iterator i;
2898 boost::shared_ptr<Region> region;
2900 Glib::Mutex::Lock lm (region_lock);
2902 for (i = regions.begin(); i != regions.end(); ++i) {
2906 if (region->whole_file()) {
2908 if (child->source_equivalent (region)) {
2914 return boost::shared_ptr<Region> ();
2918 Session::destroy_region (boost::shared_ptr<Region> region)
2920 vector<boost::shared_ptr<Source> > srcs;
2923 if (region->playlist()) {
2924 region->playlist()->destroy_region (region);
2927 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2928 srcs.push_back (region->source (n));
2932 region->drop_references ();
2934 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2936 (*i)->mark_for_remove ();
2937 (*i)->drop_references ();
2939 cerr << "source was not used by any playlist\n";
2946 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2948 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2949 destroy_region (*i);
2955 Session::remove_last_capture ()
2957 list<boost::shared_ptr<Region> > r;
2959 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2961 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2962 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2965 r.insert (r.end(), l.begin(), l.end());
2970 destroy_regions (r);
2972 save_state (_current_snapshot_name);
2978 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2984 /* Source Management */
2987 Session::add_source (boost::shared_ptr<Source> source)
2989 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2990 pair<SourceMap::iterator,bool> result;
2992 entry.first = source->id();
2993 entry.second = source;
2996 Glib::Mutex::Lock lm (source_lock);
2997 result = sources.insert (entry);
3000 if (result.second) {
3001 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3005 boost::shared_ptr<AudioFileSource> afs;
3007 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3008 if (Config->get_auto_analyse_audio()) {
3009 Analyser::queue_source_for_analysis (source, false);
3015 Session::remove_source (boost::weak_ptr<Source> src)
3017 SourceMap::iterator i;
3018 boost::shared_ptr<Source> source = src.lock();
3025 Glib::Mutex::Lock lm (source_lock);
3027 if ((i = sources.find (source->id())) != sources.end()) {
3032 if (!_state_of_the_state & InCleanup) {
3034 /* save state so we don't end up with a session file
3035 referring to non-existent sources.
3038 save_state (_current_snapshot_name);
3042 boost::shared_ptr<Source>
3043 Session::source_by_id (const PBD::ID& id)
3045 Glib::Mutex::Lock lm (source_lock);
3046 SourceMap::iterator i;
3047 boost::shared_ptr<Source> source;
3049 if ((i = sources.find (id)) != sources.end()) {
3056 boost::shared_ptr<Source>
3057 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3059 Glib::Mutex::Lock lm (source_lock);
3061 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3062 cerr << "comparing " << path << " with " << i->second->name() << endl;
3063 boost::shared_ptr<AudioFileSource> afs
3064 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3066 if (afs && afs->path() == path && chn == afs->channel()) {
3070 return boost::shared_ptr<Source>();
3075 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3078 string old_basename = PBD::basename_nosuffix (oldname);
3079 string new_legalized = legalize_for_path (newname);
3081 /* note: we know (or assume) the old path is already valid */
3085 /* destructive file sources have a name of the form:
3087 /path/to/Tnnnn-NAME(%[LR])?.wav
3089 the task here is to replace NAME with the new name.
3092 /* find last slash */
3096 string::size_type slash;
3097 string::size_type dash;
3099 if ((slash = path.find_last_of ('/')) == string::npos) {
3103 dir = path.substr (0, slash+1);
3105 /* '-' is not a legal character for the NAME part of the path */
3107 if ((dash = path.find_last_of ('-')) == string::npos) {
3111 prefix = path.substr (slash+1, dash-(slash+1));
3116 path += new_legalized;
3117 path += ".wav"; /* XXX gag me with a spoon */
3121 /* non-destructive file sources have a name of the form:
3123 /path/to/NAME-nnnnn(%[LR])?.ext
3125 the task here is to replace NAME with the new name.
3130 string::size_type slash;
3131 string::size_type dash;
3132 string::size_type postfix;
3134 /* find last slash */
3136 if ((slash = path.find_last_of ('/')) == string::npos) {
3140 dir = path.substr (0, slash+1);
3142 /* '-' is not a legal character for the NAME part of the path */
3144 if ((dash = path.find_last_of ('-')) == string::npos) {
3148 suffix = path.substr (dash+1);
3150 // Suffix is now everything after the dash. Now we need to eliminate
3151 // the nnnnn part, which is done by either finding a '%' or a '.'
3153 postfix = suffix.find_last_of ("%");
3154 if (postfix == string::npos) {
3155 postfix = suffix.find_last_of ('.');
3158 if (postfix != string::npos) {
3159 suffix = suffix.substr (postfix);
3161 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3165 const uint32_t limit = 10000;
3166 char buf[PATH_MAX+1];
3168 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3170 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3172 if (access (buf, F_OK) != 0) {
3180 error << "FATAL ERROR! Could not find a " << endl;
3188 /** Return the full path (in some session directory) for a new within-session source.
3189 * \a name must be a session-unique name that does not contain slashes
3190 * (e.g. as returned by new_*_source_name)
3193 Session::new_source_path_from_name (DataType type, const string& name)
3195 assert(name.find("/") == string::npos);
3197 SessionDirectory sdir(get_best_session_directory_for_new_source());
3200 if (type == DataType::AUDIO) {
3201 p = sdir.sound_path();
3202 } else if (type == DataType::MIDI) {
3203 p = sdir.midi_path();
3205 error << "Unknown source type, unable to create file path" << endmsg;
3210 return p.to_string();
3214 Session::peak_path (Glib::ustring base) const
3216 sys::path peakfile_path(_session_dir->peak_path());
3217 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3218 return peakfile_path.to_string();
3221 /** Return a unique name based on \a base for a new internal audio source */
3223 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3227 char buf[PATH_MAX+1];
3228 const uint32_t limit = 10000;
3232 legalized = legalize_for_path (base);
3234 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3235 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3237 vector<space_and_path>::iterator i;
3238 uint32_t existing = 0;
3240 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3242 SessionDirectory sdir((*i).path);
3244 spath = sdir.sound_path().to_string();
3249 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3250 spath.c_str(), cnt, legalized.c_str());
3251 } else if (nchan == 2) {
3253 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3254 spath.c_str(), cnt, legalized.c_str());
3256 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3257 spath.c_str(), cnt, legalized.c_str());
3259 } else if (nchan < 26) {
3260 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3261 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3263 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3264 spath.c_str(), cnt, legalized.c_str());
3273 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3274 } else if (nchan == 2) {
3276 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3278 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3280 } else if (nchan < 26) {
3281 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3283 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3287 if (sys::exists(buf)) {
3293 if (existing == 0) {
3298 error << string_compose(
3299 _("There are already %1 recordings for %2, which I consider too many."),
3300 limit, base) << endmsg;
3302 throw failed_constructor();
3306 return Glib::path_get_basename(buf);
3309 /** Create a new within-session audio source */
3310 boost::shared_ptr<AudioFileSource>
3311 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3313 const size_t n_chans = ds.n_channels().n_audio();
3314 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3315 const string path = new_source_path_from_name(DataType::AUDIO, name);
3317 return boost::dynamic_pointer_cast<AudioFileSource> (
3318 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3321 /** Return a unique name based on \a base for a new internal MIDI source */
3323 Session::new_midi_source_name (const string& base)
3326 char buf[PATH_MAX+1];
3327 const uint32_t limit = 10000;
3331 legalized = legalize_for_path (base);
3333 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3334 for (cnt = 1; cnt <= limit; ++cnt) {
3336 vector<space_and_path>::iterator i;
3337 uint32_t existing = 0;
3339 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3341 SessionDirectory sdir((*i).path);
3343 sys::path p = sdir.midi_path();
3346 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3348 if (sys::exists (buf)) {
3353 if (existing == 0) {
3358 error << string_compose(
3359 _("There are already %1 recordings for %2, which I consider too many."),
3360 limit, base) << endmsg;
3362 throw failed_constructor();
3366 return Glib::path_get_basename(buf);
3370 /** Create a new within-session MIDI source */
3371 boost::shared_ptr<MidiSource>
3372 Session::create_midi_source_for_session (MidiDiskstream& ds)
3374 const string name = new_midi_source_name (ds.name());
3375 const string path = new_source_path_from_name (DataType::MIDI, name);
3377 return boost::dynamic_pointer_cast<SMFSource> (
3378 SourceFactory::createWritable (
3379 DataType::MIDI, *this, path, false, frame_rate()));
3384 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3386 if (playlist->hidden()) {
3390 bool existing = playlists->add (playlist);
3392 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3396 playlist->release();
3403 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3405 if (_state_of_the_state & Deletion) {
3409 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3415 playlists->remove (playlist);
3421 Session::set_audition (boost::shared_ptr<Region> r)
3423 pending_audition_region = r;
3424 add_post_transport_work (PostTransportAudition);
3425 _butler->schedule_transport_work ();
3429 Session::audition_playlist ()
3431 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3432 ev->region.reset ();
3437 Session::non_realtime_set_audition ()
3439 if (!pending_audition_region) {
3440 auditioner->audition_current_playlist ();
3442 auditioner->audition_region (pending_audition_region);
3443 pending_audition_region.reset ();
3445 AuditionActive (true); /* EMIT SIGNAL */
3449 Session::audition_region (boost::shared_ptr<Region> r)
3451 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3457 Session::cancel_audition ()
3459 if (auditioner->active()) {
3460 auditioner->cancel_audition ();
3461 AuditionActive (false); /* EMIT SIGNAL */
3466 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3468 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3472 Session::remove_empty_sounds ()
3474 vector<string> audio_filenames;
3476 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3478 Glib::Mutex::Lock lm (source_lock);
3480 TapeFileMatcher tape_file_matcher;
3482 remove_if (audio_filenames.begin(), audio_filenames.end(),
3483 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3485 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3487 sys::path audio_file_path (_session_dir->sound_path());
3489 audio_file_path /= *i;
3491 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3495 sys::remove (audio_file_path);
3496 const string peakfile = peak_path (audio_file_path.to_string());
3497 sys::remove (peakfile);
3499 catch (const sys::filesystem_error& err)
3501 error << err.what() << endmsg;
3508 Session::is_auditioning () const
3510 /* can be called before we have an auditioner object */
3512 return auditioner->active();
3519 Session::set_solo (boost::shared_ptr<RouteList> r, bool yn)
3521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3522 if (!(*i)->is_hidden()) {
3523 (*i)->set_solo (yn, this);
3531 Session::set_listen (boost::shared_ptr<RouteList> r, bool yn)
3533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3534 if (!(*i)->is_hidden()) {
3535 (*i)->set_listen (yn, this);
3543 Session::set_mute (boost::shared_ptr<RouteList> r, bool yn)
3545 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3546 if (!(*i)->is_hidden()) {
3547 (*i)->set_mute (yn, this);
3555 Session::n_diskstreams () const
3559 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3561 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3562 if (!(*i)->hidden()) {
3570 Session::graph_reordered ()
3572 /* don't do this stuff if we are setting up connections
3573 from a set_state() call or creating new tracks. Ditto for deletion.
3576 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3580 /* every track/bus asked for this to be handled but it was deferred because
3581 we were connecting. do it now.
3584 request_input_change_handling ();
3588 /* force all diskstreams to update their capture offset values to
3589 reflect any changes in latencies within the graph.
3592 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3594 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3595 (*i)->set_capture_offset ();
3600 Session::set_record_enable (boost::shared_ptr<RouteList> rl, bool yn)
3606 for (RouteList::iterator i = rl->begin(); i != rl->end(); ) {
3607 boost::shared_ptr<Track> t;
3609 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3610 t->set_record_enable (yn, this);
3611 if (t->meter_point() == MeterCustom) {
3612 /* don't change metering for this track */
3626 Session::add_processor (Processor* processor)
3628 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3633 Session::remove_processor (Processor* processor)
3637 PortInsert* port_insert;
3639 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3640 insert_bitset[port_insert->bit_slot()] = false;
3641 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3642 send_bitset[send->bit_slot()] = false;
3643 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3644 return_bitset[retrn->bit_slot()] = false;
3651 Session::available_capture_duration ()
3653 float sample_bytes_on_disk = 4.0; // keep gcc happy
3655 switch (config.get_native_file_data_format()) {
3657 sample_bytes_on_disk = 4.0;
3661 sample_bytes_on_disk = 3.0;
3665 sample_bytes_on_disk = 2.0;
3669 /* impossible, but keep some gcc versions happy */
3670 fatal << string_compose (_("programming error: %1"),
3671 X_("illegal native file data format"))
3676 double scale = 4096.0 / sample_bytes_on_disk;
3678 if (_total_free_4k_blocks * scale > (double) max_frames) {
3682 return (nframes_t) floor (_total_free_4k_blocks * scale);
3686 Session::add_bundle (shared_ptr<Bundle> bundle)
3689 RCUWriter<BundleList> writer (_bundles);
3690 boost::shared_ptr<BundleList> b = writer.get_copy ();
3691 b->push_back (bundle);
3694 BundleAdded (bundle); /* EMIT SIGNAL */
3700 Session::remove_bundle (shared_ptr<Bundle> bundle)
3702 bool removed = false;
3705 RCUWriter<BundleList> writer (_bundles);
3706 boost::shared_ptr<BundleList> b = writer.get_copy ();
3707 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3709 if (i != b->end()) {
3716 BundleRemoved (bundle); /* EMIT SIGNAL */
3723 Session::bundle_by_name (string name) const
3725 boost::shared_ptr<BundleList> b = _bundles.reader ();
3727 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3728 if ((*i)->name() == name) {
3733 return boost::shared_ptr<Bundle> ();
3737 Session::tempo_map_changed (Change)
3741 playlists->update_after_tempo_map_change ();
3746 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3747 * the given count with the current block size.
3750 Session::ensure_buffers (ChanCount howmany)
3752 if (current_block_size == 0) {
3753 return; // too early? (is this ok?)
3756 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3757 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3758 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3759 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3760 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3763 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3767 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3769 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3770 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3775 Session::next_insert_id ()
3777 /* this doesn't really loop forever. just think about it */
3780 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3781 if (!insert_bitset[n]) {
3782 insert_bitset[n] = true;
3788 /* none available, so resize and try again */
3790 insert_bitset.resize (insert_bitset.size() + 16, false);
3795 Session::next_send_id ()
3797 /* this doesn't really loop forever. just think about it */
3800 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3801 if (!send_bitset[n]) {
3802 send_bitset[n] = true;
3808 /* none available, so resize and try again */
3810 send_bitset.resize (send_bitset.size() + 16, false);
3815 Session::next_return_id ()
3817 /* this doesn't really loop forever. just think about it */
3820 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3821 if (!return_bitset[n]) {
3822 return_bitset[n] = true;
3828 /* none available, so resize and try again */
3830 return_bitset.resize (return_bitset.size() + 16, false);
3835 Session::mark_send_id (uint32_t id)
3837 if (id >= send_bitset.size()) {
3838 send_bitset.resize (id+16, false);
3840 if (send_bitset[id]) {
3841 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3843 send_bitset[id] = true;
3847 Session::mark_return_id (uint32_t id)
3849 if (id >= return_bitset.size()) {
3850 return_bitset.resize (id+16, false);
3852 if (return_bitset[id]) {
3853 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3855 return_bitset[id] = true;
3859 Session::mark_insert_id (uint32_t id)
3861 if (id >= insert_bitset.size()) {
3862 insert_bitset.resize (id+16, false);
3864 if (insert_bitset[id]) {
3865 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3867 insert_bitset[id] = true;
3870 /* Named Selection management */
3873 Session::named_selection_by_name (string name)
3875 Glib::Mutex::Lock lm (named_selection_lock);
3876 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3877 if ((*i)->name == name) {
3885 Session::add_named_selection (NamedSelection* named_selection)
3888 Glib::Mutex::Lock lm (named_selection_lock);
3889 named_selections.insert (named_selections.begin(), named_selection);
3892 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3898 NamedSelectionAdded (); /* EMIT SIGNAL */
3902 Session::remove_named_selection (NamedSelection* named_selection)
3904 bool removed = false;
3907 Glib::Mutex::Lock lm (named_selection_lock);
3909 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3911 if (i != named_selections.end()) {
3913 named_selections.erase (i);
3920 NamedSelectionRemoved (); /* EMIT SIGNAL */
3925 Session::reset_native_file_format ()
3927 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3929 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3930 (*i)->reset_write_sources (false);
3935 Session::route_name_unique (string n) const
3937 shared_ptr<RouteList> r = routes.reader ();
3939 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3940 if ((*i)->name() == n) {
3949 Session::route_name_internal (string n) const
3951 if (auditioner && auditioner->name() == n) {
3955 if (_click_io && _click_io->name() == n) {
3963 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3965 if (!force && howmany <= _npan_buffers) {
3969 if (_pan_automation_buffer) {
3971 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3972 delete [] _pan_automation_buffer[i];
3975 delete [] _pan_automation_buffer;
3978 _pan_automation_buffer = new pan_t*[howmany];
3980 for (uint32_t i = 0; i < howmany; ++i) {
3981 _pan_automation_buffer[i] = new pan_t[nframes];
3984 _npan_buffers = howmany;
3988 Session::freeze (InterThreadInfo& itt)
3990 shared_ptr<RouteList> r = routes.reader ();
3992 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3994 boost::shared_ptr<Track> t;
3996 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3997 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4007 boost::shared_ptr<Region>
4008 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4009 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4010 InterThreadInfo& itt, bool enable_processing)
4012 boost::shared_ptr<Region> result;
4013 boost::shared_ptr<Playlist> playlist;
4014 boost::shared_ptr<AudioFileSource> fsource;
4016 char buf[PATH_MAX+1];
4017 ChanCount nchans(track.audio_diskstream()->n_channels());
4019 nframes_t this_chunk;
4022 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4023 const string sound_dir = sdir.sound_path().to_string();
4024 nframes_t len = end - start;
4027 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4028 end, start) << endmsg;
4032 const nframes_t chunk_size = (256 * 1024)/4;
4034 // block all process callback handling
4036 block_processing ();
4038 /* call tree *MUST* hold route_lock */
4040 if ((playlist = track.diskstream()->playlist()) == 0) {
4044 /* external redirects will be a problem */
4046 if (track.has_external_redirects()) {
4050 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4052 for (x = 0; x < 99999; ++x) {
4053 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4054 if (access (buf, F_OK) != 0) {
4060 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4065 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4066 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4069 catch (failed_constructor& err) {
4070 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4074 srcs.push_back (fsource);
4077 /* XXX need to flush all redirects */
4082 /* create a set of reasonably-sized buffers */
4083 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4084 buffers.set_count(nchans);
4086 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4087 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4089 afs->prepare_for_peakfile_writes ();
4092 while (to_do && !itt.cancel) {
4094 this_chunk = min (to_do, chunk_size);
4096 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4101 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4102 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4105 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4111 start += this_chunk;
4112 to_do -= this_chunk;
4114 itt.progress = (float) (1.0 - ((double) to_do / len));
4123 xnow = localtime (&now);
4125 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4126 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4129 afs->update_header (position, *xnow, now);
4130 afs->flush_header ();
4134 /* construct a region to represent the bounced material */
4136 result = RegionFactory::create (srcs, 0,
4137 srcs.front()->length(srcs.front()->timeline_position()),
4138 region_name_from_path (srcs.front()->name(), true));
4143 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4144 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4147 afs->mark_for_remove ();
4150 (*src)->drop_references ();
4154 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4155 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4158 afs->done_with_peakfile_writes ();
4162 unblock_processing ();
4168 Session::get_silent_buffers (ChanCount count)
4170 assert(_silent_buffers->available() >= count);
4171 _silent_buffers->set_count(count);
4173 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4174 for (size_t i= 0; i < count.get(*t); ++i) {
4175 _silent_buffers->get(*t, i).clear();
4179 return *_silent_buffers;
4183 Session::get_scratch_buffers (ChanCount count)
4185 if (count != ChanCount::ZERO) {
4186 assert(_scratch_buffers->available() >= count);
4187 _scratch_buffers->set_count(count);
4189 _scratch_buffers->set_count (_scratch_buffers->available());
4192 return *_scratch_buffers;
4196 Session::get_mix_buffers (ChanCount count)
4198 assert(_mix_buffers->available() >= count);
4199 _mix_buffers->set_count(count);
4200 return *_mix_buffers;
4204 Session::ntracks () const
4207 shared_ptr<RouteList> r = routes.reader ();
4209 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4210 if (boost::dynamic_pointer_cast<Track> (*i)) {
4219 Session::nbusses () const
4222 shared_ptr<RouteList> r = routes.reader ();
4224 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4225 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4234 Session::add_automation_list(AutomationList *al)
4236 automation_lists[al->id()] = al;
4240 Session::compute_initial_length ()
4242 return _engine.frame_rate() * 60 * 5;
4246 Session::sync_order_keys (std::string const & base)
4248 if (!Config->get_sync_all_route_ordering()) {
4249 /* leave order keys as they are */
4253 boost::shared_ptr<RouteList> r = routes.reader ();
4255 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4256 (*i)->sync_order_keys (base);
4259 Route::SyncOrderKeys (base); // EMIT SIGNAL
4263 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4265 Session::have_rec_enabled_diskstream () const
4267 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4270 /** Update the state of our rec-enabled diskstreams flag */
4272 Session::update_have_rec_enabled_diskstream ()
4274 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4275 DiskstreamList::iterator i = dsl->begin ();
4276 while (i != dsl->end () && (*i)->record_enabled () == false) {
4280 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4282 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4284 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4285 RecordStateChanged (); /* EMIT SIGNAL */
4290 Session::listen_position_changed ()
4294 switch (Config->get_listen_position()) {
4295 case AfterFaderListen:
4299 case PreFaderListen:
4304 boost::shared_ptr<RouteList> r = routes.reader ();
4306 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4307 (*i)->put_control_outs_at (p);
4312 Session::solo_control_mode_changed ()
4314 /* cancel all solo or all listen when solo control mode changes */
4316 if (Config->get_solo_control_is_listen_control()) {
4317 set_solo (routes.reader(), false);
4319 set_listen (routes.reader(), false);
4324 Session::route_group_changed ()
4326 RouteGroupChanged (); /* EMIT SIGNAL */
4330 Session::get_available_sync_options () const
4332 vector<SyncSource> ret;
4334 ret.push_back (JACK);
4337 ret.push_back (MTC);
4340 if (midi_clock_port()) {
4341 ret.push_back (MIDIClock);
4347 boost::shared_ptr<RouteList>
4348 Session::get_routes_with_regions_at (nframes64_t const p) const
4350 shared_ptr<RouteList> r = routes.reader ();
4351 shared_ptr<RouteList> rl (new RouteList);
4353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4354 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4359 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4364 boost::shared_ptr<Playlist> pl = ds->playlist ();
4369 if (pl->has_region_at (p)) {