2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include <glibmm/thread.h>
40 #include "pbd/boost_debug.h"
41 #include "pbd/pathscanner.h"
42 #include "pbd/stl_delete.h"
43 #include "pbd/basename.h"
44 #include "pbd/stacktrace.h"
45 #include "pbd/file_utils.h"
47 #include "ardour/amp.h"
48 #include "ardour/analyser.h"
49 #include "ardour/audio_buffer.h"
50 #include "ardour/audio_diskstream.h"
51 #include "ardour/audio_port.h"
52 #include "ardour/audio_track.h"
53 #include "ardour/audioengine.h"
54 #include "ardour/audiofilesource.h"
55 #include "ardour/audioplaylist.h"
56 #include "ardour/audioregion.h"
57 #include "ardour/auditioner.h"
58 #include "ardour/buffer_set.h"
59 #include "ardour/bundle.h"
60 #include "ardour/butler.h"
61 #include "ardour/click.h"
62 #include "ardour/configuration.h"
63 #include "ardour/crossfade.h"
64 #include "ardour/cycle_timer.h"
65 #include "ardour/data_type.h"
66 #include "ardour/debug.h"
67 #include "ardour/filename_extensions.h"
68 #include "ardour/internal_send.h"
69 #include "ardour/io_processor.h"
70 #include "ardour/midi_diskstream.h"
71 #include "ardour/midi_playlist.h"
72 #include "ardour/midi_region.h"
73 #include "ardour/midi_track.h"
74 #include "ardour/midi_ui.h"
75 #include "ardour/named_selection.h"
76 #include "ardour/playlist.h"
77 #include "ardour/plugin_insert.h"
78 #include "ardour/port_insert.h"
79 #include "ardour/processor.h"
80 #include "ardour/rc_configuration.h"
81 #include "ardour/recent_sessions.h"
82 #include "ardour/region_factory.h"
83 #include "ardour/return.h"
84 #include "ardour/route_group.h"
85 #include "ardour/send.h"
86 #include "ardour/session.h"
87 #include "ardour/session_directory.h"
88 #include "ardour/session_directory.h"
89 #include "ardour/session_metadata.h"
90 #include "ardour/session_playlists.h"
91 #include "ardour/slave.h"
92 #include "ardour/smf_source.h"
93 #include "ardour/source_factory.h"
94 #include "ardour/tape_file_matcher.h"
95 #include "ardour/tempo.h"
96 #include "ardour/utils.h"
101 using namespace ARDOUR;
103 using boost::shared_ptr;
104 using boost::weak_ptr;
106 bool Session::_disable_all_loaded_plugins = false;
108 sigc::signal<void,std::string> Session::Dialog;
109 sigc::signal<int> Session::AskAboutPendingState;
110 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
111 sigc::signal<void> Session::SendFeedback;
113 sigc::signal<void> Session::TimecodeOffsetChanged;
114 sigc::signal<void> Session::StartTimeChanged;
115 sigc::signal<void> Session::EndTimeChanged;
116 sigc::signal<void> Session::AutoBindingOn;
117 sigc::signal<void> Session::AutoBindingOff;
118 sigc::signal<void, std::string, std::string> Session::Exported;
120 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
121 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
123 Session::Session (AudioEngine &eng,
124 const string& fullpath,
125 const string& snapshot_name,
129 _target_transport_speed (0.0),
130 _requested_return_frame (-1),
131 _scratch_buffers(new BufferSet()),
132 _silent_buffers(new BufferSet()),
133 _mix_buffers(new BufferSet()),
135 _mmc_port (default_mmc_port),
136 _mtc_port (default_mtc_port),
137 _midi_port (default_midi_port),
138 _midi_clock_port (default_midi_clock_port),
139 _session_dir (new SessionDirectory(fullpath)),
141 _butler (new Butler (this)),
142 _post_transport_work (0),
143 _send_timecode_update (false),
144 diskstreams (new DiskstreamList),
145 routes (new RouteList),
146 _total_free_4k_blocks (0),
147 _bundles (new BundleList),
148 _bundle_xml_node (0),
151 click_emphasis_data (0),
153 _metadata (new SessionMetadata()),
154 _have_rec_enabled_diskstream (false)
157 playlists.reset (new SessionPlaylists);
161 interpolation.add_channel_to (0, 0);
163 if (!eng.connected()) {
164 throw failed_constructor();
167 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
169 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
170 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
172 first_stage_init (fullpath, snapshot_name);
174 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
177 if (create (new_session, mix_template, compute_initial_length())) {
179 throw failed_constructor ();
183 if (second_stage_init (new_session)) {
185 throw failed_constructor ();
188 store_recent_sessions(_name, _path);
190 bool was_dirty = dirty();
192 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
194 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
195 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
198 DirtyChanged (); /* EMIT SIGNAL */
202 Session::Session (AudioEngine &eng,
204 string snapshot_name,
205 AutoConnectOption input_ac,
206 AutoConnectOption output_ac,
207 uint32_t control_out_channels,
208 uint32_t master_out_channels,
209 uint32_t requested_physical_in,
210 uint32_t requested_physical_out,
211 nframes_t initial_length)
214 _target_transport_speed (0.0),
215 _requested_return_frame (-1),
216 _scratch_buffers(new BufferSet()),
217 _silent_buffers(new BufferSet()),
218 _mix_buffers(new BufferSet()),
220 _mmc_port (default_mmc_port),
221 _mtc_port (default_mtc_port),
222 _midi_port (default_midi_port),
223 _midi_clock_port (default_midi_clock_port),
224 _session_dir ( new SessionDirectory(fullpath)),
226 _butler (new Butler (this)),
227 _post_transport_work (0),
228 _send_timecode_update (false),
229 diskstreams (new DiskstreamList),
230 routes (new RouteList),
231 _total_free_4k_blocks (0),
232 _bundles (new BundleList),
233 _bundle_xml_node (0),
234 _click_io ((IO *) 0),
236 click_emphasis_data (0),
238 _metadata (new SessionMetadata()),
239 _have_rec_enabled_diskstream (false)
241 playlists.reset (new SessionPlaylists);
245 interpolation.add_channel_to (0, 0);
247 if (!eng.connected()) {
248 throw failed_constructor();
251 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
253 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
254 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
256 if (n_physical_inputs) {
257 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
260 if (n_physical_outputs) {
261 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
264 first_stage_init (fullpath, snapshot_name);
266 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
269 if (create (new_session, string(), initial_length)) {
271 throw failed_constructor ();
276 /* set up Master Out and Control Out if necessary */
281 if (master_out_channels) {
282 ChanCount count(DataType::AUDIO, master_out_channels);
283 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
284 r->input()->ensure_io (count, false, this);
285 r->output()->ensure_io (count, false, this);
286 r->set_remote_control_id (control_id);
290 /* prohibit auto-connect to master, because there isn't one */
291 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
294 if (control_out_channels) {
295 ChanCount count(DataType::AUDIO, control_out_channels);
296 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
297 r->input()->ensure_io (count, false, this);
298 r->output()->ensure_io (count, false, this);
299 r->set_remote_control_id (control_id++);
305 add_routes (rl, false);
310 if (no_auto_connect()) {
311 input_ac = AutoConnectOption (0);
312 output_ac = AutoConnectOption (0);
315 Config->set_input_auto_connect (input_ac);
316 Config->set_output_auto_connect (output_ac);
318 if (second_stage_init (new_session)) {
320 throw failed_constructor ();
323 store_recent_sessions (_name, _path);
325 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
327 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
338 vector<void*> debug_pointers;
340 /* if we got to here, leaving pending capture state around
344 remove_pending_capture_state ();
346 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
348 _engine.remove_session ();
350 GoingAway (); /* EMIT SIGNAL */
356 /* clear history so that no references to objects are held any more */
360 /* clear state tree so that no references to objects are held any more */
364 /* reset dynamic state version back to default */
366 Stateful::loading_state_version = 0;
368 _butler->terminate_thread ();
370 delete midi_control_ui;
372 if (click_data != default_click) {
373 delete [] click_data;
376 if (click_emphasis_data != default_click_emphasis) {
377 delete [] click_emphasis_data;
382 delete _scratch_buffers;
383 delete _silent_buffers;
386 /* clear out any pending dead wood from RCU managed objects */
389 diskstreams.flush ();
392 AudioDiskstream::free_working_buffers();
394 Route::SyncOrderKeys.clear();
396 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
397 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
398 NamedSelectionList::iterator tmp;
407 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
408 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
409 RegionList::iterator tmp;
414 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 (%2); pre-ref = %2\n", i->second->name(), i->second.get(), i->second.use_count()));
415 i->second->drop_references ();
416 DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count()));
422 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
424 /* reset these three references to special routes before we do the usual route delete thing */
427 _master_out.reset ();
428 _control_out.reset ();
431 RCUWriter<RouteList> writer (routes);
432 boost::shared_ptr<RouteList> r = writer.get_copy ();
433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
434 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
435 (*i)->drop_references ();
438 /* writer goes out of scope and updates master */
442 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
444 RCUWriter<DiskstreamList> dwriter (diskstreams);
445 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
446 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
447 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
448 (*i)->drop_references ();
452 diskstreams.flush ();
454 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
455 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
456 SourceMap::iterator tmp;
461 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
462 i->second->drop_references ();
470 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
471 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
475 Crossfade::set_buffer_size (0);
479 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
482 boost_debug_list_ptrs ();
484 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
488 Session::set_worst_io_latencies ()
490 _worst_output_latency = 0;
491 _worst_input_latency = 0;
493 if (!_engine.connected()) {
497 boost::shared_ptr<RouteList> r = routes.reader ();
499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
500 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
501 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
506 Session::when_engine_running ()
508 string first_physical_output;
510 BootMessage (_("Set block size and sample rate"));
512 set_block_size (_engine.frames_per_cycle());
513 set_frame_rate (_engine.frame_rate());
515 BootMessage (_("Using configuration"));
517 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
518 config.map_parameters (bind (mem_fun (*this, &Session::config_changed), true));
520 /* every time we reconnect, recompute worst case output latencies */
522 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
524 if (synced_to_jack()) {
525 _engine.transport_stop ();
528 if (config.get_jack_time_master()) {
529 _engine.transport_locate (_transport_frame);
537 _click_io.reset (new ClickIO (*this, "click"));
539 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
541 /* existing state for Click */
544 if (Stateful::loading_state_version < 3000) {
545 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
547 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
552 _clicking = Config->get_clicking ();
556 error << _("could not setup Click I/O") << endmsg;
563 /* default state for Click: dual-mono to first 2 physical outputs */
565 for (int physport = 0; physport < 2; ++physport) {
566 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
568 if (physical_output.length()) {
569 if (_click_io->add_port (physical_output, this)) {
570 // relax, even though its an error
575 if (_click_io->n_ports () > ChanCount::ZERO) {
576 _clicking = Config->get_clicking ();
581 catch (failed_constructor& err) {
582 error << _("cannot setup Click I/O") << endmsg;
585 BootMessage (_("Compute I/O Latencies"));
587 set_worst_io_latencies ();
590 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
593 BootMessage (_("Set up standard connections"));
595 /* Create a set of Bundle objects that map
596 to the physical I/O currently available. We create both
597 mono and stereo bundles, so that the common cases of mono
598 and stereo tracks get bundles to put in their mixer strip
599 in / out menus. There may be a nicer way of achieving that;
600 it doesn't really scale that well to higher channel counts
603 /* mono output bundles */
605 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
607 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
609 shared_ptr<Bundle> c (new Bundle (buf, true));
610 c->add_channel (_("mono"));
611 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
616 /* stereo output bundles */
618 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
619 if (np + 1 < n_physical_outputs) {
621 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
622 shared_ptr<Bundle> c (new Bundle (buf, true));
623 c->add_channel (_("L"));
624 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
625 c->add_channel (_("R"));
626 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
632 /* mono input bundles */
634 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
636 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
638 shared_ptr<Bundle> c (new Bundle (buf, false));
639 c->add_channel (_("mono"));
640 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
645 /* stereo input bundles */
647 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
648 if (np + 1 < n_physical_inputs) {
650 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
652 shared_ptr<Bundle> c (new Bundle (buf, false));
653 c->add_channel (_("L"));
654 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
655 c->add_channel (_("R"));
656 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
662 BootMessage (_("Setup signal flow and plugins"));
666 if (!no_auto_connect()) {
668 if (_master_out && Config->get_auto_connect_standard_busses()) {
670 /* if requested auto-connect the outputs to the first N physical ports.
673 uint32_t limit = _master_out->n_outputs().n_total();
675 for (uint32_t n = 0; n < limit; ++n) {
676 Port* p = _master_out->output()->nth (n);
677 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
679 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
680 if (_master_out->output()->connect (p, connect_to, this)) {
681 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
691 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
692 are undefined, at best.
695 /* control out listens to master bus (but ignores it
696 under some conditions)
699 uint32_t limit = _control_out->n_inputs().n_audio();
702 for (uint32_t n = 0; n < limit; ++n) {
703 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
704 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
707 string connect_to = o->name();
708 if (_control_out->input()->connect (p, connect_to, this)) {
709 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
717 /* if control out is not connected,
718 connect control out to physical outs, but use ones after the master if possible
721 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
723 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
725 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
728 _control_out->output()->connect_ports_to_bundle (b, this);
730 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
731 Config->get_monitor_bus_preferred_bundle())
737 /* XXX this logic is wrong for mixed port types */
739 uint32_t shift = _master_out->n_outputs().n_audio();
740 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
741 limit = _control_out->n_outputs().n_audio();
743 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
745 for (uint32_t n = 0; n < limit; ++n) {
747 Port* p = _control_out->output()->nth (n);
748 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
750 if (!connect_to.empty()) {
751 if (_control_out->output()->connect (p, connect_to, this)) {
752 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
763 /* catch up on send+insert cnts */
765 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
767 /* hook us up to the engine */
769 BootMessage (_("Connect to engine"));
771 _engine.set_session (this);
775 Session::hookup_io ()
777 /* stop graph reordering notifications from
778 causing resorts, etc.
781 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
786 /* we delay creating the auditioner till now because
787 it makes its own connections to ports.
788 the engine has to be running for this to work.
792 auditioner.reset (new Auditioner (*this));
795 catch (failed_constructor& err) {
796 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
800 /* load bundles, which we may have postponed earlier on */
801 if (_bundle_xml_node) {
802 load_bundles (*_bundle_xml_node);
803 delete _bundle_xml_node;
806 /* Tell all IO objects to connect themselves together */
808 IO::enable_connecting ();
810 /* Now reset all panners */
812 Delivery::reset_panners ();
814 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
818 boost::shared_ptr<RouteList> r = routes.reader ();
820 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
822 if ((*x)->is_control() || (*x)->is_master()) {
826 (*x)->listen_via (_control_out,
827 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
832 /* Anyone who cares about input state, wake up and do something */
834 IOConnectionsComplete (); /* EMIT SIGNAL */
836 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
838 /* now handle the whole enchilada as if it was one
844 /* update the full solo state, which can't be
845 correctly determined on a per-route basis, but
846 needs the global overview that only the session
850 update_route_solo_state ();
854 Session::playlist_length_changed ()
856 /* we can't just increase end_location->end() if pl->get_maximum_extent()
857 if larger. if the playlist used to be the longest playlist,
858 and its now shorter, we have to decrease end_location->end(). hence,
859 we have to iterate over all diskstreams and check the
860 playlists currently in use.
866 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
868 boost::shared_ptr<Diskstream> dstream = wp.lock ();
873 boost::shared_ptr<Playlist> playlist;
875 if ((playlist = dstream->playlist()) != 0) {
876 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
879 /* see comment in playlist_length_changed () */
884 Session::record_enabling_legal () const
886 /* this used to be in here, but survey says.... we don't need to restrict it */
887 // if (record_status() == Recording) {
891 if (Config->get_all_safe()) {
898 Session::reset_input_monitor_state ()
900 if (transport_rolling()) {
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 = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
907 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
911 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
913 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
914 if ((*i)->record_enabled ()) {
915 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
916 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
923 Session::auto_punch_start_changed (Location* location)
925 replace_event (SessionEvent::PunchIn, location->start());
927 if (get_record_enabled() && config.get_punch_in()) {
928 /* capture start has been changed, so save new pending state */
929 save_state ("", true);
934 Session::auto_punch_end_changed (Location* location)
936 nframes_t when_to_stop = location->end();
937 // when_to_stop += _worst_output_latency + _worst_input_latency;
938 replace_event (SessionEvent::PunchOut, when_to_stop);
942 Session::auto_punch_changed (Location* location)
944 nframes_t when_to_stop = location->end();
946 replace_event (SessionEvent::PunchIn, location->start());
947 //when_to_stop += _worst_output_latency + _worst_input_latency;
948 replace_event (SessionEvent::PunchOut, when_to_stop);
952 Session::auto_loop_changed (Location* location)
954 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
956 if (transport_rolling() && play_loop) {
959 // if (_transport_frame > location->end()) {
961 if (_transport_frame < location->start() || _transport_frame > location->end()) {
962 // relocate to beginning of loop
963 clear_events (SessionEvent::LocateRoll);
965 request_locate (location->start(), true);
968 else if (Config->get_seamless_loop() && !loop_changing) {
970 // schedule a locate-roll to refill the diskstreams at the
972 loop_changing = true;
974 if (location->end() > last_loopend) {
975 clear_events (SessionEvent::LocateRoll);
976 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
983 last_loopend = location->end();
987 Session::set_auto_punch_location (Location* location)
991 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
992 auto_punch_start_changed_connection.disconnect();
993 auto_punch_end_changed_connection.disconnect();
994 auto_punch_changed_connection.disconnect();
995 existing->set_auto_punch (false, this);
996 remove_event (existing->start(), SessionEvent::PunchIn);
997 clear_events (SessionEvent::PunchOut);
998 auto_punch_location_changed (0);
1003 if (location == 0) {
1007 if (location->end() <= location->start()) {
1008 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1012 auto_punch_start_changed_connection.disconnect();
1013 auto_punch_end_changed_connection.disconnect();
1014 auto_punch_changed_connection.disconnect();
1016 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1017 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1018 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1020 location->set_auto_punch (true, this);
1023 auto_punch_changed (location);
1025 auto_punch_location_changed (location);
1029 Session::set_auto_loop_location (Location* location)
1033 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1034 auto_loop_start_changed_connection.disconnect();
1035 auto_loop_end_changed_connection.disconnect();
1036 auto_loop_changed_connection.disconnect();
1037 existing->set_auto_loop (false, this);
1038 remove_event (existing->end(), SessionEvent::AutoLoop);
1039 auto_loop_location_changed (0);
1044 if (location == 0) {
1048 if (location->end() <= location->start()) {
1049 error << _("Session: you can't use a mark for auto loop") << endmsg;
1053 last_loopend = location->end();
1055 auto_loop_start_changed_connection.disconnect();
1056 auto_loop_end_changed_connection.disconnect();
1057 auto_loop_changed_connection.disconnect();
1059 auto_loop_start_changed_connection = location->start_changed.connect (
1060 mem_fun (this, &Session::auto_loop_changed));
1061 auto_loop_end_changed_connection = location->end_changed.connect (
1062 mem_fun (this, &Session::auto_loop_changed));
1063 auto_loop_changed_connection = location->changed.connect (
1064 mem_fun (this, &Session::auto_loop_changed));
1066 location->set_auto_loop (true, this);
1068 /* take care of our stuff first */
1070 auto_loop_changed (location);
1072 /* now tell everyone else */
1074 auto_loop_location_changed (location);
1078 Session::locations_added (Location *)
1084 Session::locations_changed ()
1086 _locations.apply (*this, &Session::handle_locations_changed);
1090 Session::handle_locations_changed (Locations::LocationList& locations)
1092 Locations::LocationList::iterator i;
1094 bool set_loop = false;
1095 bool set_punch = false;
1097 for (i = locations.begin(); i != locations.end(); ++i) {
1101 if (location->is_auto_punch()) {
1102 set_auto_punch_location (location);
1105 if (location->is_auto_loop()) {
1106 set_auto_loop_location (location);
1110 if (location->is_start()) {
1111 start_location = location;
1113 if (location->is_end()) {
1114 end_location = location;
1119 set_auto_loop_location (0);
1122 set_auto_punch_location (0);
1129 Session::enable_record ()
1131 /* XXX really atomic compare+swap here */
1132 if (g_atomic_int_get (&_record_status) != Recording) {
1133 g_atomic_int_set (&_record_status, Recording);
1134 _last_record_location = _transport_frame;
1135 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1137 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1138 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1139 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1140 if ((*i)->record_enabled ()) {
1141 (*i)->monitor_input (true);
1146 RecordStateChanged ();
1151 Session::disable_record (bool rt_context, bool force)
1155 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1157 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1158 g_atomic_int_set (&_record_status, Disabled);
1160 if (rs == Recording) {
1161 g_atomic_int_set (&_record_status, Enabled);
1165 // FIXME: timestamp correct? [DR]
1166 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1167 // does this /need/ to be sent in all cases?
1169 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1172 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1173 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1175 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1176 if ((*i)->record_enabled ()) {
1177 (*i)->monitor_input (false);
1182 RecordStateChanged (); /* emit signal */
1185 remove_pending_capture_state ();
1191 Session::step_back_from_record ()
1193 /* XXX really atomic compare+swap here */
1194 if (g_atomic_int_get (&_record_status) == Recording) {
1195 g_atomic_int_set (&_record_status, Enabled);
1197 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1198 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1200 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1201 if ((*i)->record_enabled ()) {
1202 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1203 (*i)->monitor_input (false);
1211 Session::maybe_enable_record ()
1213 g_atomic_int_set (&_record_status, Enabled);
1215 /* this function is currently called from somewhere other than an RT thread.
1216 this save_state() call therefore doesn't impact anything.
1219 save_state ("", true);
1221 if (_transport_speed) {
1222 if (!config.get_punch_in()) {
1226 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1227 RecordStateChanged (); /* EMIT SIGNAL */
1234 Session::audible_frame () const
1240 /* the first of these two possible settings for "offset"
1241 mean that the audible frame is stationary until
1242 audio emerges from the latency compensation
1245 the second means that the audible frame is stationary
1246 until audio would emerge from a physical port
1247 in the absence of any plugin latency compensation
1250 offset = _worst_output_latency;
1252 if (offset > current_block_size) {
1253 offset -= current_block_size;
1255 /* XXX is this correct? if we have no external
1256 physical connections and everything is internal
1257 then surely this is zero? still, how
1258 likely is that anyway?
1260 offset = current_block_size;
1263 if (synced_to_jack()) {
1264 tf = _engine.transport_frame();
1266 tf = _transport_frame;
1271 if (!non_realtime_work_pending()) {
1275 /* check to see if we have passed the first guaranteed
1276 audible frame past our last start position. if not,
1277 return that last start point because in terms
1278 of audible frames, we have not moved yet.
1281 if (_transport_speed > 0.0f) {
1283 if (!play_loop || !have_looped) {
1284 if (tf < _last_roll_location + offset) {
1285 return _last_roll_location;
1293 } else if (_transport_speed < 0.0f) {
1295 /* XXX wot? no backward looping? */
1297 if (tf > _last_roll_location - offset) {
1298 return _last_roll_location;
1310 Session::set_frame_rate (nframes_t frames_per_second)
1312 /** \fn void Session::set_frame_size(nframes_t)
1313 the AudioEngine object that calls this guarantees
1314 that it will not be called while we are also in
1315 ::process(). Its fine to do things that block
1319 _base_frame_rate = frames_per_second;
1323 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1327 // XXX we need some equivalent to this, somehow
1328 // SndFileSource::setup_standard_crossfades (frames_per_second);
1332 /* XXX need to reset/reinstantiate all LADSPA plugins */
1336 Session::set_block_size (nframes_t nframes)
1338 /* the AudioEngine guarantees
1339 that it will not be called while we are also in
1340 ::process(). It is therefore fine to do things that block
1345 current_block_size = nframes;
1347 ensure_buffers(_scratch_buffers->available());
1349 delete [] _gain_automation_buffer;
1350 _gain_automation_buffer = new gain_t[nframes];
1352 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1354 boost::shared_ptr<RouteList> r = routes.reader ();
1356 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1357 (*i)->set_block_size (nframes);
1360 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1361 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1362 (*i)->set_block_size (nframes);
1365 set_worst_io_latencies ();
1370 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1373 nframes_t fade_frames;
1375 /* Don't allow fade of less 1 frame */
1377 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1384 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1388 default_fade_msecs = fade_msecs;
1389 default_fade_steepness = steepness;
1392 // jlc, WTF is this!
1393 Glib::RWLock::ReaderLock lm (route_lock);
1394 AudioRegion::set_default_fade (steepness, fade_frames);
1399 /* XXX have to do this at some point */
1400 /* foreach region using default fade, reset, then
1401 refill_all_diskstream_buffers ();
1406 struct RouteSorter {
1407 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1408 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1410 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1413 if (r1->fed_by.empty()) {
1414 if (r2->fed_by.empty()) {
1415 /* no ardour-based connections inbound to either route. just use signal order */
1416 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1418 /* r2 has connections, r1 does not; run r1 early */
1422 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1429 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1431 shared_ptr<Route> r2;
1433 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1434 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1438 /* make a copy of the existing list of routes that feed r1 */
1440 set<weak_ptr<Route> > existing = r1->fed_by;
1442 /* for each route that feeds r1, recurse, marking it as feeding
1446 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1447 if (!(r2 = (*i).lock ())) {
1448 /* (*i) went away, ignore it */
1452 /* r2 is a route that feeds r1 which somehow feeds base. mark
1453 base as being fed by r2
1456 rbase->fed_by.insert (r2);
1460 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1464 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1468 /* now recurse, so that we can mark base as being fed by
1469 all routes that feed r2
1472 trace_terminal (r2, rbase);
1479 Session::resort_routes ()
1481 /* don't do anything here with signals emitted
1482 by Routes while we are being destroyed.
1485 if (_state_of_the_state & Deletion) {
1492 RCUWriter<RouteList> writer (routes);
1493 shared_ptr<RouteList> r = writer.get_copy ();
1494 resort_routes_using (r);
1495 /* writer goes out of scope and forces update */
1500 Session::resort_routes_using (shared_ptr<RouteList> r)
1502 RouteList::iterator i, j;
1504 for (i = r->begin(); i != r->end(); ++i) {
1506 (*i)->fed_by.clear ();
1508 for (j = r->begin(); j != r->end(); ++j) {
1510 /* although routes can feed themselves, it will
1511 cause an endless recursive descent if we
1512 detect it. so don't bother checking for
1520 if ((*j)->feeds (*i)) {
1521 (*i)->fed_by.insert (*j);
1526 for (i = r->begin(); i != r->end(); ++i) {
1527 trace_terminal (*i, *i);
1534 cerr << "finished route resort\n";
1536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1537 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1544 list<boost::shared_ptr<MidiTrack> >
1545 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1547 char track_name[32];
1548 uint32_t track_id = 0;
1551 RouteList new_routes;
1552 list<boost::shared_ptr<MidiTrack> > ret;
1553 //uint32_t control_id;
1555 // FIXME: need physical I/O and autoconnect stuff for MIDI
1557 /* count existing midi tracks */
1560 shared_ptr<RouteList> r = routes.reader ();
1562 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1563 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1564 if (!(*i)->is_hidden()) {
1566 //channels_used += (*i)->n_inputs().n_midi();
1572 vector<string> physinputs;
1573 vector<string> physoutputs;
1575 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1576 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1578 // control_id = ntracks() + nbusses();
1582 /* check for duplicate route names, since we might have pre-existing
1583 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1584 save, close,restart,add new route - first named route is now
1592 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1594 if (route_by_name (track_name) == 0) {
1598 } while (track_id < (UINT_MAX-1));
1600 shared_ptr<MidiTrack> track;
1603 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1605 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1606 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1611 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1612 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1618 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1622 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1623 port = physinputs[(channels_used+x)%nphysical_in];
1626 if (port.length() && track->connect_input (track->input (x), port, this)) {
1632 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1636 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1637 port = physoutputs[(channels_used+x)%nphysical_out];
1638 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1640 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1644 if (port.length() && track->connect_output (track->output (x), port, this)) {
1649 channels_used += track->n_inputs ().n_midi();
1653 track->midi_diskstream()->non_realtime_input_change();
1655 route_group->add (track);
1658 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1659 //track->set_remote_control_id (control_id);
1661 new_routes.push_back (track);
1662 ret.push_back (track);
1665 catch (failed_constructor &err) {
1666 error << _("Session: could not create new midi track.") << endmsg;
1669 /* we need to get rid of this, since the track failed to be created */
1670 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1673 RCUWriter<DiskstreamList> writer (diskstreams);
1674 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1675 ds->remove (track->midi_diskstream());
1682 catch (AudioEngine::PortRegistrationFailure& pfe) {
1684 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1687 /* we need to get rid of this, since the track failed to be created */
1688 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1691 RCUWriter<DiskstreamList> writer (diskstreams);
1692 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1693 ds->remove (track->midi_diskstream());
1704 if (!new_routes.empty()) {
1705 add_routes (new_routes, false);
1706 save_state (_current_snapshot_name);
1712 list<boost::shared_ptr<AudioTrack> >
1713 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1715 char track_name[32];
1716 uint32_t track_id = 0;
1718 uint32_t channels_used = 0;
1720 RouteList new_routes;
1721 list<boost::shared_ptr<AudioTrack> > ret;
1722 uint32_t control_id;
1724 /* count existing audio tracks */
1727 shared_ptr<RouteList> r = routes.reader ();
1729 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1730 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1731 if (!(*i)->is_hidden()) {
1733 channels_used += (*i)->n_inputs().n_audio();
1739 vector<string> physinputs;
1740 vector<string> physoutputs;
1742 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1743 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1745 control_id = ntracks() + nbusses() + 1;
1749 /* check for duplicate route names, since we might have pre-existing
1750 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1751 save, close,restart,add new route - first named route is now
1759 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1761 if (route_by_name (track_name) == 0) {
1765 } while (track_id < (UINT_MAX-1));
1767 shared_ptr<AudioTrack> track;
1770 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1771 // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1772 track = boost::shared_ptr<AudioTrack>(at);
1774 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1775 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1776 input_channels, output_channels)
1781 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1782 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1788 if (!physinputs.empty()) {
1789 uint32_t nphysical_in = physinputs.size();
1791 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1795 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1796 port = physinputs[(channels_used+x)%nphysical_in];
1799 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1805 if (!physoutputs.empty()) {
1806 uint32_t nphysical_out = physoutputs.size();
1808 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1811 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1812 port = physoutputs[(channels_used+x)%nphysical_out];
1813 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1814 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1815 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1819 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1825 channels_used += track->n_inputs ().n_audio();
1828 route_group->add (track);
1831 track->audio_diskstream()->non_realtime_input_change();
1833 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1834 track->set_remote_control_id (control_id);
1837 new_routes.push_back (track);
1838 ret.push_back (track);
1841 catch (failed_constructor &err) {
1842 error << _("Session: could not create new audio track.") << endmsg;
1845 /* we need to get rid of this, since the track failed to be created */
1846 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1849 RCUWriter<DiskstreamList> writer (diskstreams);
1850 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1851 ds->remove (track->audio_diskstream());
1858 catch (AudioEngine::PortRegistrationFailure& pfe) {
1860 error << pfe.what() << endmsg;
1863 /* we need to get rid of this, since the track failed to be created */
1864 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1867 RCUWriter<DiskstreamList> writer (diskstreams);
1868 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1869 ds->remove (track->audio_diskstream());
1880 if (!new_routes.empty()) {
1881 add_routes (new_routes, true);
1888 Session::set_remote_control_ids ()
1890 RemoteModel m = Config->get_remote_model();
1892 shared_ptr<RouteList> r = routes.reader ();
1894 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1895 if ( MixerOrdered == m) {
1896 long order = (*i)->order_key(N_("signal"));
1897 (*i)->set_remote_control_id( order+1 );
1898 } else if ( EditorOrdered == m) {
1899 long order = (*i)->order_key(N_("editor"));
1900 (*i)->set_remote_control_id( order+1 );
1901 } else if ( UserOrdered == m) {
1902 //do nothing ... only changes to remote id's are initiated by user
1909 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1912 uint32_t bus_id = 1;
1914 uint32_t channels_used = 0;
1917 uint32_t control_id;
1919 /* count existing audio busses */
1922 shared_ptr<RouteList> r = routes.reader ();
1924 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1925 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1927 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1930 channels_used += (*i)->n_inputs().n_audio();
1936 vector<string> physinputs;
1937 vector<string> physoutputs;
1939 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1940 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1942 n_physical_audio_outputs = physoutputs.size();
1943 n_physical_audio_inputs = physinputs.size();
1945 control_id = ntracks() + nbusses() + 1;
1950 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1954 if (route_by_name (bus_name) == 0) {
1958 } while (bus_id < (UINT_MAX-1));
1961 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1963 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1964 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1965 input_channels, output_channels)
1971 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1972 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1973 input_channels, output_channels)
1978 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1981 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1982 port = physinputs[((n+x)%n_physical_audio_inputs)];
1985 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1990 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1993 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1994 port = physoutputs[((n+x)%n_physical_outputs)];
1995 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1997 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
2001 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
2006 channels_used += bus->n_inputs ().n_audio();
2009 route_group->add (bus);
2011 bus->set_remote_control_id (control_id);
2015 bus->add_internal_return ();
2018 ret.push_back (bus);
2022 catch (failed_constructor &err) {
2023 error << _("Session: could not create new audio route.") << endmsg;
2027 catch (AudioEngine::PortRegistrationFailure& pfe) {
2028 error << pfe.what() << endmsg;
2038 add_routes (ret, true);
2046 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2050 uint32_t control_id;
2052 uint32_t number = 1;
2054 if (!tree.read (template_path.c_str())) {
2058 XMLNode* node = tree.root();
2060 control_id = ntracks() + nbusses() + 1;
2064 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2066 std::string node_name = IO::name_from_state (*node_copy.children().front());
2068 /* generate a new name by adding a number to the end of the template name */
2071 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2075 if (route_by_name (name) == 0) {
2079 } while (number < UINT_MAX);
2081 if (number == UINT_MAX) {
2082 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2086 IO::set_name_in_state (*node_copy.children().front(), name);
2088 Track::zero_diskstream_id_in_xml (node_copy);
2091 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2094 error << _("Session: cannot create track/bus from template description") << endmsg;
2098 if (boost::dynamic_pointer_cast<Track>(route)) {
2099 /* force input/output change signals so that the new diskstream
2100 picks up the configuration of the route. During session
2101 loading this normally happens in a different way.
2103 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2104 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2107 route->set_remote_control_id (control_id);
2110 ret.push_back (route);
2113 catch (failed_constructor &err) {
2114 error << _("Session: could not create new route from template") << endmsg;
2118 catch (AudioEngine::PortRegistrationFailure& pfe) {
2119 error << pfe.what() << endmsg;
2128 add_routes (ret, true);
2135 Session::add_routes (RouteList& new_routes, bool save)
2138 RCUWriter<RouteList> writer (routes);
2139 shared_ptr<RouteList> r = writer.get_copy ();
2140 r->insert (r->end(), new_routes.begin(), new_routes.end());
2143 /* if there is no control out and we're not in the middle of loading,
2144 resort the graph here. if there is a control out, we will resort
2145 toward the end of this method. if we are in the middle of loading,
2146 we will resort when done.
2149 if (!_control_out && IO::connecting_legal) {
2150 resort_routes_using (r);
2154 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2156 boost::weak_ptr<Route> wpr (*x);
2158 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2159 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2160 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2161 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2162 (*x)->processors_changed.connect (mem_fun (*this, &Session::route_processors_changed));
2163 (*x)->route_group_changed.connect (mem_fun (*this, &Session::route_group_changed));
2165 if ((*x)->is_master()) {
2169 if ((*x)->is_control()) {
2170 _control_out = (*x);
2174 if (_control_out && IO::connecting_legal) {
2176 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2177 if ((*x)->is_control() || (*x)->is_master()) {
2180 (*x)->listen_via (_control_out,
2181 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2191 save_state (_current_snapshot_name);
2194 RouteAdded (new_routes); /* EMIT SIGNAL */
2198 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2200 boost::shared_ptr<RouteList> r = routes.reader ();
2201 boost::shared_ptr<Send> s;
2205 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2206 if (boost::dynamic_pointer_cast<Track>(*i)) {
2207 if ((s = (*i)->internal_send_for (dest)) != 0) {
2208 s->amp()->gain_control()->set_value (0.0);
2215 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2217 boost::shared_ptr<RouteList> r = routes.reader ();
2218 boost::shared_ptr<Send> s;
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2223 if (boost::dynamic_pointer_cast<Track>(*i)) {
2224 if ((s = (*i)->internal_send_for (dest)) != 0) {
2225 s->amp()->gain_control()->set_value (1.0);
2232 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2234 boost::shared_ptr<RouteList> r = routes.reader ();
2235 boost::shared_ptr<Send> s;
2239 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2240 if (boost::dynamic_pointer_cast<Track>(*i)) {
2241 if ((s = (*i)->internal_send_for (dest)) != 0) {
2242 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2249 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2251 boost::shared_ptr<RouteList> r = routes.reader ();
2252 boost::shared_ptr<RouteList> t (new RouteList);
2254 /* only send tracks */
2256 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2257 if (boost::dynamic_pointer_cast<Track>(*i)) {
2262 add_internal_sends (dest, p, t);
2266 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2268 if (dest->is_control() || dest->is_master()) {
2272 if (!dest->internal_return()) {
2273 dest->add_internal_return();
2276 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2278 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2282 (*i)->listen_via (dest, p, true, true);
2289 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2291 /* need to do this in case we're rolling at the time, to prevent false underruns */
2292 dstream->do_refill_with_alloc ();
2294 dstream->set_block_size (current_block_size);
2297 RCUWriter<DiskstreamList> writer (diskstreams);
2298 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2299 ds->push_back (dstream);
2300 /* writer goes out of scope, copies ds back to main */
2303 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2304 /* this will connect to future changes, and check the current length */
2305 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2307 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2309 dstream->prepare ();
2314 Session::remove_route (shared_ptr<Route> route)
2317 RCUWriter<RouteList> writer (routes);
2318 shared_ptr<RouteList> rs = writer.get_copy ();
2322 /* deleting the master out seems like a dumb
2323 idea, but its more of a UI policy issue
2327 if (route == _master_out) {
2328 _master_out = shared_ptr<Route> ();
2331 if (route == _control_out) {
2333 /* cancel control outs for all routes */
2335 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2336 (*r)->drop_listen (_control_out);
2339 _control_out.reset ();
2342 update_route_solo_state ();
2344 /* writer goes out of scope, forces route list update */
2347 boost::shared_ptr<Track> t;
2348 boost::shared_ptr<Diskstream> ds;
2350 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2351 ds = t->diskstream();
2357 RCUWriter<DiskstreamList> dsl (diskstreams);
2358 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2363 find_current_end ();
2365 // We need to disconnect the routes inputs and outputs
2367 route->input()->disconnect (0);
2368 route->output()->disconnect (0);
2370 /* if the route had internal sends sending to it, remove them */
2371 if (route->internal_return()) {
2373 boost::shared_ptr<RouteList> r = routes.reader ();
2374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2375 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2377 (*i)->remove_processor (s);
2382 update_latency_compensation (false, false);
2385 /* get rid of it from the dead wood collection in the route list manager */
2387 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2391 /* try to cause everyone to drop their references */
2393 route->drop_references ();
2395 sync_order_keys (N_("session"));
2397 /* save the new state of the world */
2399 if (save_state (_current_snapshot_name)) {
2400 save_history (_current_snapshot_name);
2405 Session::route_mute_changed (void* /*src*/)
2411 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2413 boost::shared_ptr<Route> route = wpr.lock();
2415 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2419 if (route->listening()) {
2421 } else if (_listen_cnt > 0) {
2427 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2429 if (solo_update_disabled) {
2434 boost::shared_ptr<Route> route = wpr.lock ();
2437 /* should not happen */
2438 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2442 shared_ptr<RouteList> r = routes.reader ();
2445 if (route->self_soloed()) {
2451 /* now mod the solo level of all other routes except master & control outs
2452 so that they will be silent if appropriate.
2455 solo_update_disabled = true;
2457 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2458 bool via_sends_only;
2461 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2463 } else if ((*i)->feeds (route, &via_sends_only)) {
2464 if (!via_sends_only) {
2465 (*i)->mod_solo_by_others (delta);
2470 /* make sure master is never muted by solo */
2472 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2473 _master_out->mod_solo_by_others (1);
2476 /* ditto for control outs make sure master is never muted by solo */
2478 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2479 _control_out->mod_solo_by_others (1);
2482 solo_update_disabled = false;
2483 update_route_solo_state (r);
2484 SoloChanged (); /* EMIT SIGNAL */
2489 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2491 /* now figure out if anything that matters is soloed */
2493 bool something_soloed = false;
2496 r = routes.reader();
2499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2500 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2501 something_soloed = true;
2506 if (something_soloed != _non_soloed_outs_muted) {
2507 _non_soloed_outs_muted = something_soloed;
2508 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2512 boost::shared_ptr<RouteList>
2513 Session::get_routes_with_internal_returns() const
2515 shared_ptr<RouteList> r = routes.reader ();
2516 boost::shared_ptr<RouteList> rl (new RouteList);
2518 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2519 if ((*i)->internal_return ()) {
2527 Session::route_by_name (string name)
2529 shared_ptr<RouteList> r = routes.reader ();
2531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2532 if ((*i)->name() == name) {
2537 return shared_ptr<Route> ((Route*) 0);
2541 Session::route_by_id (PBD::ID id)
2543 shared_ptr<RouteList> r = routes.reader ();
2545 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2546 if ((*i)->id() == id) {
2551 return shared_ptr<Route> ((Route*) 0);
2555 Session::route_by_remote_id (uint32_t id)
2557 shared_ptr<RouteList> r = routes.reader ();
2559 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2560 if ((*i)->remote_control_id() == id) {
2565 return shared_ptr<Route> ((Route*) 0);
2569 Session::find_current_end ()
2571 if (_state_of_the_state & Loading) {
2575 nframes_t max = get_maximum_extent ();
2577 if (max > end_location->end()) {
2578 end_location->set_end (max);
2580 DurationChanged(); /* EMIT SIGNAL */
2585 Session::get_maximum_extent () const
2590 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2592 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2593 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2595 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2596 if ((me = pl->get_maximum_extent()) > max) {
2604 boost::shared_ptr<Diskstream>
2605 Session::diskstream_by_name (string name)
2607 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2609 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2610 if ((*i)->name() == name) {
2615 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2618 boost::shared_ptr<Diskstream>
2619 Session::diskstream_by_id (const PBD::ID& id)
2621 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2623 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2624 if ((*i)->id() == id) {
2629 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2632 /* Region management */
2635 Session::new_region_name (string old)
2637 string::size_type last_period;
2639 string::size_type len = old.length() + 64;
2642 if ((last_period = old.find_last_of ('.')) == string::npos) {
2644 /* no period present - add one explicitly */
2647 last_period = old.length() - 1;
2652 number = atoi (old.substr (last_period+1).c_str());
2656 while (number < (UINT_MAX-1)) {
2658 RegionList::const_iterator i;
2663 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2666 for (i = regions.begin(); i != regions.end(); ++i) {
2667 if (i->second->name() == sbuf) {
2672 if (i == regions.end()) {
2677 if (number != (UINT_MAX-1)) {
2681 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2686 Session::region_name (string& result, string base, bool newlevel)
2691 if (base.find("/") != string::npos) {
2692 base = base.substr(base.find_last_of("/") + 1);
2697 Glib::Mutex::Lock lm (region_lock);
2699 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2708 string::size_type pos;
2710 pos = base.find_last_of ('.');
2712 /* pos may be npos, but then we just use entire base */
2714 subbase = base.substr (0, pos);
2719 Glib::Mutex::Lock lm (region_lock);
2721 map<string,uint32_t>::iterator x;
2725 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2727 region_name_map[subbase] = 1;
2730 snprintf (buf, sizeof (buf), ".%d", x->second);
2741 Session::add_region (boost::shared_ptr<Region> region)
2743 vector<boost::shared_ptr<Region> > v;
2744 v.push_back (region);
2749 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2754 Glib::Mutex::Lock lm (region_lock);
2756 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2758 boost::shared_ptr<Region> region = *ii;
2762 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2766 RegionList::iterator x;
2768 for (x = regions.begin(); x != regions.end(); ++x) {
2770 if (region->region_list_equivalent (x->second)) {
2775 if (x == regions.end()) {
2777 pair<RegionList::key_type,RegionList::mapped_type> entry;
2779 entry.first = region->id();
2780 entry.second = region;
2782 pair<RegionList::iterator,bool> x = regions.insert (entry);
2794 /* mark dirty because something has changed even if we didn't
2795 add the region to the region list.
2802 vector<boost::weak_ptr<Region> > v;
2803 boost::shared_ptr<Region> first_r;
2805 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2807 boost::shared_ptr<Region> region = *ii;
2811 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2814 v.push_back (region);
2821 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2822 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2824 update_region_name_map (region);
2828 RegionsAdded (v); /* EMIT SIGNAL */
2834 Session::update_region_name_map (boost::shared_ptr<Region> region)
2836 string::size_type last_period = region->name().find_last_of ('.');
2838 if (last_period != string::npos && last_period < region->name().length() - 1) {
2840 string base = region->name().substr (0, last_period);
2841 string number = region->name().substr (last_period+1);
2842 map<string,uint32_t>::iterator x;
2844 /* note that if there is no number, we get zero from atoi,
2848 region_name_map[base] = atoi (number);
2853 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2855 boost::shared_ptr<Region> region (weak_region.lock ());
2861 if (what_changed & Region::HiddenChanged) {
2862 /* relay hidden changes */
2863 RegionHiddenChange (region);
2866 if (what_changed & NameChanged) {
2867 update_region_name_map (region);
2872 Session::remove_region (boost::weak_ptr<Region> weak_region)
2874 RegionList::iterator i;
2875 boost::shared_ptr<Region> region (weak_region.lock ());
2881 bool removed = false;
2884 Glib::Mutex::Lock lm (region_lock);
2886 if ((i = regions.find (region->id())) != regions.end()) {
2892 /* mark dirty because something has changed even if we didn't
2893 remove the region from the region list.
2899 RegionRemoved(region); /* EMIT SIGNAL */
2903 boost::shared_ptr<Region>
2904 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2906 RegionList::iterator i;
2907 boost::shared_ptr<Region> region;
2909 Glib::Mutex::Lock lm (region_lock);
2911 for (i = regions.begin(); i != regions.end(); ++i) {
2915 if (region->whole_file()) {
2917 if (child->source_equivalent (region)) {
2923 return boost::shared_ptr<Region> ();
2927 Session::destroy_region (boost::shared_ptr<Region> region)
2929 vector<boost::shared_ptr<Source> > srcs;
2932 if (region->playlist()) {
2933 region->playlist()->destroy_region (region);
2936 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2937 srcs.push_back (region->source (n));
2941 region->drop_references ();
2943 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2945 (*i)->mark_for_remove ();
2946 (*i)->drop_references ();
2948 cerr << "source was not used by any playlist\n";
2955 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2957 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2958 destroy_region (*i);
2964 Session::remove_last_capture ()
2966 list<boost::shared_ptr<Region> > r;
2968 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2970 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2971 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2974 r.insert (r.end(), l.begin(), l.end());
2979 destroy_regions (r);
2981 save_state (_current_snapshot_name);
2987 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2993 /* Source Management */
2996 Session::add_source (boost::shared_ptr<Source> source)
2998 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2999 pair<SourceMap::iterator,bool> result;
3001 entry.first = source->id();
3002 entry.second = source;
3005 Glib::Mutex::Lock lm (source_lock);
3006 result = sources.insert (entry);
3009 if (result.second) {
3010 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3014 boost::shared_ptr<AudioFileSource> afs;
3016 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3017 if (Config->get_auto_analyse_audio()) {
3018 Analyser::queue_source_for_analysis (source, false);
3024 Session::remove_source (boost::weak_ptr<Source> src)
3026 SourceMap::iterator i;
3027 boost::shared_ptr<Source> source = src.lock();
3034 Glib::Mutex::Lock lm (source_lock);
3036 if ((i = sources.find (source->id())) != sources.end()) {
3041 if (!_state_of_the_state & InCleanup) {
3043 /* save state so we don't end up with a session file
3044 referring to non-existent sources.
3047 save_state (_current_snapshot_name);
3051 boost::shared_ptr<Source>
3052 Session::source_by_id (const PBD::ID& id)
3054 Glib::Mutex::Lock lm (source_lock);
3055 SourceMap::iterator i;
3056 boost::shared_ptr<Source> source;
3058 if ((i = sources.find (id)) != sources.end()) {
3065 boost::shared_ptr<Source>
3066 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3068 Glib::Mutex::Lock lm (source_lock);
3070 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3071 cerr << "comparing " << path << " with " << i->second->name() << endl;
3072 boost::shared_ptr<AudioFileSource> afs
3073 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3075 if (afs && afs->path() == path && chn == afs->channel()) {
3079 return boost::shared_ptr<Source>();
3084 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3087 string old_basename = PBD::basename_nosuffix (oldname);
3088 string new_legalized = legalize_for_path (newname);
3090 /* note: we know (or assume) the old path is already valid */
3094 /* destructive file sources have a name of the form:
3096 /path/to/Tnnnn-NAME(%[LR])?.wav
3098 the task here is to replace NAME with the new name.
3101 /* find last slash */
3105 string::size_type slash;
3106 string::size_type dash;
3108 if ((slash = path.find_last_of ('/')) == string::npos) {
3112 dir = path.substr (0, slash+1);
3114 /* '-' is not a legal character for the NAME part of the path */
3116 if ((dash = path.find_last_of ('-')) == string::npos) {
3120 prefix = path.substr (slash+1, dash-(slash+1));
3125 path += new_legalized;
3126 path += ".wav"; /* XXX gag me with a spoon */
3130 /* non-destructive file sources have a name of the form:
3132 /path/to/NAME-nnnnn(%[LR])?.ext
3134 the task here is to replace NAME with the new name.
3139 string::size_type slash;
3140 string::size_type dash;
3141 string::size_type postfix;
3143 /* find last slash */
3145 if ((slash = path.find_last_of ('/')) == string::npos) {
3149 dir = path.substr (0, slash+1);
3151 /* '-' is not a legal character for the NAME part of the path */
3153 if ((dash = path.find_last_of ('-')) == string::npos) {
3157 suffix = path.substr (dash+1);
3159 // Suffix is now everything after the dash. Now we need to eliminate
3160 // the nnnnn part, which is done by either finding a '%' or a '.'
3162 postfix = suffix.find_last_of ("%");
3163 if (postfix == string::npos) {
3164 postfix = suffix.find_last_of ('.');
3167 if (postfix != string::npos) {
3168 suffix = suffix.substr (postfix);
3170 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3174 const uint32_t limit = 10000;
3175 char buf[PATH_MAX+1];
3177 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3179 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3181 if (access (buf, F_OK) != 0) {
3189 error << "FATAL ERROR! Could not find a " << endl;
3197 /** Return the full path (in some session directory) for a new within-session source.
3198 * \a name must be a session-unique name that does not contain slashes
3199 * (e.g. as returned by new_*_source_name)
3202 Session::new_source_path_from_name (DataType type, const string& name)
3204 assert(name.find("/") == string::npos);
3206 SessionDirectory sdir(get_best_session_directory_for_new_source());
3209 if (type == DataType::AUDIO) {
3210 p = sdir.sound_path();
3211 } else if (type == DataType::MIDI) {
3212 p = sdir.midi_path();
3214 error << "Unknown source type, unable to create file path" << endmsg;
3219 return p.to_string();
3223 Session::peak_path (Glib::ustring base) const
3225 sys::path peakfile_path(_session_dir->peak_path());
3226 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3227 return peakfile_path.to_string();
3230 /** Return a unique name based on \a base for a new internal audio source */
3232 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3236 char buf[PATH_MAX+1];
3237 const uint32_t limit = 10000;
3241 legalized = legalize_for_path (base);
3243 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3244 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3246 vector<space_and_path>::iterator i;
3247 uint32_t existing = 0;
3249 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3251 SessionDirectory sdir((*i).path);
3253 spath = sdir.sound_path().to_string();
3258 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3259 spath.c_str(), cnt, legalized.c_str());
3260 } else if (nchan == 2) {
3262 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3263 spath.c_str(), cnt, legalized.c_str());
3265 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3266 spath.c_str(), cnt, legalized.c_str());
3268 } else if (nchan < 26) {
3269 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3270 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3272 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3273 spath.c_str(), cnt, legalized.c_str());
3282 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3283 } else if (nchan == 2) {
3285 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3287 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3289 } else if (nchan < 26) {
3290 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3292 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3296 if (sys::exists(buf)) {
3302 if (existing == 0) {
3307 error << string_compose(
3308 _("There are already %1 recordings for %2, which I consider too many."),
3309 limit, base) << endmsg;
3311 throw failed_constructor();
3315 return Glib::path_get_basename(buf);
3318 /** Create a new within-session audio source */
3319 boost::shared_ptr<AudioFileSource>
3320 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3322 const size_t n_chans = ds.n_channels().n_audio();
3323 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3324 const string path = new_source_path_from_name(DataType::AUDIO, name);
3326 return boost::dynamic_pointer_cast<AudioFileSource> (
3327 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3330 /** Return a unique name based on \a base for a new internal MIDI source */
3332 Session::new_midi_source_name (const string& base)
3335 char buf[PATH_MAX+1];
3336 const uint32_t limit = 10000;
3340 legalized = legalize_for_path (base);
3342 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3343 for (cnt = 1; cnt <= limit; ++cnt) {
3345 vector<space_and_path>::iterator i;
3346 uint32_t existing = 0;
3348 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3350 SessionDirectory sdir((*i).path);
3352 sys::path p = sdir.midi_path();
3355 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3357 if (sys::exists (buf)) {
3362 if (existing == 0) {
3367 error << string_compose(
3368 _("There are already %1 recordings for %2, which I consider too many."),
3369 limit, base) << endmsg;
3371 throw failed_constructor();
3375 return Glib::path_get_basename(buf);
3379 /** Create a new within-session MIDI source */
3380 boost::shared_ptr<MidiSource>
3381 Session::create_midi_source_for_session (MidiDiskstream& ds)
3383 const string name = new_midi_source_name (ds.name());
3384 const string path = new_source_path_from_name (DataType::MIDI, name);
3386 return boost::dynamic_pointer_cast<SMFSource> (
3387 SourceFactory::createWritable (
3388 DataType::MIDI, *this, path, false, frame_rate()));
3393 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3395 if (playlist->hidden()) {
3399 bool existing = playlists->add (playlist);
3401 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3405 playlist->release();
3412 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3414 if (_state_of_the_state & Deletion) {
3418 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3424 playlists->remove (playlist);
3430 Session::set_audition (boost::shared_ptr<Region> r)
3432 pending_audition_region = r;
3433 add_post_transport_work (PostTransportAudition);
3434 _butler->schedule_transport_work ();
3438 Session::audition_playlist ()
3440 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3441 ev->region.reset ();
3446 Session::non_realtime_set_audition ()
3448 if (!pending_audition_region) {
3449 auditioner->audition_current_playlist ();
3451 auditioner->audition_region (pending_audition_region);
3452 pending_audition_region.reset ();
3454 AuditionActive (true); /* EMIT SIGNAL */
3458 Session::audition_region (boost::shared_ptr<Region> r)
3460 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3466 Session::cancel_audition ()
3468 if (auditioner->active()) {
3469 auditioner->cancel_audition ();
3470 AuditionActive (false); /* EMIT SIGNAL */
3475 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3477 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3481 Session::remove_empty_sounds ()
3483 vector<string> audio_filenames;
3485 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3487 Glib::Mutex::Lock lm (source_lock);
3489 TapeFileMatcher tape_file_matcher;
3491 remove_if (audio_filenames.begin(), audio_filenames.end(),
3492 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3494 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3496 sys::path audio_file_path (_session_dir->sound_path());
3498 audio_file_path /= *i;
3500 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3504 sys::remove (audio_file_path);
3505 const string peakfile = peak_path (audio_file_path.to_string());
3506 sys::remove (peakfile);
3508 catch (const sys::filesystem_error& err)
3510 error << err.what() << endmsg;
3517 Session::is_auditioning () const
3519 /* can be called before we have an auditioner object */
3521 return auditioner->active();
3528 Session::n_diskstreams () const
3532 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3534 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3535 if (!(*i)->hidden()) {
3543 Session::graph_reordered ()
3545 /* don't do this stuff if we are setting up connections
3546 from a set_state() call or creating new tracks. Ditto for deletion.
3549 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3553 /* every track/bus asked for this to be handled but it was deferred because
3554 we were connecting. do it now.
3557 request_input_change_handling ();
3561 /* force all diskstreams to update their capture offset values to
3562 reflect any changes in latencies within the graph.
3565 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3567 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3568 (*i)->set_capture_offset ();
3573 Session::add_processor (Processor* processor)
3575 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3580 Session::remove_processor (Processor* processor)
3584 PortInsert* port_insert;
3586 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3587 insert_bitset[port_insert->bit_slot()] = false;
3588 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3589 send_bitset[send->bit_slot()] = false;
3590 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3591 return_bitset[retrn->bit_slot()] = false;
3598 Session::available_capture_duration ()
3600 float sample_bytes_on_disk = 4.0; // keep gcc happy
3602 switch (config.get_native_file_data_format()) {
3604 sample_bytes_on_disk = 4.0;
3608 sample_bytes_on_disk = 3.0;
3612 sample_bytes_on_disk = 2.0;
3616 /* impossible, but keep some gcc versions happy */
3617 fatal << string_compose (_("programming error: %1"),
3618 X_("illegal native file data format"))
3623 double scale = 4096.0 / sample_bytes_on_disk;
3625 if (_total_free_4k_blocks * scale > (double) max_frames) {
3629 return (nframes_t) floor (_total_free_4k_blocks * scale);
3633 Session::add_bundle (shared_ptr<Bundle> bundle)
3636 RCUWriter<BundleList> writer (_bundles);
3637 boost::shared_ptr<BundleList> b = writer.get_copy ();
3638 b->push_back (bundle);
3641 BundleAdded (bundle); /* EMIT SIGNAL */
3647 Session::remove_bundle (shared_ptr<Bundle> bundle)
3649 bool removed = false;
3652 RCUWriter<BundleList> writer (_bundles);
3653 boost::shared_ptr<BundleList> b = writer.get_copy ();
3654 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3656 if (i != b->end()) {
3663 BundleRemoved (bundle); /* EMIT SIGNAL */
3670 Session::bundle_by_name (string name) const
3672 boost::shared_ptr<BundleList> b = _bundles.reader ();
3674 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3675 if ((*i)->name() == name) {
3680 return boost::shared_ptr<Bundle> ();
3684 Session::tempo_map_changed (Change)
3688 playlists->update_after_tempo_map_change ();
3693 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3694 * the given count with the current block size.
3697 Session::ensure_buffers (ChanCount howmany)
3699 if (current_block_size == 0) {
3700 return; // too early? (is this ok?)
3703 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3704 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3705 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3706 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3707 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3710 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3714 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3716 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3717 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3722 Session::next_insert_id ()
3724 /* this doesn't really loop forever. just think about it */
3727 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3728 if (!insert_bitset[n]) {
3729 insert_bitset[n] = true;
3735 /* none available, so resize and try again */
3737 insert_bitset.resize (insert_bitset.size() + 16, false);
3742 Session::next_send_id ()
3744 /* this doesn't really loop forever. just think about it */
3747 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3748 if (!send_bitset[n]) {
3749 send_bitset[n] = true;
3755 /* none available, so resize and try again */
3757 send_bitset.resize (send_bitset.size() + 16, false);
3762 Session::next_return_id ()
3764 /* this doesn't really loop forever. just think about it */
3767 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3768 if (!return_bitset[n]) {
3769 return_bitset[n] = true;
3775 /* none available, so resize and try again */
3777 return_bitset.resize (return_bitset.size() + 16, false);
3782 Session::mark_send_id (uint32_t id)
3784 if (id >= send_bitset.size()) {
3785 send_bitset.resize (id+16, false);
3787 if (send_bitset[id]) {
3788 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3790 send_bitset[id] = true;
3794 Session::mark_return_id (uint32_t id)
3796 if (id >= return_bitset.size()) {
3797 return_bitset.resize (id+16, false);
3799 if (return_bitset[id]) {
3800 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3802 return_bitset[id] = true;
3806 Session::mark_insert_id (uint32_t id)
3808 if (id >= insert_bitset.size()) {
3809 insert_bitset.resize (id+16, false);
3811 if (insert_bitset[id]) {
3812 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3814 insert_bitset[id] = true;
3817 /* Named Selection management */
3820 Session::named_selection_by_name (string name)
3822 Glib::Mutex::Lock lm (named_selection_lock);
3823 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3824 if ((*i)->name == name) {
3832 Session::add_named_selection (NamedSelection* named_selection)
3835 Glib::Mutex::Lock lm (named_selection_lock);
3836 named_selections.insert (named_selections.begin(), named_selection);
3839 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3845 NamedSelectionAdded (); /* EMIT SIGNAL */
3849 Session::remove_named_selection (NamedSelection* named_selection)
3851 bool removed = false;
3854 Glib::Mutex::Lock lm (named_selection_lock);
3856 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3858 if (i != named_selections.end()) {
3860 named_selections.erase (i);
3867 NamedSelectionRemoved (); /* EMIT SIGNAL */
3872 Session::reset_native_file_format ()
3874 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3876 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3877 (*i)->reset_write_sources (false);
3882 Session::route_name_unique (string n) const
3884 shared_ptr<RouteList> r = routes.reader ();
3886 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3887 if ((*i)->name() == n) {
3896 Session::route_name_internal (string n) const
3898 if (auditioner && auditioner->name() == n) {
3902 if (_click_io && _click_io->name() == n) {
3910 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3912 if (!force && howmany <= _npan_buffers) {
3916 if (_pan_automation_buffer) {
3918 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3919 delete [] _pan_automation_buffer[i];
3922 delete [] _pan_automation_buffer;
3925 _pan_automation_buffer = new pan_t*[howmany];
3927 for (uint32_t i = 0; i < howmany; ++i) {
3928 _pan_automation_buffer[i] = new pan_t[nframes];
3931 _npan_buffers = howmany;
3935 Session::freeze (InterThreadInfo& itt)
3937 shared_ptr<RouteList> r = routes.reader ();
3939 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3941 boost::shared_ptr<Track> t;
3943 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3944 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3954 boost::shared_ptr<Region>
3955 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3956 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3957 InterThreadInfo& itt, bool enable_processing)
3959 boost::shared_ptr<Region> result;
3960 boost::shared_ptr<Playlist> playlist;
3961 boost::shared_ptr<AudioFileSource> fsource;
3963 char buf[PATH_MAX+1];
3964 ChanCount nchans(track.audio_diskstream()->n_channels());
3966 nframes_t this_chunk;
3969 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3970 const string sound_dir = sdir.sound_path().to_string();
3971 nframes_t len = end - start;
3974 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3975 end, start) << endmsg;
3979 const nframes_t chunk_size = (256 * 1024)/4;
3981 // block all process callback handling
3983 block_processing ();
3985 /* call tree *MUST* hold route_lock */
3987 if ((playlist = track.diskstream()->playlist()) == 0) {
3991 /* external redirects will be a problem */
3993 if (track.has_external_redirects()) {
3997 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3999 for (x = 0; x < 99999; ++x) {
4000 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4001 if (access (buf, F_OK) != 0) {
4007 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4012 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4013 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4016 catch (failed_constructor& err) {
4017 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4021 srcs.push_back (fsource);
4024 /* XXX need to flush all redirects */
4029 /* create a set of reasonably-sized buffers */
4030 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4031 buffers.set_count(nchans);
4033 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4034 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4036 afs->prepare_for_peakfile_writes ();
4039 while (to_do && !itt.cancel) {
4041 this_chunk = min (to_do, chunk_size);
4043 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4048 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4049 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4052 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4058 start += this_chunk;
4059 to_do -= this_chunk;
4061 itt.progress = (float) (1.0 - ((double) to_do / len));
4070 xnow = localtime (&now);
4072 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4073 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4076 afs->update_header (position, *xnow, now);
4077 afs->flush_header ();
4081 /* construct a region to represent the bounced material */
4083 result = RegionFactory::create (srcs, 0,
4084 srcs.front()->length(srcs.front()->timeline_position()),
4085 region_name_from_path (srcs.front()->name(), true));
4090 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4091 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4094 afs->mark_for_remove ();
4097 (*src)->drop_references ();
4101 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4102 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4105 afs->done_with_peakfile_writes ();
4109 unblock_processing ();
4115 Session::get_silent_buffers (ChanCount count)
4117 assert(_silent_buffers->available() >= count);
4118 _silent_buffers->set_count(count);
4120 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4121 for (size_t i= 0; i < count.get(*t); ++i) {
4122 _silent_buffers->get(*t, i).clear();
4126 return *_silent_buffers;
4130 Session::get_scratch_buffers (ChanCount count)
4132 if (count != ChanCount::ZERO) {
4133 assert(_scratch_buffers->available() >= count);
4134 _scratch_buffers->set_count(count);
4136 _scratch_buffers->set_count (_scratch_buffers->available());
4139 return *_scratch_buffers;
4143 Session::get_mix_buffers (ChanCount count)
4145 assert(_mix_buffers->available() >= count);
4146 _mix_buffers->set_count(count);
4147 return *_mix_buffers;
4151 Session::ntracks () const
4154 shared_ptr<RouteList> r = routes.reader ();
4156 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4157 if (boost::dynamic_pointer_cast<Track> (*i)) {
4166 Session::nbusses () const
4169 shared_ptr<RouteList> r = routes.reader ();
4171 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4172 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4181 Session::add_automation_list(AutomationList *al)
4183 automation_lists[al->id()] = al;
4187 Session::compute_initial_length ()
4189 return _engine.frame_rate() * 60 * 5;
4193 Session::sync_order_keys (std::string const & base)
4195 if (!Config->get_sync_all_route_ordering()) {
4196 /* leave order keys as they are */
4200 boost::shared_ptr<RouteList> r = routes.reader ();
4202 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4203 (*i)->sync_order_keys (base);
4206 Route::SyncOrderKeys (base); // EMIT SIGNAL
4210 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4212 Session::have_rec_enabled_diskstream () const
4214 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4217 /** Update the state of our rec-enabled diskstreams flag */
4219 Session::update_have_rec_enabled_diskstream ()
4221 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4222 DiskstreamList::iterator i = dsl->begin ();
4223 while (i != dsl->end () && (*i)->record_enabled () == false) {
4227 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4229 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4231 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4232 RecordStateChanged (); /* EMIT SIGNAL */
4237 Session::listen_position_changed ()
4241 switch (Config->get_listen_position()) {
4242 case AfterFaderListen:
4246 case PreFaderListen:
4251 boost::shared_ptr<RouteList> r = routes.reader ();
4253 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4254 (*i)->put_control_outs_at (p);
4259 Session::solo_control_mode_changed ()
4261 /* cancel all solo or all listen when solo control mode changes */
4263 if (Config->get_solo_control_is_listen_control()) {
4264 set_solo (routes.reader(), false);
4266 set_listen (routes.reader(), false);
4271 Session::route_group_changed ()
4273 RouteGroupChanged (); /* EMIT SIGNAL */
4277 Session::get_available_sync_options () const
4279 vector<SyncSource> ret;
4281 ret.push_back (JACK);
4284 ret.push_back (MTC);
4287 if (midi_clock_port()) {
4288 ret.push_back (MIDIClock);
4294 boost::shared_ptr<RouteList>
4295 Session::get_routes_with_regions_at (nframes64_t const p) const
4297 shared_ptr<RouteList> r = routes.reader ();
4298 shared_ptr<RouteList> rl (new RouteList);
4300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4301 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4306 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4311 boost::shared_ptr<Playlist> pl = ds->playlist ();
4316 if (pl->has_region_at (p)) {