2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <glibmm/thread.h>
33 #include <glibmm/miscutils.h>
34 #include <glibmm/fileutils.h>
35 #include <glibmm/thread.h>
37 #include "pbd/error.h"
38 #include "pbd/boost_debug.h"
39 #include "pbd/pathscanner.h"
40 #include "pbd/stl_delete.h"
41 #include "pbd/basename.h"
42 #include "pbd/stacktrace.h"
43 #include "pbd/file_utils.h"
44 #include "pbd/convert.h"
46 #include "ardour/amp.h"
47 #include "ardour/analyser.h"
48 #include "ardour/audio_buffer.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_track.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/audiofilesource.h"
54 #include "ardour/audioplaylist.h"
55 #include "ardour/audioregion.h"
56 #include "ardour/auditioner.h"
57 #include "ardour/buffer_set.h"
58 #include "ardour/bundle.h"
59 #include "ardour/butler.h"
60 #include "ardour/click.h"
61 #include "ardour/configuration.h"
62 #include "ardour/crossfade.h"
63 #include "ardour/cycle_timer.h"
64 #include "ardour/data_type.h"
65 #include "ardour/debug.h"
66 #include "ardour/filename_extensions.h"
67 #include "ardour/internal_send.h"
68 #include "ardour/io_processor.h"
69 #include "ardour/midi_diskstream.h"
70 #include "ardour/midi_playlist.h"
71 #include "ardour/midi_region.h"
72 #include "ardour/midi_track.h"
73 #include "ardour/midi_ui.h"
74 #include "ardour/named_selection.h"
75 #include "ardour/playlist.h"
76 #include "ardour/plugin_insert.h"
77 #include "ardour/port_insert.h"
78 #include "ardour/processor.h"
79 #include "ardour/rc_configuration.h"
80 #include "ardour/recent_sessions.h"
81 #include "ardour/region_factory.h"
82 #include "ardour/return.h"
83 #include "ardour/route_group.h"
84 #include "ardour/send.h"
85 #include "ardour/session.h"
86 #include "ardour/session_directory.h"
87 #include "ardour/session_directory.h"
88 #include "ardour/session_metadata.h"
89 #include "ardour/session_playlists.h"
90 #include "ardour/slave.h"
91 #include "ardour/smf_source.h"
92 #include "ardour/source_factory.h"
93 #include "ardour/tape_file_matcher.h"
94 #include "ardour/tempo.h"
95 #include "ardour/utils.h"
97 #include "midi++/jack.h"
102 using namespace ARDOUR;
104 using boost::shared_ptr;
105 using boost::weak_ptr;
107 bool Session::_disable_all_loaded_plugins = false;
109 PBD::Signal1<void,std::string> Session::Dialog;
110 PBD::Signal0<int> Session::AskAboutPendingState;
111 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
112 PBD::Signal0<void> Session::SendFeedback;
114 PBD::Signal0<void> Session::TimecodeOffsetChanged;
115 PBD::Signal0<void> Session::StartTimeChanged;
116 PBD::Signal0<void> Session::EndTimeChanged;
117 PBD::Signal0<void> Session::AutoBindingOn;
118 PBD::Signal0<void> Session::AutoBindingOff;
119 PBD::Signal2<void,std::string, std::string> Session::Exported;
120 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
122 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
123 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
125 Session::Session (AudioEngine &eng,
126 const string& fullpath,
127 const string& snapshot_name,
131 _target_transport_speed (0.0),
132 _requested_return_frame (-1),
133 _scratch_buffers(new BufferSet()),
134 _silent_buffers(new BufferSet()),
135 _mix_buffers(new BufferSet()),
137 _mmc_port (default_mmc_port),
138 _mtc_port (default_mtc_port),
139 _midi_port (default_midi_port),
140 _midi_clock_port (default_midi_clock_port),
141 _session_dir (new SessionDirectory(fullpath)),
143 _butler (new Butler (*this)),
144 _post_transport_work (0),
145 _send_timecode_update (false),
146 diskstreams (new DiskstreamList),
147 routes (new RouteList),
148 _total_free_4k_blocks (0),
149 _bundles (new BundleList),
150 _bundle_xml_node (0),
153 click_emphasis_data (0),
155 _metadata (new SessionMetadata()),
156 _have_rec_enabled_diskstream (false)
159 playlists.reset (new SessionPlaylists);
163 interpolation.add_channel_to (0, 0);
165 if (!eng.connected()) {
166 throw failed_constructor();
169 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
171 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
172 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
174 first_stage_init (fullpath, snapshot_name);
176 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
179 if (create (new_session, mix_template, compute_initial_length())) {
181 throw failed_constructor ();
185 if (second_stage_init (new_session)) {
187 throw failed_constructor ();
190 store_recent_sessions(_name, _path);
192 bool was_dirty = dirty();
194 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
196 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
197 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
200 DirtyChanged (); /* EMIT SIGNAL */
204 Session::Session (AudioEngine &eng,
206 string snapshot_name,
207 AutoConnectOption input_ac,
208 AutoConnectOption output_ac,
209 uint32_t master_out_channels,
210 uint32_t requested_physical_in,
211 uint32_t requested_physical_out,
212 nframes_t initial_length)
215 _target_transport_speed (0.0),
216 _requested_return_frame (-1),
217 _scratch_buffers(new BufferSet()),
218 _silent_buffers(new BufferSet()),
219 _mix_buffers(new BufferSet()),
221 _mmc_port (default_mmc_port),
222 _mtc_port (default_mtc_port),
223 _midi_port (default_midi_port),
224 _midi_clock_port (default_midi_clock_port),
225 _session_dir ( new SessionDirectory(fullpath)),
227 _butler (new Butler (*this)),
228 _post_transport_work (0),
229 _send_timecode_update (false),
230 diskstreams (new DiskstreamList),
231 routes (new RouteList),
232 _total_free_4k_blocks (0),
233 _bundles (new BundleList),
234 _bundle_xml_node (0),
235 _click_io ((IO *) 0),
237 click_emphasis_data (0),
239 _metadata (new SessionMetadata()),
240 _have_rec_enabled_diskstream (false)
242 playlists.reset (new SessionPlaylists);
246 interpolation.add_channel_to (0, 0);
248 if (!eng.connected()) {
249 throw failed_constructor();
252 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
254 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
255 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
257 if (n_physical_inputs) {
258 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
261 if (n_physical_outputs) {
262 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
265 first_stage_init (fullpath, snapshot_name);
267 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
270 if (create (new_session, string(), initial_length)) {
272 throw failed_constructor ();
277 /* set up Master Out and Control Out if necessary */
282 if (master_out_channels) {
283 ChanCount count(DataType::AUDIO, master_out_channels);
284 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
285 boost_debug_shared_ptr_mark_interesting (rt, "Route");
286 boost::shared_ptr<Route> r (rt);
287 r->input()->ensure_io (count, false, this);
288 r->output()->ensure_io (count, false, this);
289 r->set_remote_control_id (control_id);
293 /* prohibit auto-connect to master, because there isn't one */
294 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
297 if (Config->get_use_monitor_bus()) {
298 ChanCount count(DataType::AUDIO, master_out_channels);
299 Route* rt = new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO);
300 boost_debug_shared_ptr_mark_interesting (rt, "Route");
301 shared_ptr<Route> r (rt);
302 r->input()->ensure_io (count, false, this);
303 r->output()->ensure_io (count, false, this);
304 r->set_remote_control_id (control_id++);
310 add_routes (rl, false);
315 if (no_auto_connect()) {
316 input_ac = AutoConnectOption (0);
317 output_ac = AutoConnectOption (0);
320 Config->set_input_auto_connect (input_ac);
321 Config->set_output_auto_connect (output_ac);
323 if (second_stage_init (new_session)) {
325 throw failed_constructor ();
328 store_recent_sessions (_name, _path);
330 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
332 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
343 vector<void*> debug_pointers;
345 /* if we got to here, leaving pending capture state around
349 remove_pending_capture_state ();
351 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
353 _engine.remove_session ();
355 /* clear history so that no references to objects are held any more */
359 /* clear state tree so that no references to objects are held any more */
363 /* reset dynamic state version back to default */
365 Stateful::loading_state_version = 0;
368 delete midi_control_ui;
370 if (click_data != default_click) {
371 delete [] click_data;
374 if (click_emphasis_data != default_click_emphasis) {
375 delete [] click_emphasis_data;
380 delete _scratch_buffers;
381 delete _silent_buffers;
384 /* clear out any pending dead wood from RCU managed objects */
387 diskstreams.flush ();
390 AudioDiskstream::free_working_buffers();
392 /* tell everyone who is still standing that we're about to die */
395 /* tell everyone to drop references and delete objects as we go */
397 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
398 named_selections.clear ();
400 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
401 RegionFactory::delete_all_regions ();
403 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
405 /* reset these three references to special routes before we do the usual route delete thing */
408 _master_out.reset ();
409 _control_out.reset ();
412 RCUWriter<RouteList> writer (routes);
413 boost::shared_ptr<RouteList> r = writer.get_copy ();
415 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
416 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
417 (*i)->drop_references ();
421 /* writer goes out of scope and updates master */
425 boost::shared_ptr<RouteList> r = routes.reader ();
427 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
429 RCUWriter<DiskstreamList> dwriter (diskstreams);
430 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
431 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
432 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
433 (*i)->drop_references ();
438 diskstreams.flush ();
440 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
441 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
442 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
443 i->second->drop_references ();
448 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
449 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
454 Crossfade::set_buffer_size (0);
458 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
461 boost_debug_list_ptrs ();
463 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
467 Session::set_worst_io_latencies ()
469 _worst_output_latency = 0;
470 _worst_input_latency = 0;
472 if (!_engine.connected()) {
476 boost::shared_ptr<RouteList> r = routes.reader ();
478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
479 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
480 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
485 Session::when_engine_running (bool new_session)
487 string first_physical_output;
489 BootMessage (_("Set block size and sample rate"));
491 set_block_size (_engine.frames_per_cycle());
492 set_frame_rate (_engine.frame_rate());
494 BootMessage (_("Using configuration"));
496 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
497 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
499 Config->map_parameters (ff);
500 config.map_parameters (ft);
502 /* every time we reconnect, recompute worst case output latencies */
504 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
506 if (synced_to_jack()) {
507 _engine.transport_stop ();
510 if (config.get_jack_time_master()) {
511 _engine.transport_locate (_transport_frame);
519 _click_io.reset (new ClickIO (*this, "click"));
521 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
523 /* existing state for Click */
526 if (Stateful::loading_state_version < 3000) {
527 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
529 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
534 _clicking = Config->get_clicking ();
538 error << _("could not setup Click I/O") << endmsg;
545 /* default state for Click: dual-mono to first 2 physical outputs */
547 for (int physport = 0; physport < 2; ++physport) {
548 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
550 if (physical_output.length()) {
551 if (_click_io->add_port (physical_output, this)) {
552 // relax, even though its an error
557 if (_click_io->n_ports () > ChanCount::ZERO) {
558 _clicking = Config->get_clicking ();
563 catch (failed_constructor& err) {
564 error << _("cannot setup Click I/O") << endmsg;
567 BootMessage (_("Compute I/O Latencies"));
569 set_worst_io_latencies ();
572 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
575 BootMessage (_("Set up standard connections"));
577 /* Create a set of Bundle objects that map
578 to the physical I/O currently available. We create both
579 mono and stereo bundles, so that the common cases of mono
580 and stereo tracks get bundles to put in their mixer strip
581 in / out menus. There may be a nicer way of achieving that;
582 it doesn't really scale that well to higher channel counts
585 /* mono output bundles */
587 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
589 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
591 shared_ptr<Bundle> c (new Bundle (buf, true));
592 c->add_channel (_("mono"));
593 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
598 /* stereo output bundles */
600 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
601 if (np + 1 < n_physical_outputs) {
603 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
604 shared_ptr<Bundle> c (new Bundle (buf, true));
605 c->add_channel (_("L"));
606 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
607 c->add_channel (_("R"));
608 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
614 /* mono input bundles */
616 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
618 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
620 shared_ptr<Bundle> c (new Bundle (buf, false));
621 c->add_channel (_("mono"));
622 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
627 /* stereo input bundles */
629 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
630 if (np + 1 < n_physical_inputs) {
632 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
634 shared_ptr<Bundle> c (new Bundle (buf, false));
635 c->add_channel (_("L"));
636 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
637 c->add_channel (_("R"));
638 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
644 BootMessage (_("Setup signal flow and plugins"));
646 hookup_io (new_session);
648 if (new_session && !no_auto_connect()) {
650 /* don't connect the master bus outputs if there is a monitor bus */
652 if (_master_out && Config->get_auto_connect_standard_busses() && !_control_out) {
654 /* if requested auto-connect the outputs to the first N physical ports.
657 uint32_t limit = _master_out->n_outputs().n_total();
659 for (uint32_t n = 0; n < limit; ++n) {
660 Port* p = _master_out->output()->nth (n);
661 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
663 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
664 if (_master_out->output()->connect (p, connect_to, this)) {
665 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
675 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
676 are undefined, at best.
679 /* control out listens to master bus (but ignores it
680 under some conditions)
683 uint32_t limit = _control_out->n_inputs().n_audio();
686 for (uint32_t n = 0; n < limit; ++n) {
687 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
688 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
691 string connect_to = o->name();
692 if (_control_out->input()->connect (p, connect_to, this)) {
693 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
701 /* if control out is not connected, connect control out to physical outs
704 if (!_control_out->output()->connected ()) {
706 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
708 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
711 _control_out->output()->connect_ports_to_bundle (b, this);
713 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
714 Config->get_monitor_bus_preferred_bundle())
720 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
721 uint32_t mod = _engine.n_physical_outputs (*t);
722 uint32_t limit = _control_out->n_outputs().get(*t);
724 for (uint32_t n = 0; n < limit; ++n) {
726 Port* p = _control_out->output()->ports().port(*t, n);
727 string connect_to = _engine.get_nth_physical_output (*t, (n % mod));
729 if (!connect_to.empty()) {
730 if (_control_out->output()->connect (p, connect_to, this)) {
731 error << string_compose (
732 _("cannot connect control output %1 to %2"),
745 /* catch up on send+insert cnts */
747 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
749 /* hook us up to the engine */
751 BootMessage (_("Connect to engine"));
753 _engine.set_session (this);
757 Session::hookup_io (bool new_session)
759 /* stop graph reordering notifications from
760 causing resorts, etc.
763 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
768 /* we delay creating the auditioner till now because
769 it makes its own connections to ports.
773 auditioner.reset (new Auditioner (*this));
776 catch (failed_constructor& err) {
777 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
781 /* load bundles, which we may have postponed earlier on */
782 if (_bundle_xml_node) {
783 load_bundles (*_bundle_xml_node);
784 delete _bundle_xml_node;
787 /* Tell all IO objects to connect themselves together */
789 IO::enable_connecting ();
790 MIDI::JACK_MidiPort::MakeConnections ();
792 /* Now reset all panners */
794 Delivery::reset_panners ();
796 /* Connect tracks to monitor/listen bus if there is one.
797 Note that in an existing session, the internal sends will
798 already exist, but we want the routes to notice that
799 they connect to the control out specifically.
803 boost::shared_ptr<RouteList> r = routes.reader ();
804 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
806 if ((*x)->is_control()) {
810 } else if ((*x)->is_master()) {
816 (*x)->listen_via (_control_out,
817 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
823 /* Anyone who cares about input state, wake up and do something */
825 IOConnectionsComplete (); /* EMIT SIGNAL */
827 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
829 /* now handle the whole enchilada as if it was one
835 /* update the full solo state, which can't be
836 correctly determined on a per-route basis, but
837 needs the global overview that only the session
841 update_route_solo_state ();
845 Session::playlist_length_changed ()
847 /* we can't just increase end_location->end() if pl->get_maximum_extent()
848 if larger. if the playlist used to be the longest playlist,
849 and its now shorter, we have to decrease end_location->end(). hence,
850 we have to iterate over all diskstreams and check the
851 playlists currently in use.
857 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
859 boost::shared_ptr<Diskstream> dstream = wp.lock ();
864 boost::shared_ptr<Playlist> playlist;
866 if ((playlist = dstream->playlist()) != 0) {
867 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
870 /* see comment in playlist_length_changed () */
875 Session::record_enabling_legal () const
877 /* this used to be in here, but survey says.... we don't need to restrict it */
878 // if (record_status() == Recording) {
882 if (Config->get_all_safe()) {
889 Session::reset_input_monitor_state ()
891 if (transport_rolling()) {
893 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
895 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
896 if ((*i)->record_enabled ()) {
897 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
898 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
902 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
904 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
905 if ((*i)->record_enabled ()) {
906 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
907 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
914 Session::auto_punch_start_changed (Location* location)
916 replace_event (SessionEvent::PunchIn, location->start());
918 if (get_record_enabled() && config.get_punch_in()) {
919 /* capture start has been changed, so save new pending state */
920 save_state ("", true);
925 Session::auto_punch_end_changed (Location* location)
927 nframes_t when_to_stop = location->end();
928 // when_to_stop += _worst_output_latency + _worst_input_latency;
929 replace_event (SessionEvent::PunchOut, when_to_stop);
933 Session::auto_punch_changed (Location* location)
935 nframes_t when_to_stop = location->end();
937 replace_event (SessionEvent::PunchIn, location->start());
938 //when_to_stop += _worst_output_latency + _worst_input_latency;
939 replace_event (SessionEvent::PunchOut, when_to_stop);
943 Session::auto_loop_changed (Location* location)
945 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
947 if (transport_rolling() && play_loop) {
950 // if (_transport_frame > location->end()) {
952 if (_transport_frame < location->start() || _transport_frame > location->end()) {
953 // relocate to beginning of loop
954 clear_events (SessionEvent::LocateRoll);
956 request_locate (location->start(), true);
959 else if (Config->get_seamless_loop() && !loop_changing) {
961 // schedule a locate-roll to refill the diskstreams at the
963 loop_changing = true;
965 if (location->end() > last_loopend) {
966 clear_events (SessionEvent::LocateRoll);
967 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
974 last_loopend = location->end();
978 Session::set_auto_punch_location (Location* location)
982 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
983 punch_connections.drop_connections();
984 existing->set_auto_punch (false, this);
985 remove_event (existing->start(), SessionEvent::PunchIn);
986 clear_events (SessionEvent::PunchOut);
987 auto_punch_location_changed (0);
996 if (location->end() <= location->start()) {
997 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1001 punch_connections.drop_connections ();
1003 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1004 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1005 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1007 location->set_auto_punch (true, this);
1009 auto_punch_changed (location);
1011 auto_punch_location_changed (location);
1015 Session::set_auto_loop_location (Location* location)
1019 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1020 loop_connections.drop_connections ();
1021 existing->set_auto_loop (false, this);
1022 remove_event (existing->end(), SessionEvent::AutoLoop);
1023 auto_loop_location_changed (0);
1028 if (location == 0) {
1032 if (location->end() <= location->start()) {
1033 error << _("Session: you can't use a mark for auto loop") << endmsg;
1037 last_loopend = location->end();
1039 loop_connections.drop_connections ();
1041 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1042 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1043 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1045 location->set_auto_loop (true, this);
1047 /* take care of our stuff first */
1049 auto_loop_changed (location);
1051 /* now tell everyone else */
1053 auto_loop_location_changed (location);
1057 Session::locations_added (Location *)
1063 Session::locations_changed ()
1065 _locations.apply (*this, &Session::handle_locations_changed);
1069 Session::handle_locations_changed (Locations::LocationList& locations)
1071 Locations::LocationList::iterator i;
1073 bool set_loop = false;
1074 bool set_punch = false;
1076 for (i = locations.begin(); i != locations.end(); ++i) {
1080 if (location->is_auto_punch()) {
1081 set_auto_punch_location (location);
1084 if (location->is_auto_loop()) {
1085 set_auto_loop_location (location);
1089 if (location->is_start()) {
1090 start_location = location;
1092 if (location->is_end()) {
1093 end_location = location;
1098 set_auto_loop_location (0);
1101 set_auto_punch_location (0);
1108 Session::enable_record ()
1110 /* XXX really atomic compare+swap here */
1111 if (g_atomic_int_get (&_record_status) != Recording) {
1112 g_atomic_int_set (&_record_status, Recording);
1113 _last_record_location = _transport_frame;
1114 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1116 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1117 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1118 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1119 if ((*i)->record_enabled ()) {
1120 (*i)->monitor_input (true);
1125 RecordStateChanged ();
1130 Session::disable_record (bool rt_context, bool force)
1134 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1136 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1137 g_atomic_int_set (&_record_status, Disabled);
1139 if (rs == Recording) {
1140 g_atomic_int_set (&_record_status, Enabled);
1144 // FIXME: timestamp correct? [DR]
1145 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1146 // does this /need/ to be sent in all cases?
1148 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1151 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1152 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1154 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1155 if ((*i)->record_enabled ()) {
1156 (*i)->monitor_input (false);
1161 RecordStateChanged (); /* emit signal */
1164 remove_pending_capture_state ();
1170 Session::step_back_from_record ()
1172 /* XXX really atomic compare+swap here */
1173 if (g_atomic_int_get (&_record_status) == Recording) {
1174 g_atomic_int_set (&_record_status, Enabled);
1176 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1177 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1179 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1180 if ((*i)->record_enabled ()) {
1181 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1182 (*i)->monitor_input (false);
1190 Session::maybe_enable_record ()
1192 g_atomic_int_set (&_record_status, Enabled);
1194 /* this function is currently called from somewhere other than an RT thread.
1195 this save_state() call therefore doesn't impact anything.
1198 save_state ("", true);
1200 if (_transport_speed) {
1201 if (!config.get_punch_in()) {
1205 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1206 RecordStateChanged (); /* EMIT SIGNAL */
1213 Session::audible_frame () const
1219 /* the first of these two possible settings for "offset"
1220 mean that the audible frame is stationary until
1221 audio emerges from the latency compensation
1224 the second means that the audible frame is stationary
1225 until audio would emerge from a physical port
1226 in the absence of any plugin latency compensation
1229 offset = _worst_output_latency;
1231 if (offset > current_block_size) {
1232 offset -= current_block_size;
1234 /* XXX is this correct? if we have no external
1235 physical connections and everything is internal
1236 then surely this is zero? still, how
1237 likely is that anyway?
1239 offset = current_block_size;
1242 if (synced_to_jack()) {
1243 tf = _engine.transport_frame();
1245 tf = _transport_frame;
1250 if (!non_realtime_work_pending()) {
1254 /* check to see if we have passed the first guaranteed
1255 audible frame past our last start position. if not,
1256 return that last start point because in terms
1257 of audible frames, we have not moved yet.
1260 if (_transport_speed > 0.0f) {
1262 if (!play_loop || !have_looped) {
1263 if (tf < _last_roll_location + offset) {
1264 return _last_roll_location;
1272 } else if (_transport_speed < 0.0f) {
1274 /* XXX wot? no backward looping? */
1276 if (tf > _last_roll_location - offset) {
1277 return _last_roll_location;
1289 Session::set_frame_rate (nframes_t frames_per_second)
1291 /** \fn void Session::set_frame_size(nframes_t)
1292 the AudioEngine object that calls this guarantees
1293 that it will not be called while we are also in
1294 ::process(). Its fine to do things that block
1298 _base_frame_rate = frames_per_second;
1302 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1306 // XXX we need some equivalent to this, somehow
1307 // SndFileSource::setup_standard_crossfades (frames_per_second);
1311 /* XXX need to reset/reinstantiate all LADSPA plugins */
1315 Session::set_block_size (nframes_t nframes)
1317 /* the AudioEngine guarantees
1318 that it will not be called while we are also in
1319 ::process(). It is therefore fine to do things that block
1324 current_block_size = nframes;
1326 ensure_buffers(_scratch_buffers->available());
1328 delete [] _gain_automation_buffer;
1329 _gain_automation_buffer = new gain_t[nframes];
1331 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1333 boost::shared_ptr<RouteList> r = routes.reader ();
1335 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1336 (*i)->set_block_size (nframes);
1339 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1340 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1341 (*i)->set_block_size (nframes);
1344 set_worst_io_latencies ();
1349 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1352 nframes_t fade_frames;
1354 /* Don't allow fade of less 1 frame */
1356 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1363 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1367 default_fade_msecs = fade_msecs;
1368 default_fade_steepness = steepness;
1371 // jlc, WTF is this!
1372 Glib::RWLock::ReaderLock lm (route_lock);
1373 AudioRegion::set_default_fade (steepness, fade_frames);
1378 /* XXX have to do this at some point */
1379 /* foreach region using default fade, reset, then
1380 refill_all_diskstream_buffers ();
1385 struct RouteSorter {
1386 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1387 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1389 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1392 if (r1->fed_by.empty()) {
1393 if (r2->fed_by.empty()) {
1394 /* no ardour-based connections inbound to either route. just use signal order */
1395 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1397 /* r2 has connections, r1 does not; run r1 early */
1401 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1408 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1410 shared_ptr<Route> r2;
1412 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1413 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1417 /* make a copy of the existing list of routes that feed r1 */
1419 set<weak_ptr<Route> > existing = r1->fed_by;
1421 /* for each route that feeds r1, recurse, marking it as feeding
1425 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1426 if (!(r2 = (*i).lock ())) {
1427 /* (*i) went away, ignore it */
1431 /* r2 is a route that feeds r1 which somehow feeds base. mark
1432 base as being fed by r2
1435 rbase->fed_by.insert (r2);
1439 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1443 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1447 /* now recurse, so that we can mark base as being fed by
1448 all routes that feed r2
1451 trace_terminal (r2, rbase);
1458 Session::resort_routes ()
1460 /* don't do anything here with signals emitted
1461 by Routes while we are being destroyed.
1464 if (_state_of_the_state & Deletion) {
1471 RCUWriter<RouteList> writer (routes);
1472 shared_ptr<RouteList> r = writer.get_copy ();
1473 resort_routes_using (r);
1474 /* writer goes out of scope and forces update */
1479 Session::resort_routes_using (shared_ptr<RouteList> r)
1481 RouteList::iterator i, j;
1483 for (i = r->begin(); i != r->end(); ++i) {
1485 (*i)->fed_by.clear ();
1487 for (j = r->begin(); j != r->end(); ++j) {
1489 /* although routes can feed themselves, it will
1490 cause an endless recursive descent if we
1491 detect it. so don't bother checking for
1499 if ((*j)->feeds (*i)) {
1500 (*i)->fed_by.insert (*j);
1505 for (i = r->begin(); i != r->end(); ++i) {
1506 trace_terminal (*i, *i);
1513 cerr << "finished route resort\n";
1515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1516 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1523 /** Find the route name starting with \a base with the lowest \a id.
1525 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1526 * The available route name with the lowest ID will be used, and \a id
1527 * will be set to the ID.
1529 * \return false if a route name could not be found, and \a track_name
1530 * and \a id do not reflect a free route name.
1533 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1536 snprintf (name, name_len, "%s %" PRIu32, base, id);
1538 if (route_by_name (name) == 0) {
1544 } while (id < (UINT_MAX-1));
1550 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1552 in = ChanCount::ZERO;
1553 out = ChanCount::ZERO;
1554 shared_ptr<RouteList> r = routes.reader ();
1555 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1556 if (!(*i)->is_hidden()) {
1557 in += (*i)->n_inputs();
1558 out += (*i)->n_outputs();
1563 list<boost::shared_ptr<MidiTrack> >
1564 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1566 char track_name[32];
1567 uint32_t track_id = 0;
1568 ChanCount existing_inputs;
1569 ChanCount existing_outputs;
1571 RouteList new_routes;
1572 list<boost::shared_ptr<MidiTrack> > ret;
1573 uint32_t control_id;
1575 count_existing_route_channels (existing_inputs, existing_outputs);
1577 control_id = ntracks() + nbusses();
1580 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1581 error << "cannot find name for new midi track" << endmsg;
1585 shared_ptr<MidiTrack> track;
1588 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1589 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1590 track = boost::shared_ptr<MidiTrack>(mt);
1592 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1593 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1598 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1599 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1603 auto_connect_route (track, existing_inputs, existing_outputs);
1605 track->midi_diskstream()->non_realtime_input_change();
1607 route_group->add (track);
1610 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1611 track->set_remote_control_id (control_id);
1613 new_routes.push_back (track);
1614 ret.push_back (track);
1617 catch (failed_constructor &err) {
1618 error << _("Session: could not create new midi track.") << endmsg;
1621 /* we need to get rid of this, since the track failed to be created */
1622 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1625 RCUWriter<DiskstreamList> writer (diskstreams);
1626 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1627 ds->remove (track->midi_diskstream());
1634 catch (AudioEngine::PortRegistrationFailure& pfe) {
1636 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
1639 /* we need to get rid of this, since the track failed to be created */
1640 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1643 RCUWriter<DiskstreamList> writer (diskstreams);
1644 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1645 ds->remove (track->midi_diskstream());
1656 if (!new_routes.empty()) {
1657 add_routes (new_routes, false);
1658 save_state (_current_snapshot_name);
1665 Session::auto_connect_route (boost::shared_ptr<Route> route,
1666 ChanCount& existing_inputs, ChanCount& existing_outputs)
1668 /* If both inputs and outputs are auto-connected to physical ports,
1669 use the max of input and output offsets to ensure auto-connected
1670 port numbers always match up (e.g. the first audio input and the
1671 first audio output of the route will have the same physical
1672 port number). Otherwise just use the lowest input or output
1675 const bool in_out_physical =
1676 (Config->get_input_auto_connect() & AutoConnectPhysical)
1677 && (Config->get_output_auto_connect() & AutoConnectPhysical);
1679 const ChanCount in_offset = in_out_physical
1680 ? ChanCount::max(existing_inputs, existing_outputs)
1683 const ChanCount out_offset = in_out_physical
1684 ? ChanCount::max(existing_inputs, existing_outputs)
1687 static string empty_string;
1688 string& port = empty_string;
1690 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1691 vector<string> physinputs;
1692 vector<string> physoutputs;
1694 _engine.get_physical_outputs (*t, physoutputs);
1695 _engine.get_physical_inputs (*t, physinputs);
1697 if (!physinputs.empty()) {
1698 uint32_t nphysical_in = physinputs.size();
1699 for (uint32_t i = 0; i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1700 port = empty_string;
1702 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1703 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1706 if (!port.empty() && route->input()->connect (
1707 route->input()->ports().port(*t, i), port, this)) {
1713 if (!physoutputs.empty()) {
1714 uint32_t nphysical_out = physoutputs.size();
1715 for (uint32_t i = 0; i < route->n_outputs().get(*t); ++i) {
1716 port = empty_string;
1718 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1719 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1720 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1721 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1722 port = _master_out->input()->ports().port(*t,
1723 i % _master_out->input()->n_ports().get(*t))->name();
1727 if (!port.empty() && route->output()->connect (
1728 route->output()->ports().port(*t, i), port, this)) {
1735 existing_inputs += route->n_inputs();
1736 existing_outputs += route->n_outputs();
1739 list< boost::shared_ptr<AudioTrack> >
1740 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1742 char track_name[32];
1743 uint32_t track_id = 0;
1744 ChanCount existing_inputs;
1745 ChanCount existing_outputs;
1747 RouteList new_routes;
1748 list<boost::shared_ptr<AudioTrack> > ret;
1749 uint32_t control_id;
1751 count_existing_route_channels (existing_inputs, existing_outputs);
1753 control_id = ntracks() + nbusses() + 1;
1756 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1757 error << "cannot find name for new audio track" << endmsg;
1761 shared_ptr<AudioTrack> track;
1764 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1765 boost_debug_shared_ptr_mark_interesting (at, "Track");
1766 track = boost::shared_ptr<AudioTrack>(at);
1768 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1769 error << string_compose (
1770 _("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 (
1778 _("cannot configure %1 in/%2 out configuration for new audio track"),
1779 input_channels, output_channels)
1784 auto_connect_route (track, existing_inputs, existing_outputs);
1787 route_group->add (track);
1790 track->audio_diskstream()->non_realtime_input_change();
1792 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1793 track->set_remote_control_id (control_id);
1796 new_routes.push_back (track);
1797 ret.push_back (track);
1800 catch (failed_constructor &err) {
1801 error << _("Session: could not create new audio track.") << endmsg;
1804 /* we need to get rid of this, since the track failed to be created */
1805 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1808 RCUWriter<DiskstreamList> writer (diskstreams);
1809 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1810 ds->remove (track->audio_diskstream());
1817 catch (AudioEngine::PortRegistrationFailure& pfe) {
1819 error << pfe.what() << endmsg;
1822 /* we need to get rid of this, since the track failed to be created */
1823 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1826 RCUWriter<DiskstreamList> writer (diskstreams);
1827 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1828 ds->remove (track->audio_diskstream());
1839 if (!new_routes.empty()) {
1840 add_routes (new_routes, true);
1847 Session::set_remote_control_ids ()
1849 RemoteModel m = Config->get_remote_model();
1850 bool emit_signal = false;
1852 shared_ptr<RouteList> r = routes.reader ();
1854 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1855 if (MixerOrdered == m) {
1856 long order = (*i)->order_key(N_("signal"));
1857 (*i)->set_remote_control_id (order+1, false);
1859 } else if (EditorOrdered == m) {
1860 long order = (*i)->order_key(N_("editor"));
1861 (*i)->set_remote_control_id (order+1, false);
1863 } else if (UserOrdered == m) {
1864 //do nothing ... only changes to remote id's are initiated by user
1869 Route::RemoteControlIDChange();
1875 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1878 uint32_t bus_id = 0;
1879 ChanCount existing_inputs;
1880 ChanCount existing_outputs;
1883 uint32_t control_id;
1885 count_existing_route_channels (existing_inputs, existing_outputs);
1887 control_id = ntracks() + nbusses() + 1;
1890 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1891 error << "cannot find name for new audio bus" << endmsg;
1896 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1897 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1898 shared_ptr<Route> bus (rt);
1900 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1901 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1902 input_channels, output_channels)
1908 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1909 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1910 input_channels, output_channels)
1915 auto_connect_route (bus, existing_inputs, existing_outputs);
1918 route_group->add (bus);
1920 bus->set_remote_control_id (control_id);
1924 bus->add_internal_return ();
1927 ret.push_back (bus);
1931 catch (failed_constructor &err) {
1932 error << _("Session: could not create new audio route.") << endmsg;
1936 catch (AudioEngine::PortRegistrationFailure& pfe) {
1937 error << pfe.what() << endmsg;
1947 add_routes (ret, true);
1955 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1959 uint32_t control_id;
1961 uint32_t number = 0;
1963 if (!tree.read (template_path.c_str())) {
1967 XMLNode* node = tree.root();
1969 control_id = ntracks() + nbusses() + 1;
1973 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1975 std::string node_name = IO::name_from_state (*node_copy.children().front());
1977 /* generate a new name by adding a number to the end of the template name */
1978 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1979 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1983 IO::set_name_in_state (*node_copy.children().front(), name);
1985 Track::zero_diskstream_id_in_xml (node_copy);
1988 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1991 error << _("Session: cannot create track/bus from template description") << endmsg;
1995 if (boost::dynamic_pointer_cast<Track>(route)) {
1996 /* force input/output change signals so that the new diskstream
1997 picks up the configuration of the route. During session
1998 loading this normally happens in a different way.
2000 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2001 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2004 route->set_remote_control_id (control_id);
2007 ret.push_back (route);
2010 catch (failed_constructor &err) {
2011 error << _("Session: could not create new route from template") << endmsg;
2015 catch (AudioEngine::PortRegistrationFailure& pfe) {
2016 error << pfe.what() << endmsg;
2025 add_routes (ret, true);
2032 Session::add_routes (RouteList& new_routes, bool save)
2035 RCUWriter<RouteList> writer (routes);
2036 shared_ptr<RouteList> r = writer.get_copy ();
2037 r->insert (r->end(), new_routes.begin(), new_routes.end());
2040 /* if there is no control out and we're not in the middle of loading,
2041 resort the graph here. if there is a control out, we will resort
2042 toward the end of this method. if we are in the middle of loading,
2043 we will resort when done.
2046 if (!_control_out && IO::connecting_legal) {
2047 resort_routes_using (r);
2051 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2053 boost::weak_ptr<Route> wpr (*x);
2054 boost::shared_ptr<Route> r (*x);
2056 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2057 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
2058 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2059 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2060 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2061 r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2063 if (r->is_master()) {
2067 if (r->is_control()) {
2072 if (_control_out && IO::connecting_legal) {
2074 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2075 if ((*x)->is_control()) {
2077 } else if ((*x)->is_master()) {
2080 (*x)->listen_via (_control_out,
2081 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2092 save_state (_current_snapshot_name);
2095 RouteAdded (new_routes); /* EMIT SIGNAL */
2096 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2100 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2102 boost::shared_ptr<RouteList> r = routes.reader ();
2103 boost::shared_ptr<Send> s;
2107 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2108 if (boost::dynamic_pointer_cast<Track>(*i)) {
2109 if ((s = (*i)->internal_send_for (dest)) != 0) {
2110 s->amp()->gain_control()->set_value (0.0);
2117 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2119 boost::shared_ptr<RouteList> r = routes.reader ();
2120 boost::shared_ptr<Send> s;
2124 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2125 if (boost::dynamic_pointer_cast<Track>(*i)) {
2126 if ((s = (*i)->internal_send_for (dest)) != 0) {
2127 s->amp()->gain_control()->set_value (1.0);
2134 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2136 boost::shared_ptr<RouteList> r = routes.reader ();
2137 boost::shared_ptr<Send> s;
2141 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2142 if (boost::dynamic_pointer_cast<Track>(*i)) {
2143 if ((s = (*i)->internal_send_for (dest)) != 0) {
2144 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2151 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2153 boost::shared_ptr<RouteList> r = routes.reader ();
2154 boost::shared_ptr<RouteList> t (new RouteList);
2156 /* only send tracks */
2158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2159 if (boost::dynamic_pointer_cast<Track>(*i)) {
2164 add_internal_sends (dest, p, t);
2168 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2170 if (dest->is_control() || dest->is_master()) {
2174 if (!dest->internal_return()) {
2175 dest->add_internal_return();
2178 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2180 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2184 (*i)->listen_via (dest, p, true, true);
2191 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2193 /* need to do this in case we're rolling at the time, to prevent false underruns */
2194 dstream->do_refill_with_alloc ();
2196 dstream->set_block_size (current_block_size);
2199 RCUWriter<DiskstreamList> writer (diskstreams);
2200 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2201 ds->push_back (dstream);
2202 /* writer goes out of scope, copies ds back to main */
2205 dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr<Diskstream> (dstream)));
2206 /* this will connect to future changes, and check the current length */
2207 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2209 dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this));
2211 dstream->prepare ();
2216 Session::remove_route (shared_ptr<Route> route)
2219 RCUWriter<RouteList> writer (routes);
2220 shared_ptr<RouteList> rs = writer.get_copy ();
2224 /* deleting the master out seems like a dumb
2225 idea, but its more of a UI policy issue
2229 if (route == _master_out) {
2230 _master_out = shared_ptr<Route> ();
2233 if (route == _control_out) {
2235 /* cancel control outs for all routes */
2237 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2238 (*r)->drop_listen (_control_out);
2241 _control_out.reset ();
2244 update_route_solo_state ();
2246 /* writer goes out of scope, forces route list update */
2249 boost::shared_ptr<Track> t;
2250 boost::shared_ptr<Diskstream> ds;
2252 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2253 ds = t->diskstream();
2259 RCUWriter<DiskstreamList> dsl (diskstreams);
2260 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2265 find_current_end ();
2267 // We need to disconnect the routes inputs and outputs
2269 route->input()->disconnect (0);
2270 route->output()->disconnect (0);
2272 /* if the route had internal sends sending to it, remove them */
2273 if (route->internal_return()) {
2275 boost::shared_ptr<RouteList> r = routes.reader ();
2276 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2277 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2279 (*i)->remove_processor (s);
2284 update_latency_compensation (false, false);
2287 /* get rid of it from the dead wood collection in the route list manager */
2289 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2293 /* try to cause everyone to drop their references */
2295 route->drop_references ();
2297 sync_order_keys (N_("session"));
2299 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2301 /* save the new state of the world */
2303 if (save_state (_current_snapshot_name)) {
2304 save_history (_current_snapshot_name);
2309 Session::route_mute_changed (void* /*src*/)
2315 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2317 boost::shared_ptr<Route> route = wpr.lock();
2319 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2323 if (route->listening()) {
2325 } else if (_listen_cnt > 0) {
2331 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2333 if (solo_update_disabled) {
2338 boost::shared_ptr<Route> route = wpr.lock ();
2341 /* should not happen */
2342 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2346 shared_ptr<RouteList> r = routes.reader ();
2349 if (route->self_soloed()) {
2355 /* now mod the solo level of all other routes except master & control outs
2356 so that they will be silent if appropriate.
2359 solo_update_disabled = true;
2361 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2362 bool via_sends_only;
2364 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_control() || (*i)->is_hidden()) {
2366 } else if ((*i)->feeds (route, &via_sends_only)) {
2367 if (!via_sends_only) {
2368 (*i)->mod_solo_by_others (delta);
2373 /* make sure master is never muted by solo */
2375 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2376 _master_out->mod_solo_by_others (1);
2379 /* ditto for control outs make sure master is never muted by solo */
2381 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2382 _control_out->mod_solo_by_others (1);
2385 solo_update_disabled = false;
2386 update_route_solo_state (r);
2387 SoloChanged (); /* EMIT SIGNAL */
2392 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2394 /* now figure out if anything that matters is soloed (or is "listening")*/
2396 bool something_soloed = false;
2397 uint32_t listeners = 0;
2400 r = routes.reader();
2403 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2404 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2405 something_soloed = true;
2409 if (!(*i)->is_hidden() && (*i)->listening()) {
2414 if (something_soloed != _non_soloed_outs_muted) {
2415 _non_soloed_outs_muted = something_soloed;
2416 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2420 _listen_cnt = listeners;
2424 boost::shared_ptr<RouteList>
2425 Session::get_routes_with_internal_returns() const
2427 shared_ptr<RouteList> r = routes.reader ();
2428 boost::shared_ptr<RouteList> rl (new RouteList);
2430 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2431 if ((*i)->internal_return ()) {
2439 Session::route_by_name (string name)
2441 shared_ptr<RouteList> r = routes.reader ();
2443 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2444 if ((*i)->name() == name) {
2449 return shared_ptr<Route> ((Route*) 0);
2453 Session::route_by_id (PBD::ID id)
2455 shared_ptr<RouteList> r = routes.reader ();
2457 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2458 if ((*i)->id() == id) {
2463 return shared_ptr<Route> ((Route*) 0);
2467 Session::route_by_remote_id (uint32_t id)
2469 shared_ptr<RouteList> r = routes.reader ();
2471 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2472 if ((*i)->remote_control_id() == id) {
2477 return shared_ptr<Route> ((Route*) 0);
2481 Session::find_current_end ()
2483 if (_state_of_the_state & Loading) {
2487 nframes_t max = get_maximum_extent ();
2489 if (max > end_location->end()) {
2490 end_location->set_end (max);
2492 DurationChanged(); /* EMIT SIGNAL */
2497 Session::get_maximum_extent () const
2502 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2504 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2505 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2507 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2508 if ((me = pl->get_maximum_extent()) > max) {
2516 boost::shared_ptr<Diskstream>
2517 Session::diskstream_by_name (string name)
2519 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2521 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2522 if ((*i)->name() == name) {
2527 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2530 boost::shared_ptr<Diskstream>
2531 Session::diskstream_by_id (const PBD::ID& id)
2533 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2535 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2536 if ((*i)->id() == id) {
2541 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2544 /* Region management */
2547 Session::new_region_name (string old)
2549 string::size_type last_period;
2551 string::size_type len = old.length() + 64;
2554 if ((last_period = old.find_last_of ('.')) == string::npos) {
2556 /* no period present - add one explicitly */
2559 last_period = old.length() - 1;
2564 number = atoi (old.substr (last_period+1).c_str());
2568 while (number < (UINT_MAX-1)) {
2570 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2571 RegionFactory::RegionMap::const_iterator i;
2576 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2579 for (i = regions.begin(); i != regions.end(); ++i) {
2580 if (i->second->name() == sbuf) {
2585 if (i == regions.end()) {
2590 if (number != (UINT_MAX-1)) {
2594 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2599 Session::region_name (string& result, string base, bool newlevel)
2604 if (base.find("/") != string::npos) {
2605 base = base.substr(base.find_last_of("/") + 1);
2610 snprintf (buf, sizeof (buf), "%d", RegionFactory::nregions() + 1);
2619 string::size_type pos;
2621 pos = base.find_last_of ('.');
2623 /* pos may be npos, but then we just use entire base */
2625 subbase = base.substr (0, pos);
2630 Glib::Mutex::Lock lm (region_lock);
2632 map<string,uint32_t>::iterator x;
2636 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2638 region_name_map[subbase] = 1;
2641 snprintf (buf, sizeof (buf), ".%d", x->second);
2652 Session::add_region (boost::shared_ptr<Region> region)
2654 vector<boost::shared_ptr<Region> > v;
2655 v.push_back (region);
2660 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2662 /* mark dirty because something has changed
2667 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2669 boost::shared_ptr<Region> region = *ii;
2672 region->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region)));
2673 update_region_name_map (region);
2676 if (!new_regions.empty()) {
2677 RegionsAdded (new_regions); /* EMIT SIGNAL */
2682 Session::update_region_name_map (boost::shared_ptr<Region> region)
2684 string::size_type last_period = region->name().find_last_of ('.');
2686 if (last_period != string::npos && last_period < region->name().length() - 1) {
2688 string base = region->name().substr (0, last_period);
2689 string number = region->name().substr (last_period+1);
2690 map<string,uint32_t>::iterator x;
2692 /* note that if there is no number, we get zero from atoi,
2696 region_name_map[base] = atoi (number);
2701 Session::region_changed (const PropertyChange& what_changed, boost::weak_ptr<Region> weak_region)
2703 boost::shared_ptr<Region> region (weak_region.lock ());
2709 if (what_changed.contains (Properties::hidden)) {
2710 /* relay hidden changes */
2711 RegionHiddenChange (region);
2714 if (what_changed.contains (Properties::name)) {
2715 update_region_name_map (region);
2720 Session::remove_region (boost::weak_ptr<Region> weak_region)
2722 boost::shared_ptr<Region> region (weak_region.lock ());
2728 RegionFactory::map_remove (region);
2731 RegionRemoved(region); /* EMIT SIGNAL */
2734 boost::shared_ptr<Region>
2735 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2737 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2738 RegionFactory::RegionMap::const_iterator i;
2739 boost::shared_ptr<Region> region;
2741 Glib::Mutex::Lock lm (region_lock);
2743 for (i = regions.begin(); i != regions.end(); ++i) {
2747 if (region->whole_file()) {
2749 if (child->source_equivalent (region)) {
2755 return boost::shared_ptr<Region> ();
2759 Session::destroy_region (boost::shared_ptr<Region> region)
2761 vector<boost::shared_ptr<Source> > srcs;
2764 if (region->playlist()) {
2765 region->playlist()->destroy_region (region);
2768 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2769 srcs.push_back (region->source (n));
2773 region->drop_references ();
2775 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2777 (*i)->mark_for_remove ();
2778 (*i)->drop_references ();
2780 cerr << "source was not used by any playlist\n";
2787 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2789 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2790 destroy_region (*i);
2796 Session::remove_last_capture ()
2798 list<boost::shared_ptr<Region> > r;
2800 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2802 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2803 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2806 r.insert (r.end(), l.begin(), l.end());
2811 destroy_regions (r);
2813 save_state (_current_snapshot_name);
2818 /* Source Management */
2821 Session::add_source (boost::shared_ptr<Source> source)
2823 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2824 pair<SourceMap::iterator,bool> result;
2826 entry.first = source->id();
2827 entry.second = source;
2830 Glib::Mutex::Lock lm (source_lock);
2831 result = sources.insert (entry);
2834 if (result.second) {
2838 boost::shared_ptr<AudioFileSource> afs;
2840 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2841 if (Config->get_auto_analyse_audio()) {
2842 Analyser::queue_source_for_analysis (source, false);
2848 Session::remove_source (boost::weak_ptr<Source> src)
2850 SourceMap::iterator i;
2851 boost::shared_ptr<Source> source = src.lock();
2858 Glib::Mutex::Lock lm (source_lock);
2860 if ((i = sources.find (source->id())) != sources.end()) {
2865 if (!_state_of_the_state & InCleanup) {
2867 /* save state so we don't end up with a session file
2868 referring to non-existent sources.
2871 save_state (_current_snapshot_name);
2875 boost::shared_ptr<Source>
2876 Session::source_by_id (const PBD::ID& id)
2878 Glib::Mutex::Lock lm (source_lock);
2879 SourceMap::iterator i;
2880 boost::shared_ptr<Source> source;
2882 if ((i = sources.find (id)) != sources.end()) {
2889 boost::shared_ptr<Source>
2890 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2892 Glib::Mutex::Lock lm (source_lock);
2894 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2895 cerr << "comparing " << path << " with " << i->second->name() << endl;
2896 boost::shared_ptr<AudioFileSource> afs
2897 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2899 if (afs && afs->path() == path && chn == afs->channel()) {
2903 return boost::shared_ptr<Source>();
2908 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2911 string old_basename = PBD::basename_nosuffix (oldname);
2912 string new_legalized = legalize_for_path (newname);
2914 /* note: we know (or assume) the old path is already valid */
2918 /* destructive file sources have a name of the form:
2920 /path/to/Tnnnn-NAME(%[LR])?.wav
2922 the task here is to replace NAME with the new name.
2925 /* find last slash */
2929 string::size_type slash;
2930 string::size_type dash;
2932 if ((slash = path.find_last_of ('/')) == string::npos) {
2936 dir = path.substr (0, slash+1);
2938 /* '-' is not a legal character for the NAME part of the path */
2940 if ((dash = path.find_last_of ('-')) == string::npos) {
2944 prefix = path.substr (slash+1, dash-(slash+1));
2949 path += new_legalized;
2950 path += ".wav"; /* XXX gag me with a spoon */
2954 /* non-destructive file sources have a name of the form:
2956 /path/to/NAME-nnnnn(%[LR])?.ext
2958 the task here is to replace NAME with the new name.
2963 string::size_type slash;
2964 string::size_type dash;
2965 string::size_type postfix;
2967 /* find last slash */
2969 if ((slash = path.find_last_of ('/')) == string::npos) {
2973 dir = path.substr (0, slash+1);
2975 /* '-' is not a legal character for the NAME part of the path */
2977 if ((dash = path.find_last_of ('-')) == string::npos) {
2981 suffix = path.substr (dash+1);
2983 // Suffix is now everything after the dash. Now we need to eliminate
2984 // the nnnnn part, which is done by either finding a '%' or a '.'
2986 postfix = suffix.find_last_of ("%");
2987 if (postfix == string::npos) {
2988 postfix = suffix.find_last_of ('.');
2991 if (postfix != string::npos) {
2992 suffix = suffix.substr (postfix);
2994 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2998 const uint32_t limit = 10000;
2999 char buf[PATH_MAX+1];
3001 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3003 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3005 if (access (buf, F_OK) != 0) {
3013 error << "FATAL ERROR! Could not find a " << endl;
3021 /** Return the full path (in some session directory) for a new within-session source.
3022 * \a name must be a session-unique name that does not contain slashes
3023 * (e.g. as returned by new_*_source_name)
3026 Session::new_source_path_from_name (DataType type, const string& name)
3028 assert(name.find("/") == string::npos);
3030 SessionDirectory sdir(get_best_session_directory_for_new_source());
3033 if (type == DataType::AUDIO) {
3034 p = sdir.sound_path();
3035 } else if (type == DataType::MIDI) {
3036 p = sdir.midi_path();
3038 error << "Unknown source type, unable to create file path" << endmsg;
3043 return p.to_string();
3047 Session::peak_path (Glib::ustring base) const
3049 sys::path peakfile_path(_session_dir->peak_path());
3050 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3051 return peakfile_path.to_string();
3054 /** Return a unique name based on \a base for a new internal audio source */
3056 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3060 char buf[PATH_MAX+1];
3061 const uint32_t limit = 10000;
3065 legalized = legalize_for_path (base);
3067 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3068 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3070 vector<space_and_path>::iterator i;
3071 uint32_t existing = 0;
3073 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3075 SessionDirectory sdir((*i).path);
3077 spath = sdir.sound_path().to_string();
3082 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3083 spath.c_str(), cnt, legalized.c_str());
3084 } else if (nchan == 2) {
3086 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3087 spath.c_str(), cnt, legalized.c_str());
3089 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3090 spath.c_str(), cnt, legalized.c_str());
3092 } else if (nchan < 26) {
3093 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3094 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3096 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3097 spath.c_str(), cnt, legalized.c_str());
3106 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3107 } else if (nchan == 2) {
3109 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3111 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3113 } else if (nchan < 26) {
3114 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3116 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3120 if (sys::exists(buf)) {
3126 if (existing == 0) {
3131 error << string_compose(
3132 _("There are already %1 recordings for %2, which I consider too many."),
3133 limit, base) << endmsg;
3135 throw failed_constructor();
3139 return Glib::path_get_basename(buf);
3142 /** Create a new within-session audio source */
3143 boost::shared_ptr<AudioFileSource>
3144 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3146 const size_t n_chans = ds.n_channels().n_audio();
3147 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3148 const string path = new_source_path_from_name(DataType::AUDIO, name);
3150 return boost::dynamic_pointer_cast<AudioFileSource> (
3151 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3154 /** Return a unique name based on \a base for a new internal MIDI source */
3156 Session::new_midi_source_name (const string& base)
3159 char buf[PATH_MAX+1];
3160 const uint32_t limit = 10000;
3164 legalized = legalize_for_path (base);
3166 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3167 for (cnt = 1; cnt <= limit; ++cnt) {
3169 vector<space_and_path>::iterator i;
3170 uint32_t existing = 0;
3172 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3174 SessionDirectory sdir((*i).path);
3176 sys::path p = sdir.midi_path();
3179 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3181 if (sys::exists (buf)) {
3186 if (existing == 0) {
3191 error << string_compose(
3192 _("There are already %1 recordings for %2, which I consider too many."),
3193 limit, base) << endmsg;
3195 throw failed_constructor();
3199 return Glib::path_get_basename(buf);
3203 /** Create a new within-session MIDI source */
3204 boost::shared_ptr<MidiSource>
3205 Session::create_midi_source_for_session (MidiDiskstream& ds)
3207 const string name = new_midi_source_name (ds.name());
3208 const string path = new_source_path_from_name (DataType::MIDI, name);
3210 return boost::dynamic_pointer_cast<SMFSource> (
3211 SourceFactory::createWritable (
3212 DataType::MIDI, *this, path, false, frame_rate()));
3217 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3219 if (playlist->hidden()) {
3223 playlists->add (playlist);
3226 playlist->release();
3233 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3235 if (_state_of_the_state & Deletion) {
3239 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3245 playlists->remove (playlist);
3251 Session::set_audition (boost::shared_ptr<Region> r)
3253 pending_audition_region = r;
3254 add_post_transport_work (PostTransportAudition);
3255 _butler->schedule_transport_work ();
3259 Session::audition_playlist ()
3261 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3262 ev->region.reset ();
3267 Session::non_realtime_set_audition ()
3269 if (!pending_audition_region) {
3270 auditioner->audition_current_playlist ();
3272 auditioner->audition_region (pending_audition_region);
3273 pending_audition_region.reset ();
3275 AuditionActive (true); /* EMIT SIGNAL */
3279 Session::audition_region (boost::shared_ptr<Region> r)
3281 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3287 Session::cancel_audition ()
3289 if (auditioner->active()) {
3290 auditioner->cancel_audition ();
3291 AuditionActive (false); /* EMIT SIGNAL */
3296 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3298 if (a->is_control()) {
3301 if (b->is_control()) {
3304 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3308 Session::remove_empty_sounds ()
3310 vector<string> audio_filenames;
3312 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3314 Glib::Mutex::Lock lm (source_lock);
3316 TapeFileMatcher tape_file_matcher;
3318 remove_if (audio_filenames.begin(), audio_filenames.end(),
3319 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3321 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3323 sys::path audio_file_path (_session_dir->sound_path());
3325 audio_file_path /= *i;
3327 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3331 sys::remove (audio_file_path);
3332 const string peakfile = peak_path (audio_file_path.to_string());
3333 sys::remove (peakfile);
3335 catch (const sys::filesystem_error& err)
3337 error << err.what() << endmsg;
3344 Session::is_auditioning () const
3346 /* can be called before we have an auditioner object */
3348 return auditioner->active();
3355 Session::n_diskstreams () const
3359 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3361 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3362 if (!(*i)->hidden()) {
3370 Session::graph_reordered ()
3372 /* don't do this stuff if we are setting up connections
3373 from a set_state() call or creating new tracks. Ditto for deletion.
3376 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3380 /* every track/bus asked for this to be handled but it was deferred because
3381 we were connecting. do it now.
3384 request_input_change_handling ();
3388 /* force all diskstreams to update their capture offset values to
3389 reflect any changes in latencies within the graph.
3392 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3394 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3395 (*i)->set_capture_offset ();
3400 Session::add_processor (Processor* processor)
3402 /* Session does not own Processors (they belong to a Route) but we do want to track
3403 the arrival and departure of port inserts, sends and returns for naming
3406 processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
3411 Session::remove_processor (Processor* processor)
3415 PortInsert* port_insert;
3417 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3418 insert_bitset[port_insert->bit_slot()] = false;
3419 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3420 send_bitset[send->bit_slot()] = false;
3421 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3422 return_bitset[retrn->bit_slot()] = false;
3429 Session::available_capture_duration ()
3431 float sample_bytes_on_disk = 4.0; // keep gcc happy
3433 switch (config.get_native_file_data_format()) {
3435 sample_bytes_on_disk = 4.0;
3439 sample_bytes_on_disk = 3.0;
3443 sample_bytes_on_disk = 2.0;
3447 /* impossible, but keep some gcc versions happy */
3448 fatal << string_compose (_("programming error: %1"),
3449 X_("illegal native file data format"))
3454 double scale = 4096.0 / sample_bytes_on_disk;
3456 if (_total_free_4k_blocks * scale > (double) max_frames) {
3460 return (nframes_t) floor (_total_free_4k_blocks * scale);
3464 Session::add_bundle (shared_ptr<Bundle> bundle)
3467 RCUWriter<BundleList> writer (_bundles);
3468 boost::shared_ptr<BundleList> b = writer.get_copy ();
3469 b->push_back (bundle);
3472 BundleAdded (bundle); /* EMIT SIGNAL */
3478 Session::remove_bundle (shared_ptr<Bundle> bundle)
3480 bool removed = false;
3483 RCUWriter<BundleList> writer (_bundles);
3484 boost::shared_ptr<BundleList> b = writer.get_copy ();
3485 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3487 if (i != b->end()) {
3494 BundleRemoved (bundle); /* EMIT SIGNAL */
3501 Session::bundle_by_name (string name) const
3503 boost::shared_ptr<BundleList> b = _bundles.reader ();
3505 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3506 if ((*i)->name() == name) {
3511 return boost::shared_ptr<Bundle> ();
3515 Session::tempo_map_changed (const PropertyChange&)
3519 playlists->update_after_tempo_map_change ();
3524 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3525 * the given count with the current block size.
3528 Session::ensure_buffers (ChanCount howmany)
3530 if (current_block_size == 0) {
3531 return; // too early? (is this ok?)
3534 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3535 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3536 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3537 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3538 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3541 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3545 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3547 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3548 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3553 Session::next_insert_id ()
3555 /* this doesn't really loop forever. just think about it */
3558 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3559 if (!insert_bitset[n]) {
3560 insert_bitset[n] = true;
3566 /* none available, so resize and try again */
3568 insert_bitset.resize (insert_bitset.size() + 16, false);
3573 Session::next_send_id ()
3575 /* this doesn't really loop forever. just think about it */
3578 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3579 if (!send_bitset[n]) {
3580 send_bitset[n] = true;
3586 /* none available, so resize and try again */
3588 send_bitset.resize (send_bitset.size() + 16, false);
3593 Session::next_return_id ()
3595 /* this doesn't really loop forever. just think about it */
3598 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3599 if (!return_bitset[n]) {
3600 return_bitset[n] = true;
3606 /* none available, so resize and try again */
3608 return_bitset.resize (return_bitset.size() + 16, false);
3613 Session::mark_send_id (uint32_t id)
3615 if (id >= send_bitset.size()) {
3616 send_bitset.resize (id+16, false);
3618 if (send_bitset[id]) {
3619 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3621 send_bitset[id] = true;
3625 Session::mark_return_id (uint32_t id)
3627 if (id >= return_bitset.size()) {
3628 return_bitset.resize (id+16, false);
3630 if (return_bitset[id]) {
3631 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3633 return_bitset[id] = true;
3637 Session::mark_insert_id (uint32_t id)
3639 if (id >= insert_bitset.size()) {
3640 insert_bitset.resize (id+16, false);
3642 if (insert_bitset[id]) {
3643 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3645 insert_bitset[id] = true;
3648 /* Named Selection management */
3650 boost::shared_ptr<NamedSelection>
3651 Session::named_selection_by_name (string name)
3653 Glib::Mutex::Lock lm (named_selection_lock);
3654 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3655 if ((*i)->name == name) {
3659 return boost::shared_ptr<NamedSelection>();
3663 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3666 Glib::Mutex::Lock lm (named_selection_lock);
3667 named_selections.insert (named_selections.begin(), named_selection);
3672 NamedSelectionAdded (); /* EMIT SIGNAL */
3676 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3678 bool removed = false;
3681 Glib::Mutex::Lock lm (named_selection_lock);
3683 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3685 if (i != named_selections.end()) {
3686 named_selections.erase (i);
3693 NamedSelectionRemoved (); /* EMIT SIGNAL */
3698 Session::reset_native_file_format ()
3700 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3702 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3703 (*i)->reset_write_sources (false);
3708 Session::route_name_unique (string n) const
3710 shared_ptr<RouteList> r = routes.reader ();
3712 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3713 if ((*i)->name() == n) {
3722 Session::route_name_internal (string n) const
3724 if (auditioner && auditioner->name() == n) {
3728 if (_click_io && _click_io->name() == n) {
3736 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3738 if (!force && howmany <= _npan_buffers) {
3742 if (_pan_automation_buffer) {
3744 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3745 delete [] _pan_automation_buffer[i];
3748 delete [] _pan_automation_buffer;
3751 _pan_automation_buffer = new pan_t*[howmany];
3753 for (uint32_t i = 0; i < howmany; ++i) {
3754 _pan_automation_buffer[i] = new pan_t[nframes];
3757 _npan_buffers = howmany;
3761 Session::freeze_all (InterThreadInfo& itt)
3763 shared_ptr<RouteList> r = routes.reader ();
3765 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3767 boost::shared_ptr<Track> t;
3769 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3770 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3780 boost::shared_ptr<Region>
3781 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3782 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3783 InterThreadInfo& itt, bool enable_processing)
3785 boost::shared_ptr<Region> result;
3786 boost::shared_ptr<Playlist> playlist;
3787 boost::shared_ptr<AudioFileSource> fsource;
3789 char buf[PATH_MAX+1];
3790 ChanCount nchans(track.audio_diskstream()->n_channels());
3792 nframes_t this_chunk;
3795 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3796 const string sound_dir = sdir.sound_path().to_string();
3797 nframes_t len = end - start;
3800 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3801 end, start) << endmsg;
3805 const nframes_t chunk_size = (256 * 1024)/4;
3807 // block all process callback handling
3809 block_processing ();
3811 /* call tree *MUST* hold route_lock */
3813 if ((playlist = track.diskstream()->playlist()) == 0) {
3817 /* external redirects will be a problem */
3819 if (track.has_external_redirects()) {
3823 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3825 for (x = 0; x < 99999; ++x) {
3826 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3827 if (access (buf, F_OK) != 0) {
3833 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3838 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3839 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3842 catch (failed_constructor& err) {
3843 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3847 srcs.push_back (fsource);
3850 /* XXX need to flush all redirects */
3855 /* create a set of reasonably-sized buffers */
3856 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3857 buffers.set_count(nchans);
3859 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3860 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3862 afs->prepare_for_peakfile_writes ();
3865 while (to_do && !itt.cancel) {
3867 this_chunk = min (to_do, chunk_size);
3869 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3874 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3875 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3878 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3884 start += this_chunk;
3885 to_do -= this_chunk;
3887 itt.progress = (float) (1.0 - ((double) to_do / len));
3896 xnow = localtime (&now);
3898 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3899 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3902 afs->update_header (position, *xnow, now);
3903 afs->flush_header ();
3907 /* construct a region to represent the bounced material */
3911 plist.add (Properties::start, 0);
3912 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3913 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3915 result = RegionFactory::create (srcs, plist);
3921 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3922 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3925 afs->mark_for_remove ();
3928 (*src)->drop_references ();
3932 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3933 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3936 afs->done_with_peakfile_writes ();
3940 unblock_processing ();
3946 Session::get_silent_buffers (ChanCount count)
3948 assert(_silent_buffers->available() >= count);
3949 _silent_buffers->set_count(count);
3951 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3952 for (size_t i= 0; i < count.get(*t); ++i) {
3953 _silent_buffers->get(*t, i).clear();
3957 return *_silent_buffers;
3961 Session::get_scratch_buffers (ChanCount count)
3963 if (count != ChanCount::ZERO) {
3964 assert(_scratch_buffers->available() >= count);
3965 _scratch_buffers->set_count(count);
3967 _scratch_buffers->set_count (_scratch_buffers->available());
3970 return *_scratch_buffers;
3974 Session::get_mix_buffers (ChanCount count)
3976 assert(_mix_buffers->available() >= count);
3977 _mix_buffers->set_count(count);
3978 return *_mix_buffers;
3982 Session::ntracks () const
3985 shared_ptr<RouteList> r = routes.reader ();
3987 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3988 if (boost::dynamic_pointer_cast<Track> (*i)) {
3997 Session::nbusses () const
4000 shared_ptr<RouteList> r = routes.reader ();
4002 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4003 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4012 Session::add_automation_list(AutomationList *al)
4014 automation_lists[al->id()] = al;
4018 Session::compute_initial_length ()
4020 return _engine.frame_rate() * 60 * 5;
4024 Session::sync_order_keys (std::string const & base)
4026 if (deletion_in_progress()) {
4030 if (!Config->get_sync_all_route_ordering()) {
4031 /* leave order keys as they are */
4035 boost::shared_ptr<RouteList> r = routes.reader ();
4037 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4038 (*i)->sync_order_keys (base);
4041 Route::SyncOrderKeys (base); // EMIT SIGNAL
4043 /* this might not do anything */
4045 set_remote_control_ids ();
4048 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4050 Session::have_rec_enabled_diskstream () const
4052 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4055 /** Update the state of our rec-enabled diskstreams flag */
4057 Session::update_have_rec_enabled_diskstream ()
4059 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4060 DiskstreamList::iterator i = dsl->begin ();
4061 while (i != dsl->end () && (*i)->record_enabled () == false) {
4065 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4067 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4069 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4070 RecordStateChanged (); /* EMIT SIGNAL */
4075 Session::listen_position_changed ()
4079 switch (Config->get_listen_position()) {
4080 case AfterFaderListen:
4084 case PreFaderListen:
4089 boost::shared_ptr<RouteList> r = routes.reader ();
4091 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4092 (*i)->put_control_outs_at (p);
4097 Session::solo_control_mode_changed ()
4099 /* cancel all solo or all listen when solo control mode changes */
4102 set_solo (get_routes(), false);
4103 } else if (listening()) {
4104 set_listen (get_routes(), false);
4109 Session::route_group_changed ()
4111 RouteGroupChanged (); /* EMIT SIGNAL */
4115 Session::get_available_sync_options () const
4117 vector<SyncSource> ret;
4119 ret.push_back (JACK);
4122 ret.push_back (MTC);
4125 if (midi_clock_port()) {
4126 ret.push_back (MIDIClock);
4132 boost::shared_ptr<RouteList>
4133 Session::get_routes_with_regions_at (nframes64_t const p) const
4135 shared_ptr<RouteList> r = routes.reader ();
4136 shared_ptr<RouteList> rl (new RouteList);
4138 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4139 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4144 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4149 boost::shared_ptr<Playlist> pl = ds->playlist ();
4154 if (pl->has_region_at (p)) {