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/named_selection.h"
75 #include "ardour/playlist.h"
76 #include "ardour/plugin_insert.h"
77 #include "ardour/port_insert.h"
78 #include "ardour/processor.h"
79 #include "ardour/rc_configuration.h"
80 #include "ardour/recent_sessions.h"
81 #include "ardour/region_factory.h"
82 #include "ardour/return.h"
83 #include "ardour/route_group.h"
84 #include "ardour/send.h"
85 #include "ardour/session.h"
86 #include "ardour/session_directory.h"
87 #include "ardour/session_directory.h"
88 #include "ardour/session_metadata.h"
89 #include "ardour/session_playlists.h"
90 #include "ardour/slave.h"
91 #include "ardour/smf_source.h"
92 #include "ardour/source_factory.h"
93 #include "ardour/tape_file_matcher.h"
94 #include "ardour/tempo.h"
95 #include "ardour/utils.h"
100 using namespace ARDOUR;
102 using boost::shared_ptr;
103 using boost::weak_ptr;
105 bool Session::_disable_all_loaded_plugins = false;
107 sigc::signal<void,std::string> Session::Dialog;
108 sigc::signal<int> Session::AskAboutPendingState;
109 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
110 sigc::signal<void> Session::SendFeedback;
112 sigc::signal<void> Session::TimecodeOffsetChanged;
113 sigc::signal<void> Session::StartTimeChanged;
114 sigc::signal<void> Session::EndTimeChanged;
115 sigc::signal<void> Session::AutoBindingOn;
116 sigc::signal<void> Session::AutoBindingOff;
117 sigc::signal<void, std::string, std::string> Session::Exported;
119 Session::Session (AudioEngine &eng,
120 const string& fullpath,
121 const string& snapshot_name,
125 _target_transport_speed (0.0),
126 _requested_return_frame (-1),
127 _scratch_buffers(new BufferSet()),
128 _silent_buffers(new BufferSet()),
129 _mix_buffers(new BufferSet()),
131 _mmc_port (default_mmc_port),
132 _mtc_port (default_mtc_port),
133 _midi_port (default_midi_port),
134 _midi_clock_port (default_midi_clock_port),
135 _session_dir (new SessionDirectory(fullpath)),
137 _butler (new Butler (this)),
138 _post_transport_work (0),
139 _send_timecode_update (false),
140 midi_thread (pthread_t (0)),
141 midi_requests (128), // the size of this should match the midi request pool size
142 diskstreams (new DiskstreamList),
143 routes (new RouteList),
144 _total_free_4k_blocks (0),
145 _bundles (new BundleList),
146 _bundle_xml_node (0),
149 click_emphasis_data (0),
151 _metadata (new SessionMetadata()),
152 _have_rec_enabled_diskstream (false)
155 playlists.reset (new SessionPlaylists);
159 interpolation.add_channel_to (0, 0);
161 if (!eng.connected()) {
162 throw failed_constructor();
165 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
167 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
168 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
170 first_stage_init (fullpath, snapshot_name);
172 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
175 if (create (new_session, mix_template, compute_initial_length())) {
177 throw failed_constructor ();
181 if (second_stage_init (new_session)) {
183 throw failed_constructor ();
186 store_recent_sessions(_name, _path);
188 bool was_dirty = dirty();
190 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
192 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
193 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
196 DirtyChanged (); /* EMIT SIGNAL */
200 Session::Session (AudioEngine &eng,
202 string snapshot_name,
203 AutoConnectOption input_ac,
204 AutoConnectOption output_ac,
205 uint32_t control_out_channels,
206 uint32_t master_out_channels,
207 uint32_t requested_physical_in,
208 uint32_t requested_physical_out,
209 nframes_t initial_length)
212 _target_transport_speed (0.0),
213 _requested_return_frame (-1),
214 _scratch_buffers(new BufferSet()),
215 _silent_buffers(new BufferSet()),
216 _mix_buffers(new BufferSet()),
218 _mmc_port (default_mmc_port),
219 _mtc_port (default_mtc_port),
220 _midi_port (default_midi_port),
221 _midi_clock_port (default_midi_clock_port),
222 _session_dir ( new SessionDirectory(fullpath)),
224 _butler (new Butler (this)),
225 _post_transport_work (0),
226 _send_timecode_update (false),
227 midi_thread (pthread_t (0)),
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 ();
369 //terminate_midi_thread ();
371 if (click_data != default_click) {
372 delete [] click_data;
375 if (click_emphasis_data != default_click_emphasis) {
376 delete [] click_emphasis_data;
381 delete _scratch_buffers;
382 delete _silent_buffers;
385 /* clear out any pending dead wood from RCU managed objects */
388 diskstreams.flush ();
391 AudioDiskstream::free_working_buffers();
393 Route::SyncOrderKeys.clear();
395 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
396 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
397 NamedSelectionList::iterator tmp;
406 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
407 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
408 RegionList::iterator tmp;
413 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()));
414 i->second->drop_references ();
415 DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count()));
421 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
423 /* reset these three references to special routes before we do the usual route delete thing */
426 _master_out.reset ();
427 _control_out.reset ();
430 RCUWriter<RouteList> writer (routes);
431 boost::shared_ptr<RouteList> r = writer.get_copy ();
432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
433 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
434 (*i)->drop_references ();
437 /* writer goes out of scope and updates master */
441 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
443 RCUWriter<DiskstreamList> dwriter (diskstreams);
444 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
445 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
446 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
447 (*i)->drop_references ();
451 diskstreams.flush ();
453 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
454 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
455 SourceMap::iterator tmp;
460 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
461 i->second->drop_references ();
469 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
470 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
474 Crossfade::set_buffer_size (0);
478 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
481 boost_debug_list_ptrs ();
483 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
487 Session::set_worst_io_latencies ()
489 _worst_output_latency = 0;
490 _worst_input_latency = 0;
492 if (!_engine.connected()) {
496 boost::shared_ptr<RouteList> r = routes.reader ();
498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
499 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
500 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
505 Session::when_engine_running ()
507 string first_physical_output;
509 BootMessage (_("Set block size and sample rate"));
511 set_block_size (_engine.frames_per_cycle());
512 set_frame_rate (_engine.frame_rate());
514 BootMessage (_("Using configuration"));
516 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
517 config.map_parameters (bind (mem_fun (*this, &Session::config_changed), true));
519 /* every time we reconnect, recompute worst case output latencies */
521 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
523 if (synced_to_jack()) {
524 _engine.transport_stop ();
527 if (config.get_jack_time_master()) {
528 _engine.transport_locate (_transport_frame);
536 _click_io.reset (new ClickIO (*this, "click"));
538 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
540 /* existing state for Click */
543 if (Stateful::loading_state_version < 3000) {
544 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
546 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
551 _clicking = Config->get_clicking ();
555 error << _("could not setup Click I/O") << endmsg;
562 /* default state for Click: dual-mono to first 2 physical outputs */
564 for (int physport = 0; physport < 2; ++physport) {
565 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
567 if (physical_output.length()) {
568 if (_click_io->add_port (physical_output, this)) {
569 // relax, even though its an error
574 if (_click_io->n_ports () > ChanCount::ZERO) {
575 _clicking = Config->get_clicking ();
580 catch (failed_constructor& err) {
581 error << _("cannot setup Click I/O") << endmsg;
584 BootMessage (_("Compute I/O Latencies"));
586 set_worst_io_latencies ();
589 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
592 BootMessage (_("Set up standard connections"));
594 /* Create a set of Bundle objects that map
595 to the physical I/O currently available. We create both
596 mono and stereo bundles, so that the common cases of mono
597 and stereo tracks get bundles to put in their mixer strip
598 in / out menus. There may be a nicer way of achieving that;
599 it doesn't really scale that well to higher channel counts
602 /* mono output bundles */
604 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
606 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
608 shared_ptr<Bundle> c (new Bundle (buf, true));
609 c->add_channel (_("mono"));
610 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
615 /* stereo output bundles */
617 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
618 if (np + 1 < n_physical_outputs) {
620 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
621 shared_ptr<Bundle> c (new Bundle (buf, true));
622 c->add_channel (_("L"));
623 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
624 c->add_channel (_("R"));
625 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
631 /* mono input bundles */
633 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
635 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
637 shared_ptr<Bundle> c (new Bundle (buf, false));
638 c->add_channel (_("mono"));
639 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
644 /* stereo input bundles */
646 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
647 if (np + 1 < n_physical_inputs) {
649 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
651 shared_ptr<Bundle> c (new Bundle (buf, false));
652 c->add_channel (_("L"));
653 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
654 c->add_channel (_("R"));
655 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
661 BootMessage (_("Setup signal flow and plugins"));
665 if (!no_auto_connect()) {
667 if (_master_out && Config->get_auto_connect_standard_busses()) {
669 /* if requested auto-connect the outputs to the first N physical ports.
672 uint32_t limit = _master_out->n_outputs().n_total();
674 for (uint32_t n = 0; n < limit; ++n) {
675 Port* p = _master_out->output()->nth (n);
676 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
678 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
679 if (_master_out->output()->connect (p, connect_to, this)) {
680 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
690 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
691 are undefined, at best.
694 /* control out listens to master bus (but ignores it
695 under some conditions)
698 uint32_t limit = _control_out->n_inputs().n_audio();
701 for (uint32_t n = 0; n < limit; ++n) {
702 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
703 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
706 string connect_to = o->name();
707 if (_control_out->input()->connect (p, connect_to, this)) {
708 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
716 /* if control out is not connected,
717 connect control out to physical outs, but use ones after the master if possible
720 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
722 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
724 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
727 _control_out->output()->connect_ports_to_bundle (b, this);
729 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
730 Config->get_monitor_bus_preferred_bundle())
736 /* XXX this logic is wrong for mixed port types */
738 uint32_t shift = _master_out->n_outputs().n_audio();
739 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
740 limit = _control_out->n_outputs().n_audio();
742 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
744 for (uint32_t n = 0; n < limit; ++n) {
746 Port* p = _control_out->output()->nth (n);
747 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
749 if (!connect_to.empty()) {
750 if (_control_out->output()->connect (p, connect_to, this)) {
751 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
762 /* catch up on send+insert cnts */
764 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
766 /* hook us up to the engine */
768 BootMessage (_("Connect to engine"));
770 _engine.set_session (this);
774 Session::hookup_io ()
776 /* stop graph reordering notifications from
777 causing resorts, etc.
780 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
785 /* we delay creating the auditioner till now because
786 it makes its own connections to ports.
787 the engine has to be running for this to work.
791 auditioner.reset (new Auditioner (*this));
794 catch (failed_constructor& err) {
795 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
799 /* load bundles, which we may have postponed earlier on */
800 if (_bundle_xml_node) {
801 load_bundles (*_bundle_xml_node);
802 delete _bundle_xml_node;
805 /* Tell all IO objects to connect themselves together */
807 IO::enable_connecting ();
809 /* Now reset all panners */
811 Delivery::reset_panners ();
813 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
817 boost::shared_ptr<RouteList> r = routes.reader ();
819 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
821 if ((*x)->is_control() || (*x)->is_master()) {
825 (*x)->listen_via (_control_out,
826 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
831 /* Anyone who cares about input state, wake up and do something */
833 IOConnectionsComplete (); /* EMIT SIGNAL */
835 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
837 /* now handle the whole enchilada as if it was one
843 /* update the full solo state, which can't be
844 correctly determined on a per-route basis, but
845 needs the global overview that only the session
849 update_route_solo_state ();
853 Session::playlist_length_changed ()
855 /* we can't just increase end_location->end() if pl->get_maximum_extent()
856 if larger. if the playlist used to be the longest playlist,
857 and its now shorter, we have to decrease end_location->end(). hence,
858 we have to iterate over all diskstreams and check the
859 playlists currently in use.
865 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
867 boost::shared_ptr<Diskstream> dstream = wp.lock ();
872 boost::shared_ptr<Playlist> playlist;
874 if ((playlist = dstream->playlist()) != 0) {
875 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
878 /* see comment in playlist_length_changed () */
883 Session::record_enabling_legal () const
885 /* this used to be in here, but survey says.... we don't need to restrict it */
886 // if (record_status() == Recording) {
890 if (Config->get_all_safe()) {
897 Session::reset_input_monitor_state ()
899 if (transport_rolling()) {
901 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
903 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
904 if ((*i)->record_enabled ()) {
905 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
906 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
910 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
912 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
913 if ((*i)->record_enabled ()) {
914 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
915 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
922 Session::auto_punch_start_changed (Location* location)
924 replace_event (SessionEvent::PunchIn, location->start());
926 if (get_record_enabled() && config.get_punch_in()) {
927 /* capture start has been changed, so save new pending state */
928 save_state ("", true);
933 Session::auto_punch_end_changed (Location* location)
935 nframes_t when_to_stop = location->end();
936 // when_to_stop += _worst_output_latency + _worst_input_latency;
937 replace_event (SessionEvent::PunchOut, when_to_stop);
941 Session::auto_punch_changed (Location* location)
943 nframes_t when_to_stop = location->end();
945 replace_event (SessionEvent::PunchIn, location->start());
946 //when_to_stop += _worst_output_latency + _worst_input_latency;
947 replace_event (SessionEvent::PunchOut, when_to_stop);
951 Session::auto_loop_changed (Location* location)
953 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
955 if (transport_rolling() && play_loop) {
958 // if (_transport_frame > location->end()) {
960 if (_transport_frame < location->start() || _transport_frame > location->end()) {
961 // relocate to beginning of loop
962 clear_events (SessionEvent::LocateRoll);
964 request_locate (location->start(), true);
967 else if (Config->get_seamless_loop() && !loop_changing) {
969 // schedule a locate-roll to refill the diskstreams at the
971 loop_changing = true;
973 if (location->end() > last_loopend) {
974 clear_events (SessionEvent::LocateRoll);
975 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
982 last_loopend = location->end();
986 Session::set_auto_punch_location (Location* location)
990 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
991 auto_punch_start_changed_connection.disconnect();
992 auto_punch_end_changed_connection.disconnect();
993 auto_punch_changed_connection.disconnect();
994 existing->set_auto_punch (false, this);
995 remove_event (existing->start(), SessionEvent::PunchIn);
996 clear_events (SessionEvent::PunchOut);
997 auto_punch_location_changed (0);
1002 if (location == 0) {
1006 if (location->end() <= location->start()) {
1007 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1011 auto_punch_start_changed_connection.disconnect();
1012 auto_punch_end_changed_connection.disconnect();
1013 auto_punch_changed_connection.disconnect();
1015 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1016 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1017 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1019 location->set_auto_punch (true, this);
1022 auto_punch_changed (location);
1024 auto_punch_location_changed (location);
1028 Session::set_auto_loop_location (Location* location)
1032 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1033 auto_loop_start_changed_connection.disconnect();
1034 auto_loop_end_changed_connection.disconnect();
1035 auto_loop_changed_connection.disconnect();
1036 existing->set_auto_loop (false, this);
1037 remove_event (existing->end(), SessionEvent::AutoLoop);
1038 auto_loop_location_changed (0);
1043 if (location == 0) {
1047 if (location->end() <= location->start()) {
1048 error << _("Session: you can't use a mark for auto loop") << endmsg;
1052 last_loopend = location->end();
1054 auto_loop_start_changed_connection.disconnect();
1055 auto_loop_end_changed_connection.disconnect();
1056 auto_loop_changed_connection.disconnect();
1058 auto_loop_start_changed_connection = location->start_changed.connect (
1059 mem_fun (this, &Session::auto_loop_changed));
1060 auto_loop_end_changed_connection = location->end_changed.connect (
1061 mem_fun (this, &Session::auto_loop_changed));
1062 auto_loop_changed_connection = location->changed.connect (
1063 mem_fun (this, &Session::auto_loop_changed));
1065 location->set_auto_loop (true, this);
1067 /* take care of our stuff first */
1069 auto_loop_changed (location);
1071 /* now tell everyone else */
1073 auto_loop_location_changed (location);
1077 Session::locations_added (Location *)
1083 Session::locations_changed ()
1085 _locations.apply (*this, &Session::handle_locations_changed);
1089 Session::handle_locations_changed (Locations::LocationList& locations)
1091 Locations::LocationList::iterator i;
1093 bool set_loop = false;
1094 bool set_punch = false;
1096 for (i = locations.begin(); i != locations.end(); ++i) {
1100 if (location->is_auto_punch()) {
1101 set_auto_punch_location (location);
1104 if (location->is_auto_loop()) {
1105 set_auto_loop_location (location);
1109 if (location->is_start()) {
1110 start_location = location;
1112 if (location->is_end()) {
1113 end_location = location;
1118 set_auto_loop_location (0);
1121 set_auto_punch_location (0);
1128 Session::enable_record ()
1130 /* XXX really atomic compare+swap here */
1131 if (g_atomic_int_get (&_record_status) != Recording) {
1132 g_atomic_int_set (&_record_status, Recording);
1133 _last_record_location = _transport_frame;
1134 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1136 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1137 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1138 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1139 if ((*i)->record_enabled ()) {
1140 (*i)->monitor_input (true);
1145 RecordStateChanged ();
1150 Session::disable_record (bool rt_context, bool force)
1154 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1156 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1157 g_atomic_int_set (&_record_status, Disabled);
1159 if (rs == Recording) {
1160 g_atomic_int_set (&_record_status, Enabled);
1164 // FIXME: timestamp correct? [DR]
1165 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1166 // does this /need/ to be sent in all cases?
1168 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1171 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1172 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1174 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1175 if ((*i)->record_enabled ()) {
1176 (*i)->monitor_input (false);
1181 RecordStateChanged (); /* emit signal */
1184 remove_pending_capture_state ();
1190 Session::step_back_from_record ()
1192 /* XXX really atomic compare+swap here */
1193 if (g_atomic_int_get (&_record_status) == Recording) {
1194 g_atomic_int_set (&_record_status, Enabled);
1196 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1197 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1199 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1200 if ((*i)->record_enabled ()) {
1201 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1202 (*i)->monitor_input (false);
1210 Session::maybe_enable_record ()
1212 g_atomic_int_set (&_record_status, Enabled);
1214 /* this function is currently called from somewhere other than an RT thread.
1215 this save_state() call therefore doesn't impact anything.
1218 save_state ("", true);
1220 if (_transport_speed) {
1221 if (!config.get_punch_in()) {
1225 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1226 RecordStateChanged (); /* EMIT SIGNAL */
1233 Session::audible_frame () const
1239 /* the first of these two possible settings for "offset"
1240 mean that the audible frame is stationary until
1241 audio emerges from the latency compensation
1244 the second means that the audible frame is stationary
1245 until audio would emerge from a physical port
1246 in the absence of any plugin latency compensation
1249 offset = _worst_output_latency;
1251 if (offset > current_block_size) {
1252 offset -= current_block_size;
1254 /* XXX is this correct? if we have no external
1255 physical connections and everything is internal
1256 then surely this is zero? still, how
1257 likely is that anyway?
1259 offset = current_block_size;
1262 if (synced_to_jack()) {
1263 tf = _engine.transport_frame();
1265 tf = _transport_frame;
1270 if (!non_realtime_work_pending()) {
1274 /* check to see if we have passed the first guaranteed
1275 audible frame past our last start position. if not,
1276 return that last start point because in terms
1277 of audible frames, we have not moved yet.
1280 if (_transport_speed > 0.0f) {
1282 if (!play_loop || !have_looped) {
1283 if (tf < _last_roll_location + offset) {
1284 return _last_roll_location;
1292 } else if (_transport_speed < 0.0f) {
1294 /* XXX wot? no backward looping? */
1296 if (tf > _last_roll_location - offset) {
1297 return _last_roll_location;
1309 Session::set_frame_rate (nframes_t frames_per_second)
1311 /** \fn void Session::set_frame_size(nframes_t)
1312 the AudioEngine object that calls this guarantees
1313 that it will not be called while we are also in
1314 ::process(). Its fine to do things that block
1318 _base_frame_rate = frames_per_second;
1322 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1326 // XXX we need some equivalent to this, somehow
1327 // SndFileSource::setup_standard_crossfades (frames_per_second);
1331 /* XXX need to reset/reinstantiate all LADSPA plugins */
1335 Session::set_block_size (nframes_t nframes)
1337 /* the AudioEngine guarantees
1338 that it will not be called while we are also in
1339 ::process(). It is therefore fine to do things that block
1344 current_block_size = nframes;
1346 ensure_buffers(_scratch_buffers->available());
1348 delete [] _gain_automation_buffer;
1349 _gain_automation_buffer = new gain_t[nframes];
1351 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1353 boost::shared_ptr<RouteList> r = routes.reader ();
1355 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1356 (*i)->set_block_size (nframes);
1359 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1360 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1361 (*i)->set_block_size (nframes);
1364 set_worst_io_latencies ();
1369 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1372 nframes_t fade_frames;
1374 /* Don't allow fade of less 1 frame */
1376 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1383 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1387 default_fade_msecs = fade_msecs;
1388 default_fade_steepness = steepness;
1391 // jlc, WTF is this!
1392 Glib::RWLock::ReaderLock lm (route_lock);
1393 AudioRegion::set_default_fade (steepness, fade_frames);
1398 /* XXX have to do this at some point */
1399 /* foreach region using default fade, reset, then
1400 refill_all_diskstream_buffers ();
1405 struct RouteSorter {
1406 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1407 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1409 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1412 if (r1->fed_by.empty()) {
1413 if (r2->fed_by.empty()) {
1414 /* no ardour-based connections inbound to either route. just use signal order */
1415 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1417 /* r2 has connections, r1 does not; run r1 early */
1421 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1428 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1430 shared_ptr<Route> r2;
1432 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1433 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1437 /* make a copy of the existing list of routes that feed r1 */
1439 set<weak_ptr<Route> > existing = r1->fed_by;
1441 /* for each route that feeds r1, recurse, marking it as feeding
1445 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1446 if (!(r2 = (*i).lock ())) {
1447 /* (*i) went away, ignore it */
1451 /* r2 is a route that feeds r1 which somehow feeds base. mark
1452 base as being fed by r2
1455 rbase->fed_by.insert (r2);
1459 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1463 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1467 /* now recurse, so that we can mark base as being fed by
1468 all routes that feed r2
1471 trace_terminal (r2, rbase);
1478 Session::resort_routes ()
1480 /* don't do anything here with signals emitted
1481 by Routes while we are being destroyed.
1484 if (_state_of_the_state & Deletion) {
1491 RCUWriter<RouteList> writer (routes);
1492 shared_ptr<RouteList> r = writer.get_copy ();
1493 resort_routes_using (r);
1494 /* writer goes out of scope and forces update */
1499 Session::resort_routes_using (shared_ptr<RouteList> r)
1501 RouteList::iterator i, j;
1503 for (i = r->begin(); i != r->end(); ++i) {
1505 (*i)->fed_by.clear ();
1507 for (j = r->begin(); j != r->end(); ++j) {
1509 /* although routes can feed themselves, it will
1510 cause an endless recursive descent if we
1511 detect it. so don't bother checking for
1519 if ((*j)->feeds (*i)) {
1520 (*i)->fed_by.insert (*j);
1525 for (i = r->begin(); i != r->end(); ++i) {
1526 trace_terminal (*i, *i);
1533 cerr << "finished route resort\n";
1535 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1536 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1543 list<boost::shared_ptr<MidiTrack> >
1544 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1546 char track_name[32];
1547 uint32_t track_id = 0;
1550 RouteList new_routes;
1551 list<boost::shared_ptr<MidiTrack> > ret;
1552 //uint32_t control_id;
1554 // FIXME: need physical I/O and autoconnect stuff for MIDI
1556 /* count existing midi tracks */
1559 shared_ptr<RouteList> r = routes.reader ();
1561 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1562 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1563 if (!(*i)->is_hidden()) {
1565 //channels_used += (*i)->n_inputs().n_midi();
1571 vector<string> physinputs;
1572 vector<string> physoutputs;
1574 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1575 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1577 // control_id = ntracks() + nbusses();
1581 /* check for duplicate route names, since we might have pre-existing
1582 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1583 save, close,restart,add new route - first named route is now
1591 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1593 if (route_by_name (track_name) == 0) {
1597 } while (track_id < (UINT_MAX-1));
1599 shared_ptr<MidiTrack> track;
1602 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1604 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1605 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1610 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1611 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1617 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1621 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1622 port = physinputs[(channels_used+x)%nphysical_in];
1625 if (port.length() && track->connect_input (track->input (x), port, this)) {
1631 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1635 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1636 port = physoutputs[(channels_used+x)%nphysical_out];
1637 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1639 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1643 if (port.length() && track->connect_output (track->output (x), port, this)) {
1648 channels_used += track->n_inputs ().n_midi();
1652 track->midi_diskstream()->non_realtime_input_change();
1653 track->set_route_group (route_group, 0);
1655 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1656 //track->set_remote_control_id (control_id);
1658 new_routes.push_back (track);
1659 ret.push_back (track);
1662 catch (failed_constructor &err) {
1663 error << _("Session: could not create new midi track.") << endmsg;
1666 /* we need to get rid of this, since the track failed to be created */
1667 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1670 RCUWriter<DiskstreamList> writer (diskstreams);
1671 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1672 ds->remove (track->midi_diskstream());
1679 catch (AudioEngine::PortRegistrationFailure& pfe) {
1681 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;
1684 /* we need to get rid of this, since the track failed to be created */
1685 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1688 RCUWriter<DiskstreamList> writer (diskstreams);
1689 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1690 ds->remove (track->midi_diskstream());
1701 if (!new_routes.empty()) {
1702 add_routes (new_routes, false);
1703 save_state (_current_snapshot_name);
1709 list<boost::shared_ptr<AudioTrack> >
1710 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1712 char track_name[32];
1713 uint32_t track_id = 0;
1715 uint32_t channels_used = 0;
1717 RouteList new_routes;
1718 list<boost::shared_ptr<AudioTrack> > ret;
1719 uint32_t control_id;
1721 /* count existing audio tracks */
1724 shared_ptr<RouteList> r = routes.reader ();
1726 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1727 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1728 if (!(*i)->is_hidden()) {
1730 channels_used += (*i)->n_inputs().n_audio();
1736 vector<string> physinputs;
1737 vector<string> physoutputs;
1739 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1740 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1742 control_id = ntracks() + nbusses() + 1;
1746 /* check for duplicate route names, since we might have pre-existing
1747 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1748 save, close,restart,add new route - first named route is now
1756 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1758 if (route_by_name (track_name) == 0) {
1762 } while (track_id < (UINT_MAX-1));
1764 shared_ptr<AudioTrack> track;
1767 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1768 // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1769 track = boost::shared_ptr<AudioTrack>(at);
1771 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1772 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1773 input_channels, output_channels)
1778 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1779 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1780 input_channels, output_channels)
1785 if (!physinputs.empty()) {
1786 uint32_t nphysical_in = physinputs.size();
1788 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1792 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1793 port = physinputs[(channels_used+x)%nphysical_in];
1796 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1802 if (!physoutputs.empty()) {
1803 uint32_t nphysical_out = physoutputs.size();
1805 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1808 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1809 port = physoutputs[(channels_used+x)%nphysical_out];
1810 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1811 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1812 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1816 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1822 channels_used += track->n_inputs ().n_audio();
1824 track->set_route_group (route_group, 0);
1826 track->audio_diskstream()->non_realtime_input_change();
1828 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1829 track->set_remote_control_id (control_id);
1832 new_routes.push_back (track);
1833 ret.push_back (track);
1836 catch (failed_constructor &err) {
1837 error << _("Session: could not create new audio track.") << endmsg;
1840 /* we need to get rid of this, since the track failed to be created */
1841 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1844 RCUWriter<DiskstreamList> writer (diskstreams);
1845 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1846 ds->remove (track->audio_diskstream());
1853 catch (AudioEngine::PortRegistrationFailure& pfe) {
1855 error << pfe.what() << endmsg;
1858 /* we need to get rid of this, since the track failed to be created */
1859 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1862 RCUWriter<DiskstreamList> writer (diskstreams);
1863 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1864 ds->remove (track->audio_diskstream());
1875 if (!new_routes.empty()) {
1876 add_routes (new_routes, true);
1883 Session::set_remote_control_ids ()
1885 RemoteModel m = Config->get_remote_model();
1887 shared_ptr<RouteList> r = routes.reader ();
1889 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1890 if ( MixerOrdered == m) {
1891 long order = (*i)->order_key(N_("signal"));
1892 (*i)->set_remote_control_id( order+1 );
1893 } else if ( EditorOrdered == m) {
1894 long order = (*i)->order_key(N_("editor"));
1895 (*i)->set_remote_control_id( order+1 );
1896 } else if ( UserOrdered == m) {
1897 //do nothing ... only changes to remote id's are initiated by user
1904 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1907 uint32_t bus_id = 1;
1909 uint32_t channels_used = 0;
1912 uint32_t control_id;
1914 /* count existing audio busses */
1917 shared_ptr<RouteList> r = routes.reader ();
1919 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1920 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1922 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1925 channels_used += (*i)->n_inputs().n_audio();
1931 vector<string> physinputs;
1932 vector<string> physoutputs;
1934 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1935 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1937 n_physical_audio_outputs = physoutputs.size();
1938 n_physical_audio_inputs = physinputs.size();
1940 control_id = ntracks() + nbusses() + 1;
1945 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1949 if (route_by_name (bus_name) == 0) {
1953 } while (bus_id < (UINT_MAX-1));
1956 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1958 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1959 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1960 input_channels, output_channels)
1966 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1967 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1968 input_channels, output_channels)
1973 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1976 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1977 port = physinputs[((n+x)%n_physical_audio_inputs)];
1980 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1985 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1988 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1989 port = physoutputs[((n+x)%n_physical_outputs)];
1990 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1992 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1996 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
2001 channels_used += bus->n_inputs ().n_audio();
2003 bus->set_route_group (route_group, 0);
2004 bus->set_remote_control_id (control_id);
2008 bus->add_internal_return ();
2011 ret.push_back (bus);
2015 catch (failed_constructor &err) {
2016 error << _("Session: could not create new audio route.") << endmsg;
2020 catch (AudioEngine::PortRegistrationFailure& pfe) {
2021 error << pfe.what() << endmsg;
2031 add_routes (ret, true);
2039 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2043 uint32_t control_id;
2045 uint32_t number = 1;
2047 if (!tree.read (template_path.c_str())) {
2051 XMLNode* node = tree.root();
2053 control_id = ntracks() + nbusses() + 1;
2057 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2059 std::string node_name = IO::name_from_state (*node_copy.children().front());
2061 /* generate a new name by adding a number to the end of the template name */
2064 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2068 if (route_by_name (name) == 0) {
2072 } while (number < UINT_MAX);
2074 if (number == UINT_MAX) {
2075 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2079 IO::set_name_in_state (*node_copy.children().front(), name);
2081 Track::zero_diskstream_id_in_xml (node_copy);
2084 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2087 error << _("Session: cannot create track/bus from template description") << endmsg;
2091 if (boost::dynamic_pointer_cast<Track>(route)) {
2092 /* force input/output change signals so that the new diskstream
2093 picks up the configuration of the route. During session
2094 loading this normally happens in a different way.
2096 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2097 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2100 route->set_remote_control_id (control_id);
2103 ret.push_back (route);
2106 catch (failed_constructor &err) {
2107 error << _("Session: could not create new route from template") << endmsg;
2111 catch (AudioEngine::PortRegistrationFailure& pfe) {
2112 error << pfe.what() << endmsg;
2121 add_routes (ret, true);
2128 Session::add_routes (RouteList& new_routes, bool save)
2131 RCUWriter<RouteList> writer (routes);
2132 shared_ptr<RouteList> r = writer.get_copy ();
2133 r->insert (r->end(), new_routes.begin(), new_routes.end());
2136 /* if there is no control out and we're not in the middle of loading,
2137 resort the graph here. if there is a control out, we will resort
2138 toward the end of this method. if we are in the middle of loading,
2139 we will resort when done.
2142 if (!_control_out && IO::connecting_legal) {
2143 resort_routes_using (r);
2147 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2149 boost::weak_ptr<Route> wpr (*x);
2151 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2152 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2153 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2154 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2155 (*x)->processors_changed.connect (mem_fun (*this, &Session::route_processors_changed));
2156 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2158 if ((*x)->is_master()) {
2162 if ((*x)->is_control()) {
2163 _control_out = (*x);
2167 if (_control_out && IO::connecting_legal) {
2169 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2170 if ((*x)->is_control() || (*x)->is_master()) {
2173 (*x)->listen_via (_control_out,
2174 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2184 save_state (_current_snapshot_name);
2187 RouteAdded (new_routes); /* EMIT SIGNAL */
2191 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2193 boost::shared_ptr<RouteList> r = routes.reader ();
2194 boost::shared_ptr<Send> s;
2198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2199 if (boost::dynamic_pointer_cast<Track>(*i)) {
2200 if ((s = (*i)->internal_send_for (dest)) != 0) {
2201 s->amp()->gain_control()->set_value (0.0);
2208 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2210 boost::shared_ptr<RouteList> r = routes.reader ();
2211 boost::shared_ptr<Send> s;
2215 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2216 if (boost::dynamic_pointer_cast<Track>(*i)) {
2217 if ((s = (*i)->internal_send_for (dest)) != 0) {
2218 s->amp()->gain_control()->set_value (1.0);
2225 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2227 boost::shared_ptr<RouteList> r = routes.reader ();
2228 boost::shared_ptr<Send> s;
2232 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2233 if (boost::dynamic_pointer_cast<Track>(*i)) {
2234 if ((s = (*i)->internal_send_for (dest)) != 0) {
2235 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2242 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2244 boost::shared_ptr<RouteList> r = routes.reader ();
2245 boost::shared_ptr<RouteList> t (new RouteList);
2247 /* only send tracks */
2249 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2250 if (boost::dynamic_pointer_cast<Track>(*i)) {
2255 add_internal_sends (dest, p, t);
2259 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2261 if (dest->is_control() || dest->is_master()) {
2265 if (!dest->internal_return()) {
2266 dest->add_internal_return();
2269 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2271 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2275 (*i)->listen_via (dest, p, true, true);
2282 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2284 /* need to do this in case we're rolling at the time, to prevent false underruns */
2285 dstream->do_refill_with_alloc ();
2287 dstream->set_block_size (current_block_size);
2290 RCUWriter<DiskstreamList> writer (diskstreams);
2291 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2292 ds->push_back (dstream);
2293 /* writer goes out of scope, copies ds back to main */
2296 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2297 /* this will connect to future changes, and check the current length */
2298 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2300 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2302 dstream->prepare ();
2307 Session::remove_route (shared_ptr<Route> route)
2310 RCUWriter<RouteList> writer (routes);
2311 shared_ptr<RouteList> rs = writer.get_copy ();
2315 /* deleting the master out seems like a dumb
2316 idea, but its more of a UI policy issue
2320 if (route == _master_out) {
2321 _master_out = shared_ptr<Route> ();
2324 if (route == _control_out) {
2326 /* cancel control outs for all routes */
2328 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2329 (*r)->drop_listen (_control_out);
2332 _control_out.reset ();
2335 update_route_solo_state ();
2337 /* writer goes out of scope, forces route list update */
2340 boost::shared_ptr<Track> t;
2341 boost::shared_ptr<Diskstream> ds;
2343 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2344 ds = t->diskstream();
2350 RCUWriter<DiskstreamList> dsl (diskstreams);
2351 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2356 find_current_end ();
2358 // We need to disconnect the routes inputs and outputs
2360 route->input()->disconnect (0);
2361 route->output()->disconnect (0);
2363 /* if the route had internal sends sending to it, remove them */
2364 if (route->internal_return()) {
2366 boost::shared_ptr<RouteList> r = routes.reader ();
2367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2368 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2370 (*i)->remove_processor (s);
2375 update_latency_compensation (false, false);
2378 /* get rid of it from the dead wood collection in the route list manager */
2380 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2384 /* try to cause everyone to drop their references */
2386 route->drop_references ();
2388 sync_order_keys (N_("session"));
2390 /* save the new state of the world */
2392 if (save_state (_current_snapshot_name)) {
2393 save_history (_current_snapshot_name);
2398 Session::route_mute_changed (void* /*src*/)
2404 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2406 boost::shared_ptr<Route> route = wpr.lock();
2408 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2412 if (route->listening()) {
2414 } else if (_listen_cnt > 0) {
2420 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2422 if (solo_update_disabled) {
2427 boost::shared_ptr<Route> route = wpr.lock ();
2430 /* should not happen */
2431 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2435 shared_ptr<RouteList> r = routes.reader ();
2438 if (route->self_soloed()) {
2444 /* now mod the solo level of all other routes except master & control outs
2445 so that they will be silent if appropriate.
2448 solo_update_disabled = true;
2450 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2451 bool via_sends_only;
2454 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2456 } else if ((*i)->feeds (route, &via_sends_only)) {
2457 if (!via_sends_only) {
2458 (*i)->mod_solo_by_others (delta);
2463 /* make sure master is never muted by solo */
2465 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2466 _master_out->mod_solo_by_others (1);
2469 /* ditto for control outs make sure master is never muted by solo */
2471 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2472 _control_out->mod_solo_by_others (1);
2475 solo_update_disabled = false;
2476 update_route_solo_state (r);
2477 SoloChanged (); /* EMIT SIGNAL */
2482 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2484 /* now figure out if anything that matters is soloed */
2486 bool something_soloed = false;
2489 r = routes.reader();
2492 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2493 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2494 something_soloed = true;
2499 if (something_soloed != _non_soloed_outs_muted) {
2500 _non_soloed_outs_muted = something_soloed;
2501 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2505 boost::shared_ptr<RouteList>
2506 Session::get_routes_with_internal_returns() const
2508 shared_ptr<RouteList> r = routes.reader ();
2509 boost::shared_ptr<RouteList> rl (new RouteList);
2511 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2512 if ((*i)->internal_return ()) {
2520 Session::route_by_name (string name)
2522 shared_ptr<RouteList> r = routes.reader ();
2524 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2525 if ((*i)->name() == name) {
2530 return shared_ptr<Route> ((Route*) 0);
2534 Session::route_by_id (PBD::ID id)
2536 shared_ptr<RouteList> r = routes.reader ();
2538 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2539 if ((*i)->id() == id) {
2544 return shared_ptr<Route> ((Route*) 0);
2548 Session::route_by_remote_id (uint32_t id)
2550 shared_ptr<RouteList> r = routes.reader ();
2552 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2553 if ((*i)->remote_control_id() == id) {
2558 return shared_ptr<Route> ((Route*) 0);
2562 Session::find_current_end ()
2564 if (_state_of_the_state & Loading) {
2568 nframes_t max = get_maximum_extent ();
2570 if (max > end_location->end()) {
2571 end_location->set_end (max);
2573 DurationChanged(); /* EMIT SIGNAL */
2578 Session::get_maximum_extent () const
2583 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2585 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2586 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2588 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2589 if ((me = pl->get_maximum_extent()) > max) {
2597 boost::shared_ptr<Diskstream>
2598 Session::diskstream_by_name (string name)
2600 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2602 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2603 if ((*i)->name() == name) {
2608 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2611 boost::shared_ptr<Diskstream>
2612 Session::diskstream_by_id (const PBD::ID& id)
2614 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2616 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2617 if ((*i)->id() == id) {
2622 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2625 /* Region management */
2628 Session::new_region_name (string old)
2630 string::size_type last_period;
2632 string::size_type len = old.length() + 64;
2635 if ((last_period = old.find_last_of ('.')) == string::npos) {
2637 /* no period present - add one explicitly */
2640 last_period = old.length() - 1;
2645 number = atoi (old.substr (last_period+1).c_str());
2649 while (number < (UINT_MAX-1)) {
2651 RegionList::const_iterator i;
2656 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2659 for (i = regions.begin(); i != regions.end(); ++i) {
2660 if (i->second->name() == sbuf) {
2665 if (i == regions.end()) {
2670 if (number != (UINT_MAX-1)) {
2674 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2679 Session::region_name (string& result, string base, bool newlevel)
2684 if (base.find("/") != string::npos) {
2685 base = base.substr(base.find_last_of("/") + 1);
2690 Glib::Mutex::Lock lm (region_lock);
2692 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2701 string::size_type pos;
2703 pos = base.find_last_of ('.');
2705 /* pos may be npos, but then we just use entire base */
2707 subbase = base.substr (0, pos);
2712 Glib::Mutex::Lock lm (region_lock);
2714 map<string,uint32_t>::iterator x;
2718 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2720 region_name_map[subbase] = 1;
2723 snprintf (buf, sizeof (buf), ".%d", x->second);
2734 Session::add_region (boost::shared_ptr<Region> region)
2736 vector<boost::shared_ptr<Region> > v;
2737 v.push_back (region);
2742 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2747 Glib::Mutex::Lock lm (region_lock);
2749 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2751 boost::shared_ptr<Region> region = *ii;
2755 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2759 RegionList::iterator x;
2761 for (x = regions.begin(); x != regions.end(); ++x) {
2763 if (region->region_list_equivalent (x->second)) {
2768 if (x == regions.end()) {
2770 pair<RegionList::key_type,RegionList::mapped_type> entry;
2772 entry.first = region->id();
2773 entry.second = region;
2775 pair<RegionList::iterator,bool> x = regions.insert (entry);
2787 /* mark dirty because something has changed even if we didn't
2788 add the region to the region list.
2795 vector<boost::weak_ptr<Region> > v;
2796 boost::shared_ptr<Region> first_r;
2798 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2800 boost::shared_ptr<Region> region = *ii;
2804 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2807 v.push_back (region);
2814 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2815 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2817 update_region_name_map (region);
2821 RegionsAdded (v); /* EMIT SIGNAL */
2827 Session::update_region_name_map (boost::shared_ptr<Region> region)
2829 string::size_type last_period = region->name().find_last_of ('.');
2831 if (last_period != string::npos && last_period < region->name().length() - 1) {
2833 string base = region->name().substr (0, last_period);
2834 string number = region->name().substr (last_period+1);
2835 map<string,uint32_t>::iterator x;
2837 /* note that if there is no number, we get zero from atoi,
2841 region_name_map[base] = atoi (number);
2846 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2848 boost::shared_ptr<Region> region (weak_region.lock ());
2854 if (what_changed & Region::HiddenChanged) {
2855 /* relay hidden changes */
2856 RegionHiddenChange (region);
2859 if (what_changed & NameChanged) {
2860 update_region_name_map (region);
2865 Session::remove_region (boost::weak_ptr<Region> weak_region)
2867 RegionList::iterator i;
2868 boost::shared_ptr<Region> region (weak_region.lock ());
2874 bool removed = false;
2877 Glib::Mutex::Lock lm (region_lock);
2879 if ((i = regions.find (region->id())) != regions.end()) {
2885 /* mark dirty because something has changed even if we didn't
2886 remove the region from the region list.
2892 RegionRemoved(region); /* EMIT SIGNAL */
2896 boost::shared_ptr<Region>
2897 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2899 RegionList::iterator i;
2900 boost::shared_ptr<Region> region;
2902 Glib::Mutex::Lock lm (region_lock);
2904 for (i = regions.begin(); i != regions.end(); ++i) {
2908 if (region->whole_file()) {
2910 if (child->source_equivalent (region)) {
2916 return boost::shared_ptr<Region> ();
2920 Session::destroy_region (boost::shared_ptr<Region> region)
2922 vector<boost::shared_ptr<Source> > srcs;
2925 if (region->playlist()) {
2926 region->playlist()->destroy_region (region);
2929 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2930 srcs.push_back (region->source (n));
2934 region->drop_references ();
2936 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2938 (*i)->mark_for_remove ();
2939 (*i)->drop_references ();
2941 cerr << "source was not used by any playlist\n";
2948 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2950 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2951 destroy_region (*i);
2957 Session::remove_last_capture ()
2959 list<boost::shared_ptr<Region> > r;
2961 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2963 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2964 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2967 r.insert (r.end(), l.begin(), l.end());
2972 destroy_regions (r);
2974 save_state (_current_snapshot_name);
2980 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2986 /* Source Management */
2989 Session::add_source (boost::shared_ptr<Source> source)
2991 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2992 pair<SourceMap::iterator,bool> result;
2994 entry.first = source->id();
2995 entry.second = source;
2998 Glib::Mutex::Lock lm (source_lock);
2999 result = sources.insert (entry);
3002 if (result.second) {
3003 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3007 boost::shared_ptr<AudioFileSource> afs;
3009 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3010 if (Config->get_auto_analyse_audio()) {
3011 Analyser::queue_source_for_analysis (source, false);
3017 Session::remove_source (boost::weak_ptr<Source> src)
3019 SourceMap::iterator i;
3020 boost::shared_ptr<Source> source = src.lock();
3027 Glib::Mutex::Lock lm (source_lock);
3029 if ((i = sources.find (source->id())) != sources.end()) {
3034 if (!_state_of_the_state & InCleanup) {
3036 /* save state so we don't end up with a session file
3037 referring to non-existent sources.
3040 save_state (_current_snapshot_name);
3044 boost::shared_ptr<Source>
3045 Session::source_by_id (const PBD::ID& id)
3047 Glib::Mutex::Lock lm (source_lock);
3048 SourceMap::iterator i;
3049 boost::shared_ptr<Source> source;
3051 if ((i = sources.find (id)) != sources.end()) {
3058 boost::shared_ptr<Source>
3059 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3061 Glib::Mutex::Lock lm (source_lock);
3063 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3064 cerr << "comparing " << path << " with " << i->second->name() << endl;
3065 boost::shared_ptr<AudioFileSource> afs
3066 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3068 if (afs && afs->path() == path && chn == afs->channel()) {
3072 return boost::shared_ptr<Source>();
3077 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3080 string old_basename = PBD::basename_nosuffix (oldname);
3081 string new_legalized = legalize_for_path (newname);
3083 /* note: we know (or assume) the old path is already valid */
3087 /* destructive file sources have a name of the form:
3089 /path/to/Tnnnn-NAME(%[LR])?.wav
3091 the task here is to replace NAME with the new name.
3094 /* find last slash */
3098 string::size_type slash;
3099 string::size_type dash;
3101 if ((slash = path.find_last_of ('/')) == string::npos) {
3105 dir = path.substr (0, slash+1);
3107 /* '-' is not a legal character for the NAME part of the path */
3109 if ((dash = path.find_last_of ('-')) == string::npos) {
3113 prefix = path.substr (slash+1, dash-(slash+1));
3118 path += new_legalized;
3119 path += ".wav"; /* XXX gag me with a spoon */
3123 /* non-destructive file sources have a name of the form:
3125 /path/to/NAME-nnnnn(%[LR])?.ext
3127 the task here is to replace NAME with the new name.
3132 string::size_type slash;
3133 string::size_type dash;
3134 string::size_type postfix;
3136 /* find last slash */
3138 if ((slash = path.find_last_of ('/')) == string::npos) {
3142 dir = path.substr (0, slash+1);
3144 /* '-' is not a legal character for the NAME part of the path */
3146 if ((dash = path.find_last_of ('-')) == string::npos) {
3150 suffix = path.substr (dash+1);
3152 // Suffix is now everything after the dash. Now we need to eliminate
3153 // the nnnnn part, which is done by either finding a '%' or a '.'
3155 postfix = suffix.find_last_of ("%");
3156 if (postfix == string::npos) {
3157 postfix = suffix.find_last_of ('.');
3160 if (postfix != string::npos) {
3161 suffix = suffix.substr (postfix);
3163 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3167 const uint32_t limit = 10000;
3168 char buf[PATH_MAX+1];
3170 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3172 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3174 if (access (buf, F_OK) != 0) {
3182 error << "FATAL ERROR! Could not find a " << endl;
3190 /** Return the full path (in some session directory) for a new within-session source.
3191 * \a name must be a session-unique name that does not contain slashes
3192 * (e.g. as returned by new_*_source_name)
3195 Session::new_source_path_from_name (DataType type, const string& name)
3197 assert(name.find("/") == string::npos);
3199 SessionDirectory sdir(get_best_session_directory_for_new_source());
3202 if (type == DataType::AUDIO) {
3203 p = sdir.sound_path();
3204 } else if (type == DataType::MIDI) {
3205 p = sdir.midi_path();
3207 error << "Unknown source type, unable to create file path" << endmsg;
3212 return p.to_string();
3216 Session::peak_path (Glib::ustring base) const
3218 sys::path peakfile_path(_session_dir->peak_path());
3219 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3220 return peakfile_path.to_string();
3223 /** Return a unique name based on \a base for a new internal audio source */
3225 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3229 char buf[PATH_MAX+1];
3230 const uint32_t limit = 10000;
3234 legalized = legalize_for_path (base);
3236 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3237 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3239 vector<space_and_path>::iterator i;
3240 uint32_t existing = 0;
3242 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3244 SessionDirectory sdir((*i).path);
3246 spath = sdir.sound_path().to_string();
3251 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3252 spath.c_str(), cnt, legalized.c_str());
3253 } else if (nchan == 2) {
3255 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3256 spath.c_str(), cnt, legalized.c_str());
3258 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3259 spath.c_str(), cnt, legalized.c_str());
3261 } else if (nchan < 26) {
3262 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3263 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3265 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3266 spath.c_str(), cnt, legalized.c_str());
3275 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3276 } else if (nchan == 2) {
3278 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3280 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3282 } else if (nchan < 26) {
3283 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3285 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3289 if (sys::exists(buf)) {
3295 if (existing == 0) {
3300 error << string_compose(
3301 _("There are already %1 recordings for %2, which I consider too many."),
3302 limit, base) << endmsg;
3304 throw failed_constructor();
3308 return Glib::path_get_basename(buf);
3311 /** Create a new within-session audio source */
3312 boost::shared_ptr<AudioFileSource>
3313 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3315 const size_t n_chans = ds.n_channels().n_audio();
3316 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3317 const string path = new_source_path_from_name(DataType::AUDIO, name);
3319 return boost::dynamic_pointer_cast<AudioFileSource> (
3320 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3323 /** Return a unique name based on \a base for a new internal MIDI source */
3325 Session::new_midi_source_name (const string& base)
3328 char buf[PATH_MAX+1];
3329 const uint32_t limit = 10000;
3333 legalized = legalize_for_path (base);
3335 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3336 for (cnt = 1; cnt <= limit; ++cnt) {
3338 vector<space_and_path>::iterator i;
3339 uint32_t existing = 0;
3341 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3343 SessionDirectory sdir((*i).path);
3345 sys::path p = sdir.midi_path();
3348 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3350 if (sys::exists (buf)) {
3355 if (existing == 0) {
3360 error << string_compose(
3361 _("There are already %1 recordings for %2, which I consider too many."),
3362 limit, base) << endmsg;
3364 throw failed_constructor();
3368 return Glib::path_get_basename(buf);
3372 /** Create a new within-session MIDI source */
3373 boost::shared_ptr<MidiSource>
3374 Session::create_midi_source_for_session (MidiDiskstream& ds)
3376 const string name = new_midi_source_name (ds.name());
3377 const string path = new_source_path_from_name (DataType::MIDI, name);
3379 return boost::dynamic_pointer_cast<SMFSource> (
3380 SourceFactory::createWritable (
3381 DataType::MIDI, *this, path, false, frame_rate()));
3386 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3388 if (playlist->hidden()) {
3392 bool existing = playlists->add (playlist);
3394 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3398 playlist->release();
3405 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3407 if (_state_of_the_state & Deletion) {
3411 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3417 playlists->remove (playlist);
3423 Session::set_audition (boost::shared_ptr<Region> r)
3425 pending_audition_region = r;
3426 add_post_transport_work (PostTransportAudition);
3427 _butler->schedule_transport_work ();
3431 Session::audition_playlist ()
3433 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3434 ev->region.reset ();
3439 Session::non_realtime_set_audition ()
3441 if (!pending_audition_region) {
3442 auditioner->audition_current_playlist ();
3444 auditioner->audition_region (pending_audition_region);
3445 pending_audition_region.reset ();
3447 AuditionActive (true); /* EMIT SIGNAL */
3451 Session::audition_region (boost::shared_ptr<Region> r)
3453 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3459 Session::cancel_audition ()
3461 if (auditioner->active()) {
3462 auditioner->cancel_audition ();
3463 AuditionActive (false); /* EMIT SIGNAL */
3468 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3470 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3474 Session::remove_empty_sounds ()
3476 vector<string> audio_filenames;
3478 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3480 Glib::Mutex::Lock lm (source_lock);
3482 TapeFileMatcher tape_file_matcher;
3484 remove_if (audio_filenames.begin(), audio_filenames.end(),
3485 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3487 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3489 sys::path audio_file_path (_session_dir->sound_path());
3491 audio_file_path /= *i;
3493 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3497 sys::remove (audio_file_path);
3498 const string peakfile = peak_path (audio_file_path.to_string());
3499 sys::remove (peakfile);
3501 catch (const sys::filesystem_error& err)
3503 error << err.what() << endmsg;
3510 Session::is_auditioning () const
3512 /* can be called before we have an auditioner object */
3514 return auditioner->active();
3521 Session::set_all_solo (bool yn)
3523 shared_ptr<RouteList> r = routes.reader ();
3525 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3526 if (!(*i)->is_hidden()) {
3527 (*i)->set_solo (yn, this);
3535 Session::set_all_listen (bool yn)
3537 shared_ptr<RouteList> r = routes.reader ();
3539 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3540 if (!(*i)->is_hidden()) {
3541 (*i)->set_listen (yn, this);
3549 Session::set_all_mute (bool yn)
3551 shared_ptr<RouteList> r = routes.reader ();
3553 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3554 if (!(*i)->is_hidden()) {
3555 (*i)->set_mute (yn, this);
3563 Session::n_diskstreams () const
3567 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3569 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3570 if (!(*i)->hidden()) {
3578 Session::graph_reordered ()
3580 /* don't do this stuff if we are setting up connections
3581 from a set_state() call or creating new tracks. Ditto for deletion.
3584 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3588 /* every track/bus asked for this to be handled but it was deferred because
3589 we were connecting. do it now.
3592 request_input_change_handling ();
3596 /* force all diskstreams to update their capture offset values to
3597 reflect any changes in latencies within the graph.
3600 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3602 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3603 (*i)->set_capture_offset ();
3608 Session::set_all_record_enable (boost::shared_ptr<RouteList> rl, bool yn)
3614 for (RouteList::iterator i = rl->begin(); i != rl->end(); ) {
3615 boost::shared_ptr<Track> t;
3617 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3618 t->set_record_enable (yn, this);
3619 if (t->meter_point() == MeterCustom) {
3620 /* don't change metering for this track */
3634 Session::add_processor (Processor* processor)
3636 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3641 Session::remove_processor (Processor* processor)
3645 PortInsert* port_insert;
3647 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3648 insert_bitset[port_insert->bit_slot()] = false;
3649 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3650 send_bitset[send->bit_slot()] = false;
3651 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3652 return_bitset[retrn->bit_slot()] = false;
3659 Session::available_capture_duration ()
3661 float sample_bytes_on_disk = 4.0; // keep gcc happy
3663 switch (config.get_native_file_data_format()) {
3665 sample_bytes_on_disk = 4.0;
3669 sample_bytes_on_disk = 3.0;
3673 sample_bytes_on_disk = 2.0;
3677 /* impossible, but keep some gcc versions happy */
3678 fatal << string_compose (_("programming error: %1"),
3679 X_("illegal native file data format"))
3684 double scale = 4096.0 / sample_bytes_on_disk;
3686 if (_total_free_4k_blocks * scale > (double) max_frames) {
3690 return (nframes_t) floor (_total_free_4k_blocks * scale);
3694 Session::add_bundle (shared_ptr<Bundle> bundle)
3697 RCUWriter<BundleList> writer (_bundles);
3698 boost::shared_ptr<BundleList> b = writer.get_copy ();
3699 b->push_back (bundle);
3702 BundleAdded (bundle); /* EMIT SIGNAL */
3708 Session::remove_bundle (shared_ptr<Bundle> bundle)
3710 bool removed = false;
3713 RCUWriter<BundleList> writer (_bundles);
3714 boost::shared_ptr<BundleList> b = writer.get_copy ();
3715 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3717 if (i != b->end()) {
3724 BundleRemoved (bundle); /* EMIT SIGNAL */
3731 Session::bundle_by_name (string name) const
3733 boost::shared_ptr<BundleList> b = _bundles.reader ();
3735 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3736 if ((*i)->name() == name) {
3741 return boost::shared_ptr<Bundle> ();
3745 Session::tempo_map_changed (Change)
3749 playlists->update_after_tempo_map_change ();
3754 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3755 * the given count with the current block size.
3758 Session::ensure_buffers (ChanCount howmany)
3760 if (current_block_size == 0) {
3761 return; // too early? (is this ok?)
3764 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3765 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3766 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3767 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3768 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3771 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3775 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3777 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3778 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3783 Session::next_insert_id ()
3785 /* this doesn't really loop forever. just think about it */
3788 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3789 if (!insert_bitset[n]) {
3790 insert_bitset[n] = true;
3796 /* none available, so resize and try again */
3798 insert_bitset.resize (insert_bitset.size() + 16, false);
3803 Session::next_send_id ()
3805 /* this doesn't really loop forever. just think about it */
3808 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3809 if (!send_bitset[n]) {
3810 send_bitset[n] = true;
3816 /* none available, so resize and try again */
3818 send_bitset.resize (send_bitset.size() + 16, false);
3823 Session::next_return_id ()
3825 /* this doesn't really loop forever. just think about it */
3828 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3829 if (!return_bitset[n]) {
3830 return_bitset[n] = true;
3836 /* none available, so resize and try again */
3838 return_bitset.resize (return_bitset.size() + 16, false);
3843 Session::mark_send_id (uint32_t id)
3845 if (id >= send_bitset.size()) {
3846 send_bitset.resize (id+16, false);
3848 if (send_bitset[id]) {
3849 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3851 send_bitset[id] = true;
3855 Session::mark_return_id (uint32_t id)
3857 if (id >= return_bitset.size()) {
3858 return_bitset.resize (id+16, false);
3860 if (return_bitset[id]) {
3861 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3863 return_bitset[id] = true;
3867 Session::mark_insert_id (uint32_t id)
3869 if (id >= insert_bitset.size()) {
3870 insert_bitset.resize (id+16, false);
3872 if (insert_bitset[id]) {
3873 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3875 insert_bitset[id] = true;
3878 /* Named Selection management */
3881 Session::named_selection_by_name (string name)
3883 Glib::Mutex::Lock lm (named_selection_lock);
3884 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3885 if ((*i)->name == name) {
3893 Session::add_named_selection (NamedSelection* named_selection)
3896 Glib::Mutex::Lock lm (named_selection_lock);
3897 named_selections.insert (named_selections.begin(), named_selection);
3900 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3906 NamedSelectionAdded (); /* EMIT SIGNAL */
3910 Session::remove_named_selection (NamedSelection* named_selection)
3912 bool removed = false;
3915 Glib::Mutex::Lock lm (named_selection_lock);
3917 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3919 if (i != named_selections.end()) {
3921 named_selections.erase (i);
3928 NamedSelectionRemoved (); /* EMIT SIGNAL */
3933 Session::reset_native_file_format ()
3935 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3937 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3938 (*i)->reset_write_sources (false);
3943 Session::route_name_unique (string n) const
3945 shared_ptr<RouteList> r = routes.reader ();
3947 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3948 if ((*i)->name() == n) {
3957 Session::route_name_internal (string n) const
3959 if (auditioner && auditioner->name() == n) {
3963 if (_click_io && _click_io->name() == n) {
3971 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3973 if (!force && howmany <= _npan_buffers) {
3977 if (_pan_automation_buffer) {
3979 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3980 delete [] _pan_automation_buffer[i];
3983 delete [] _pan_automation_buffer;
3986 _pan_automation_buffer = new pan_t*[howmany];
3988 for (uint32_t i = 0; i < howmany; ++i) {
3989 _pan_automation_buffer[i] = new pan_t[nframes];
3992 _npan_buffers = howmany;
3996 Session::freeze (InterThreadInfo& itt)
3998 shared_ptr<RouteList> r = routes.reader ();
4000 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4002 boost::shared_ptr<Track> t;
4004 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4005 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4015 boost::shared_ptr<Region>
4016 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4017 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4018 InterThreadInfo& itt, bool enable_processing)
4020 boost::shared_ptr<Region> result;
4021 boost::shared_ptr<Playlist> playlist;
4022 boost::shared_ptr<AudioFileSource> fsource;
4024 char buf[PATH_MAX+1];
4025 ChanCount nchans(track.audio_diskstream()->n_channels());
4027 nframes_t this_chunk;
4030 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4031 const string sound_dir = sdir.sound_path().to_string();
4032 nframes_t len = end - start;
4035 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4036 end, start) << endmsg;
4040 // any bigger than this seems to cause stack overflows in called functions
4041 const nframes_t chunk_size = (128 * 1024)/4;
4043 // block all process callback handling
4045 block_processing ();
4047 /* call tree *MUST* hold route_lock */
4049 if ((playlist = track.diskstream()->playlist()) == 0) {
4053 /* external redirects will be a problem */
4055 if (track.has_external_redirects()) {
4059 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4061 for (x = 0; x < 99999; ++x) {
4062 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4063 if (access (buf, F_OK) != 0) {
4069 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4074 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4075 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4078 catch (failed_constructor& err) {
4079 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4083 srcs.push_back (fsource);
4086 /* XXX need to flush all redirects */
4091 /* create a set of reasonably-sized buffers */
4092 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4093 buffers.set_count(nchans);
4095 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4096 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4098 afs->prepare_for_peakfile_writes ();
4101 while (to_do && !itt.cancel) {
4103 this_chunk = min (to_do, chunk_size);
4105 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4110 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4111 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4114 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4120 start += this_chunk;
4121 to_do -= this_chunk;
4123 itt.progress = (float) (1.0 - ((double) to_do / len));
4132 xnow = localtime (&now);
4134 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4135 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4138 afs->update_header (position, *xnow, now);
4139 afs->flush_header ();
4143 /* construct a region to represent the bounced material */
4145 result = RegionFactory::create (srcs, 0,
4146 srcs.front()->length(srcs.front()->timeline_position()),
4147 region_name_from_path (srcs.front()->name(), true));
4152 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4153 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4156 afs->mark_for_remove ();
4159 (*src)->drop_references ();
4163 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4164 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4167 afs->done_with_peakfile_writes ();
4171 unblock_processing ();
4177 Session::get_silent_buffers (ChanCount count)
4179 assert(_silent_buffers->available() >= count);
4180 _silent_buffers->set_count(count);
4182 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4183 for (size_t i= 0; i < count.get(*t); ++i) {
4184 _silent_buffers->get(*t, i).clear();
4188 return *_silent_buffers;
4192 Session::get_scratch_buffers (ChanCount count)
4194 if (count != ChanCount::ZERO) {
4195 assert(_scratch_buffers->available() >= count);
4196 _scratch_buffers->set_count(count);
4198 _scratch_buffers->set_count (_scratch_buffers->available());
4201 return *_scratch_buffers;
4205 Session::get_mix_buffers (ChanCount count)
4207 assert(_mix_buffers->available() >= count);
4208 _mix_buffers->set_count(count);
4209 return *_mix_buffers;
4213 Session::ntracks () const
4216 shared_ptr<RouteList> r = routes.reader ();
4218 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4219 if (boost::dynamic_pointer_cast<Track> (*i)) {
4228 Session::nbusses () const
4231 shared_ptr<RouteList> r = routes.reader ();
4233 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4234 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4243 Session::add_automation_list(AutomationList *al)
4245 automation_lists[al->id()] = al;
4249 Session::compute_initial_length ()
4251 return _engine.frame_rate() * 60 * 5;
4255 Session::sync_order_keys (std::string const & base)
4257 if (!Config->get_sync_all_route_ordering()) {
4258 /* leave order keys as they are */
4262 boost::shared_ptr<RouteList> r = routes.reader ();
4264 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4265 (*i)->sync_order_keys (base);
4268 Route::SyncOrderKeys (base); // EMIT SIGNAL
4272 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4274 Session::have_rec_enabled_diskstream () const
4276 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4279 /** Update the state of our rec-enabled diskstreams flag */
4281 Session::update_have_rec_enabled_diskstream ()
4283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4284 DiskstreamList::iterator i = dsl->begin ();
4285 while (i != dsl->end () && (*i)->record_enabled () == false) {
4289 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4291 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4293 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4294 RecordStateChanged (); /* EMIT SIGNAL */
4299 Session::listen_position_changed ()
4303 switch (Config->get_listen_position()) {
4304 case AfterFaderListen:
4308 case PreFaderListen:
4313 boost::shared_ptr<RouteList> r = routes.reader ();
4315 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4316 (*i)->put_control_outs_at (p);
4321 Session::solo_control_mode_changed ()
4323 /* cancel all solo or all listen when solo control mode changes */
4325 if (Config->get_solo_control_is_listen_control()) {
4326 set_all_solo (false);
4328 set_all_listen (false);
4333 Session::route_group_changed ()
4335 RouteGroupChanged (); /* EMIT SIGNAL */
4339 Session::get_available_sync_options () const
4341 vector<SyncSource> ret;
4343 ret.push_back (JACK);
4346 ret.push_back (MTC);
4349 if (midi_clock_port()) {
4350 ret.push_back (MIDIClock);
4356 boost::shared_ptr<RouteList>
4357 Session::get_routes_with_regions_at (nframes64_t const p) const
4359 shared_ptr<RouteList> r = routes.reader ();
4360 shared_ptr<RouteList> rl (new RouteList);
4362 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4363 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4368 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4373 boost::shared_ptr<Playlist> pl = ds->playlist ();
4378 if (pl->has_region_at (p)) {