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::record_disenable_all (sigc::slot<void,SessionEvent*> callback)
3614 record_enable_change_all (false, callback);
3618 Session::record_enable_all (sigc::slot<void,SessionEvent*> callback)
3624 record_enable_change_all (true, callback);
3628 Session::record_enable_change_all (bool yn, sigc::slot<void,SessionEvent*> callback)
3630 shared_ptr<RouteList> r = routes.reader ();
3631 RouteList* tracks = new RouteList;
3633 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3634 boost::shared_ptr<Track> t;
3636 if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
3637 tracks->push_back (*i);
3641 sigc::slot<void> rt_op = bind (sigc::mem_fun (*this, &Session::do_record_enable_change_all), tracks, yn);
3643 SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3645 ev->routes = tracks; // set here so that callback can delete it
3646 ev->rt_slot = rt_op;
3647 ev->rt_return = callback;
3653 Session::do_record_enable_change_all (RouteList* rl, bool yn)
3655 for (RouteList::iterator i = rl->begin(); i != rl->end(); ) {
3656 boost::shared_ptr<Track> t;
3658 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3659 t->set_record_enable (yn, this);
3660 if (t->meter_point() == MeterCustom) {
3661 /* don't change metering for this track */
3673 Session::add_processor (Processor* processor)
3675 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3680 Session::remove_processor (Processor* processor)
3684 PortInsert* port_insert;
3686 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3687 insert_bitset[port_insert->bit_slot()] = false;
3688 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3689 send_bitset[send->bit_slot()] = false;
3690 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3691 return_bitset[retrn->bit_slot()] = false;
3698 Session::available_capture_duration ()
3700 float sample_bytes_on_disk = 4.0; // keep gcc happy
3702 switch (config.get_native_file_data_format()) {
3704 sample_bytes_on_disk = 4.0;
3708 sample_bytes_on_disk = 3.0;
3712 sample_bytes_on_disk = 2.0;
3716 /* impossible, but keep some gcc versions happy */
3717 fatal << string_compose (_("programming error: %1"),
3718 X_("illegal native file data format"))
3723 double scale = 4096.0 / sample_bytes_on_disk;
3725 if (_total_free_4k_blocks * scale > (double) max_frames) {
3729 return (nframes_t) floor (_total_free_4k_blocks * scale);
3733 Session::add_bundle (shared_ptr<Bundle> bundle)
3736 RCUWriter<BundleList> writer (_bundles);
3737 boost::shared_ptr<BundleList> b = writer.get_copy ();
3738 b->push_back (bundle);
3741 BundleAdded (bundle); /* EMIT SIGNAL */
3747 Session::remove_bundle (shared_ptr<Bundle> bundle)
3749 bool removed = false;
3752 RCUWriter<BundleList> writer (_bundles);
3753 boost::shared_ptr<BundleList> b = writer.get_copy ();
3754 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3756 if (i != b->end()) {
3763 BundleRemoved (bundle); /* EMIT SIGNAL */
3770 Session::bundle_by_name (string name) const
3772 boost::shared_ptr<BundleList> b = _bundles.reader ();
3774 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3775 if ((*i)->name() == name) {
3780 return boost::shared_ptr<Bundle> ();
3784 Session::tempo_map_changed (Change)
3788 playlists->update_after_tempo_map_change ();
3793 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3794 * the given count with the current block size.
3797 Session::ensure_buffers (ChanCount howmany)
3799 if (current_block_size == 0) {
3800 return; // too early? (is this ok?)
3803 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3804 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3805 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3806 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3807 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3810 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3814 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3816 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3817 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3822 Session::next_insert_id ()
3824 /* this doesn't really loop forever. just think about it */
3827 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3828 if (!insert_bitset[n]) {
3829 insert_bitset[n] = true;
3835 /* none available, so resize and try again */
3837 insert_bitset.resize (insert_bitset.size() + 16, false);
3842 Session::next_send_id ()
3844 /* this doesn't really loop forever. just think about it */
3847 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3848 if (!send_bitset[n]) {
3849 send_bitset[n] = true;
3855 /* none available, so resize and try again */
3857 send_bitset.resize (send_bitset.size() + 16, false);
3862 Session::next_return_id ()
3864 /* this doesn't really loop forever. just think about it */
3867 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3868 if (!return_bitset[n]) {
3869 return_bitset[n] = true;
3875 /* none available, so resize and try again */
3877 return_bitset.resize (return_bitset.size() + 16, false);
3882 Session::mark_send_id (uint32_t id)
3884 if (id >= send_bitset.size()) {
3885 send_bitset.resize (id+16, false);
3887 if (send_bitset[id]) {
3888 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3890 send_bitset[id] = true;
3894 Session::mark_return_id (uint32_t id)
3896 if (id >= return_bitset.size()) {
3897 return_bitset.resize (id+16, false);
3899 if (return_bitset[id]) {
3900 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3902 return_bitset[id] = true;
3906 Session::mark_insert_id (uint32_t id)
3908 if (id >= insert_bitset.size()) {
3909 insert_bitset.resize (id+16, false);
3911 if (insert_bitset[id]) {
3912 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3914 insert_bitset[id] = true;
3917 /* Named Selection management */
3920 Session::named_selection_by_name (string name)
3922 Glib::Mutex::Lock lm (named_selection_lock);
3923 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3924 if ((*i)->name == name) {
3932 Session::add_named_selection (NamedSelection* named_selection)
3935 Glib::Mutex::Lock lm (named_selection_lock);
3936 named_selections.insert (named_selections.begin(), named_selection);
3939 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3945 NamedSelectionAdded (); /* EMIT SIGNAL */
3949 Session::remove_named_selection (NamedSelection* named_selection)
3951 bool removed = false;
3954 Glib::Mutex::Lock lm (named_selection_lock);
3956 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3958 if (i != named_selections.end()) {
3960 named_selections.erase (i);
3967 NamedSelectionRemoved (); /* EMIT SIGNAL */
3972 Session::reset_native_file_format ()
3974 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3976 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3977 (*i)->reset_write_sources (false);
3982 Session::route_name_unique (string n) const
3984 shared_ptr<RouteList> r = routes.reader ();
3986 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3987 if ((*i)->name() == n) {
3996 Session::route_name_internal (string n) const
3998 if (auditioner && auditioner->name() == n) {
4002 if (_click_io && _click_io->name() == n) {
4010 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4012 if (!force && howmany <= _npan_buffers) {
4016 if (_pan_automation_buffer) {
4018 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4019 delete [] _pan_automation_buffer[i];
4022 delete [] _pan_automation_buffer;
4025 _pan_automation_buffer = new pan_t*[howmany];
4027 for (uint32_t i = 0; i < howmany; ++i) {
4028 _pan_automation_buffer[i] = new pan_t[nframes];
4031 _npan_buffers = howmany;
4035 Session::freeze (InterThreadInfo& itt)
4037 shared_ptr<RouteList> r = routes.reader ();
4039 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4041 boost::shared_ptr<Track> t;
4043 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4044 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4054 boost::shared_ptr<Region>
4055 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4056 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4057 InterThreadInfo& itt, bool enable_processing)
4059 boost::shared_ptr<Region> result;
4060 boost::shared_ptr<Playlist> playlist;
4061 boost::shared_ptr<AudioFileSource> fsource;
4063 char buf[PATH_MAX+1];
4064 ChanCount nchans(track.audio_diskstream()->n_channels());
4066 nframes_t this_chunk;
4069 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4070 const string sound_dir = sdir.sound_path().to_string();
4071 nframes_t len = end - start;
4074 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4075 end, start) << endmsg;
4079 // any bigger than this seems to cause stack overflows in called functions
4080 const nframes_t chunk_size = (128 * 1024)/4;
4082 // block all process callback handling
4084 block_processing ();
4086 /* call tree *MUST* hold route_lock */
4088 if ((playlist = track.diskstream()->playlist()) == 0) {
4092 /* external redirects will be a problem */
4094 if (track.has_external_redirects()) {
4098 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4100 for (x = 0; x < 99999; ++x) {
4101 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4102 if (access (buf, F_OK) != 0) {
4108 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4113 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4114 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4117 catch (failed_constructor& err) {
4118 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4122 srcs.push_back (fsource);
4125 /* XXX need to flush all redirects */
4130 /* create a set of reasonably-sized buffers */
4131 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4132 buffers.set_count(nchans);
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);
4137 afs->prepare_for_peakfile_writes ();
4140 while (to_do && !itt.cancel) {
4142 this_chunk = min (to_do, chunk_size);
4144 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4149 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4150 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4153 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4159 start += this_chunk;
4160 to_do -= this_chunk;
4162 itt.progress = (float) (1.0 - ((double) to_do / len));
4171 xnow = localtime (&now);
4173 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4174 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4177 afs->update_header (position, *xnow, now);
4178 afs->flush_header ();
4182 /* construct a region to represent the bounced material */
4184 result = RegionFactory::create (srcs, 0,
4185 srcs.front()->length(srcs.front()->timeline_position()),
4186 region_name_from_path (srcs.front()->name(), true));
4191 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4192 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4195 afs->mark_for_remove ();
4198 (*src)->drop_references ();
4202 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4203 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4206 afs->done_with_peakfile_writes ();
4210 unblock_processing ();
4216 Session::get_silent_buffers (ChanCount count)
4218 assert(_silent_buffers->available() >= count);
4219 _silent_buffers->set_count(count);
4221 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4222 for (size_t i= 0; i < count.get(*t); ++i) {
4223 _silent_buffers->get(*t, i).clear();
4227 return *_silent_buffers;
4231 Session::get_scratch_buffers (ChanCount count)
4233 if (count != ChanCount::ZERO) {
4234 assert(_scratch_buffers->available() >= count);
4235 _scratch_buffers->set_count(count);
4237 _scratch_buffers->set_count (_scratch_buffers->available());
4240 return *_scratch_buffers;
4244 Session::get_mix_buffers (ChanCount count)
4246 assert(_mix_buffers->available() >= count);
4247 _mix_buffers->set_count(count);
4248 return *_mix_buffers;
4252 Session::ntracks () const
4255 shared_ptr<RouteList> r = routes.reader ();
4257 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4258 if (boost::dynamic_pointer_cast<Track> (*i)) {
4267 Session::nbusses () const
4270 shared_ptr<RouteList> r = routes.reader ();
4272 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4273 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4282 Session::add_automation_list(AutomationList *al)
4284 automation_lists[al->id()] = al;
4288 Session::compute_initial_length ()
4290 return _engine.frame_rate() * 60 * 5;
4294 Session::sync_order_keys (std::string const & base)
4296 if (!Config->get_sync_all_route_ordering()) {
4297 /* leave order keys as they are */
4301 boost::shared_ptr<RouteList> r = routes.reader ();
4303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4304 (*i)->sync_order_keys (base);
4307 Route::SyncOrderKeys (base); // EMIT SIGNAL
4311 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4313 Session::have_rec_enabled_diskstream () const
4315 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4318 /** Update the state of our rec-enabled diskstreams flag */
4320 Session::update_have_rec_enabled_diskstream ()
4322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4323 DiskstreamList::iterator i = dsl->begin ();
4324 while (i != dsl->end () && (*i)->record_enabled () == false) {
4328 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4330 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4332 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4333 RecordStateChanged (); /* EMIT SIGNAL */
4338 Session::listen_position_changed ()
4342 switch (Config->get_listen_position()) {
4343 case AfterFaderListen:
4347 case PreFaderListen:
4352 boost::shared_ptr<RouteList> r = routes.reader ();
4354 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4355 (*i)->put_control_outs_at (p);
4360 Session::solo_control_mode_changed ()
4362 /* cancel all solo or all listen when solo control mode changes */
4364 if (Config->get_solo_control_is_listen_control()) {
4365 set_all_solo (false);
4367 set_all_listen (false);
4372 Session::route_group_changed ()
4374 RouteGroupChanged (); /* EMIT SIGNAL */
4378 Session::get_available_sync_options () const
4380 vector<SyncSource> ret;
4382 ret.push_back (JACK);
4385 ret.push_back (MTC);
4388 if (midi_clock_port()) {
4389 ret.push_back (MIDIClock);
4395 boost::shared_ptr<RouteList>
4396 Session::get_routes_with_regions_at (nframes64_t const p) const
4398 shared_ptr<RouteList> r = routes.reader ();
4399 shared_ptr<RouteList> rl (new RouteList);
4401 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4402 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4407 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4412 boost::shared_ptr<Playlist> pl = ds->playlist ();
4417 if (pl->has_region_at (p)) {