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/slave.h"
90 #include "ardour/smf_source.h"
91 #include "ardour/source_factory.h"
92 #include "ardour/tape_file_matcher.h"
93 #include "ardour/tempo.h"
94 #include "ardour/utils.h"
99 using namespace ARDOUR;
101 using boost::shared_ptr;
102 using boost::weak_ptr;
104 bool Session::_disable_all_loaded_plugins = false;
106 sigc::signal<void,std::string> Session::Dialog;
107 sigc::signal<int> Session::AskAboutPendingState;
108 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
109 sigc::signal<void> Session::SendFeedback;
111 sigc::signal<void> Session::TimecodeOffsetChanged;
112 sigc::signal<void> Session::StartTimeChanged;
113 sigc::signal<void> Session::EndTimeChanged;
114 sigc::signal<void> Session::AutoBindingOn;
115 sigc::signal<void> Session::AutoBindingOff;
116 sigc::signal<void, std::string, std::string> Session::Exported;
118 Session::Session (AudioEngine &eng,
119 const string& fullpath,
120 const string& snapshot_name,
124 _target_transport_speed (0.0),
125 _requested_return_frame (-1),
126 _scratch_buffers(new BufferSet()),
127 _silent_buffers(new BufferSet()),
128 _mix_buffers(new BufferSet()),
130 _mmc_port (default_mmc_port),
131 _mtc_port (default_mtc_port),
132 _midi_port (default_midi_port),
133 _midi_clock_port (default_midi_clock_port),
134 _session_dir (new SessionDirectory(fullpath)),
135 pending_events (2048),
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)
157 interpolation.add_channel_to (0, 0);
159 if (!eng.connected()) {
160 throw failed_constructor();
163 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
165 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
166 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
168 first_stage_init (fullpath, snapshot_name);
170 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
173 if (create (new_session, mix_template, compute_initial_length())) {
175 throw failed_constructor ();
179 if (second_stage_init (new_session)) {
181 throw failed_constructor ();
184 store_recent_sessions(_name, _path);
186 bool was_dirty = dirty();
188 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
190 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
191 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
194 DirtyChanged (); /* EMIT SIGNAL */
198 Session::Session (AudioEngine &eng,
200 string snapshot_name,
201 AutoConnectOption input_ac,
202 AutoConnectOption output_ac,
203 uint32_t control_out_channels,
204 uint32_t master_out_channels,
205 uint32_t requested_physical_in,
206 uint32_t requested_physical_out,
207 nframes_t initial_length)
210 _target_transport_speed (0.0),
211 _requested_return_frame (-1),
212 _scratch_buffers(new BufferSet()),
213 _silent_buffers(new BufferSet()),
214 _mix_buffers(new BufferSet()),
216 _mmc_port (default_mmc_port),
217 _mtc_port (default_mtc_port),
218 _midi_port (default_midi_port),
219 _midi_clock_port (default_midi_clock_port),
220 _session_dir ( new SessionDirectory(fullpath)),
221 pending_events (2048),
223 _butler (new Butler (this)),
224 _post_transport_work (0),
225 _send_timecode_update (false),
226 midi_thread (pthread_t (0)),
228 diskstreams (new DiskstreamList),
229 routes (new RouteList),
230 _total_free_4k_blocks (0),
231 _bundles (new BundleList),
232 _bundle_xml_node (0),
233 _click_io ((IO *) 0),
235 click_emphasis_data (0),
237 _metadata (new SessionMetadata()),
238 _have_rec_enabled_diskstream (false)
242 interpolation.add_channel_to (0, 0);
244 if (!eng.connected()) {
245 throw failed_constructor();
248 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
250 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
251 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
253 if (n_physical_inputs) {
254 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
257 if (n_physical_outputs) {
258 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
261 first_stage_init (fullpath, snapshot_name);
263 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
266 if (create (new_session, string(), initial_length)) {
268 throw failed_constructor ();
273 /* set up Master Out and Control Out if necessary */
278 if (master_out_channels) {
279 ChanCount count(DataType::AUDIO, master_out_channels);
280 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
281 r->input()->ensure_io (count, false, this);
282 r->output()->ensure_io (count, false, this);
283 r->set_remote_control_id (control_id);
287 /* prohibit auto-connect to master, because there isn't one */
288 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
291 if (control_out_channels) {
292 ChanCount count(DataType::AUDIO, control_out_channels);
293 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
294 r->input()->ensure_io (count, false, this);
295 r->output()->ensure_io (count, false, this);
296 r->set_remote_control_id (control_id++);
302 add_routes (rl, false);
307 if (no_auto_connect()) {
308 input_ac = AutoConnectOption (0);
309 output_ac = AutoConnectOption (0);
312 Config->set_input_auto_connect (input_ac);
313 Config->set_output_auto_connect (output_ac);
315 if (second_stage_init (new_session)) {
317 throw failed_constructor ();
320 store_recent_sessions (_name, _path);
322 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
324 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
335 vector<void*> debug_pointers;
337 /* if we got to here, leaving pending capture state around
341 remove_pending_capture_state ();
343 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
345 _engine.remove_session ();
347 GoingAway (); /* EMIT SIGNAL */
353 /* clear history so that no references to objects are held any more */
357 /* clear state tree so that no references to objects are held any more */
361 /* reset dynamic state version back to default */
363 Stateful::loading_state_version = 0;
365 _butler->terminate_thread ();
366 //terminate_midi_thread ();
368 if (click_data != default_click) {
369 delete [] click_data;
372 if (click_emphasis_data != default_click_emphasis) {
373 delete [] click_emphasis_data;
378 delete _scratch_buffers;
379 delete _silent_buffers;
382 /* clear out any pending dead wood from RCU managed objects */
385 diskstreams.flush ();
388 AudioDiskstream::free_working_buffers();
390 Route::SyncOrderKeys.clear();
392 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
393 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
394 NamedSelectionList::iterator tmp;
403 DEBUG_TRACE (DEBUG::Destruction, "delete used playlists\n");
404 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
405 PlaylistList::iterator tmp;
410 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
411 (*i)->drop_references ();
417 DEBUG_TRACE (DEBUG::Destruction, "delete unused playlists\n");
418 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
419 PlaylistList::iterator tmp;
424 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
425 (*i)->drop_references ();
431 unused_playlists.clear ();
433 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
434 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
435 RegionList::iterator tmp;
440 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()));
441 i->second->drop_references ();
442 DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count()));
448 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
450 /* reset these three references to special routes before we do the usual route delete thing */
453 _master_out.reset ();
454 _control_out.reset ();
457 RCUWriter<RouteList> writer (routes);
458 boost::shared_ptr<RouteList> r = writer.get_copy ();
459 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
460 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
461 (*i)->drop_references ();
464 /* writer goes out of scope and updates master */
468 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
470 RCUWriter<DiskstreamList> dwriter (diskstreams);
471 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
472 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
473 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
474 (*i)->drop_references ();
478 diskstreams.flush ();
480 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
481 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
482 SourceMap::iterator tmp;
487 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
488 i->second->drop_references ();
496 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
497 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
501 Crossfade::set_buffer_size (0);
505 boost_debug_list_ptrs ();
507 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
511 Session::set_worst_io_latencies ()
513 _worst_output_latency = 0;
514 _worst_input_latency = 0;
516 if (!_engine.connected()) {
520 boost::shared_ptr<RouteList> r = routes.reader ();
522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
523 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
524 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
529 Session::when_engine_running ()
531 string first_physical_output;
533 BootMessage (_("Set block size and sample rate"));
535 set_block_size (_engine.frames_per_cycle());
536 set_frame_rate (_engine.frame_rate());
538 BootMessage (_("Using configuration"));
540 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
542 /* every time we reconnect, recompute worst case output latencies */
544 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
546 if (synced_to_jack()) {
547 _engine.transport_stop ();
550 if (config.get_jack_time_master()) {
551 _engine.transport_locate (_transport_frame);
559 _click_io.reset (new ClickIO (*this, "click"));
561 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
563 /* existing state for Click */
566 if (Stateful::loading_state_version < 3000) {
567 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
569 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
574 _clicking = Config->get_clicking ();
578 error << _("could not setup Click I/O") << endmsg;
585 /* default state for Click: dual-mono to first 2 physical outputs */
587 for (int physport = 0; physport < 2; ++physport) {
588 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
590 if (physical_output.length()) {
591 if (_click_io->add_port (physical_output, this)) {
592 // relax, even though its an error
597 if (_click_io->n_ports () > ChanCount::ZERO) {
598 _clicking = Config->get_clicking ();
603 catch (failed_constructor& err) {
604 error << _("cannot setup Click I/O") << endmsg;
607 BootMessage (_("Compute I/O Latencies"));
609 set_worst_io_latencies ();
612 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
615 BootMessage (_("Set up standard connections"));
617 /* Create a set of Bundle objects that map
618 to the physical I/O currently available. We create both
619 mono and stereo bundles, so that the common cases of mono
620 and stereo tracks get bundles to put in their mixer strip
621 in / out menus. There may be a nicer way of achieving that;
622 it doesn't really scale that well to higher channel counts
625 /* mono output bundles */
627 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
629 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
631 shared_ptr<Bundle> c (new Bundle (buf, true));
632 c->add_channel (_("mono"));
633 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
638 /* stereo output bundles */
640 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
641 if (np + 1 < n_physical_outputs) {
643 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
644 shared_ptr<Bundle> c (new Bundle (buf, true));
645 c->add_channel (_("L"));
646 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
647 c->add_channel (_("R"));
648 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
654 /* mono input bundles */
656 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
658 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
660 shared_ptr<Bundle> c (new Bundle (buf, false));
661 c->add_channel (_("mono"));
662 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
667 /* stereo input bundles */
669 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
670 if (np + 1 < n_physical_inputs) {
672 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
674 shared_ptr<Bundle> c (new Bundle (buf, false));
675 c->add_channel (_("L"));
676 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
677 c->add_channel (_("R"));
678 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
684 BootMessage (_("Setup signal flow and plugins"));
688 if (!no_auto_connect()) {
690 if (_master_out && Config->get_auto_connect_standard_busses()) {
692 /* if requested auto-connect the outputs to the first N physical ports.
695 uint32_t limit = _master_out->n_outputs().n_total();
697 for (uint32_t n = 0; n < limit; ++n) {
698 Port* p = _master_out->output()->nth (n);
699 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
701 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
702 if (_master_out->output()->connect (p, connect_to, this)) {
703 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
713 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
714 are undefined, at best.
717 /* control out listens to master bus (but ignores it
718 under some conditions)
721 uint32_t limit = _control_out->n_inputs().n_audio();
724 for (uint32_t n = 0; n < limit; ++n) {
725 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
726 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
729 string connect_to = o->name();
730 if (_control_out->input()->connect (p, connect_to, this)) {
731 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
739 /* if control out is not connected,
740 connect control out to physical outs, but use ones after the master if possible
743 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
745 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
747 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
750 _control_out->output()->connect_ports_to_bundle (b, this);
752 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
753 Config->get_monitor_bus_preferred_bundle())
759 /* XXX this logic is wrong for mixed port types */
761 uint32_t shift = _master_out->n_outputs().n_audio();
762 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
763 limit = _control_out->n_outputs().n_audio();
765 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
767 for (uint32_t n = 0; n < limit; ++n) {
769 Port* p = _control_out->output()->nth (n);
770 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
772 if (!connect_to.empty()) {
773 if (_control_out->output()->connect (p, connect_to, this)) {
774 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
785 /* catch up on send+insert cnts */
787 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
789 /* hook us up to the engine */
791 BootMessage (_("Connect to engine"));
793 _engine.set_session (this);
797 Session::hookup_io ()
799 /* stop graph reordering notifications from
800 causing resorts, etc.
803 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
808 /* we delay creating the auditioner till now because
809 it makes its own connections to ports.
810 the engine has to be running for this to work.
814 auditioner.reset (new Auditioner (*this));
817 catch (failed_constructor& err) {
818 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
822 /* load bundles, which we may have postponed earlier on */
823 if (_bundle_xml_node) {
824 load_bundles (*_bundle_xml_node);
825 delete _bundle_xml_node;
828 /* Tell all IO objects to connect themselves together */
830 IO::enable_connecting ();
832 /* Now reset all panners */
834 Delivery::reset_panners ();
836 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
840 boost::shared_ptr<RouteList> r = routes.reader ();
842 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
844 if ((*x)->is_control() || (*x)->is_master()) {
848 (*x)->listen_via (_control_out,
849 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
854 /* Anyone who cares about input state, wake up and do something */
856 IOConnectionsComplete (); /* EMIT SIGNAL */
858 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
860 /* now handle the whole enchilada as if it was one
866 /* update the full solo state, which can't be
867 correctly determined on a per-route basis, but
868 needs the global overview that only the session
872 update_route_solo_state ();
876 Session::playlist_length_changed ()
878 /* we can't just increase end_location->end() if pl->get_maximum_extent()
879 if larger. if the playlist used to be the longest playlist,
880 and its now shorter, we have to decrease end_location->end(). hence,
881 we have to iterate over all diskstreams and check the
882 playlists currently in use.
888 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
890 boost::shared_ptr<Diskstream> dstream = wp.lock ();
895 boost::shared_ptr<Playlist> playlist;
897 if ((playlist = dstream->playlist()) != 0) {
898 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
901 /* see comment in playlist_length_changed () */
906 Session::record_enabling_legal () const
908 /* this used to be in here, but survey says.... we don't need to restrict it */
909 // if (record_status() == Recording) {
913 if (Config->get_all_safe()) {
920 Session::reset_input_monitor_state ()
922 if (transport_rolling()) {
924 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
926 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
927 if ((*i)->record_enabled ()) {
928 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
929 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
933 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
935 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
936 if ((*i)->record_enabled ()) {
937 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
938 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
945 Session::auto_punch_start_changed (Location* location)
947 replace_event (Event::PunchIn, location->start());
949 if (get_record_enabled() && config.get_punch_in()) {
950 /* capture start has been changed, so save new pending state */
951 save_state ("", true);
956 Session::auto_punch_end_changed (Location* location)
958 nframes_t when_to_stop = location->end();
959 // when_to_stop += _worst_output_latency + _worst_input_latency;
960 replace_event (Event::PunchOut, when_to_stop);
964 Session::auto_punch_changed (Location* location)
966 nframes_t when_to_stop = location->end();
968 replace_event (Event::PunchIn, location->start());
969 //when_to_stop += _worst_output_latency + _worst_input_latency;
970 replace_event (Event::PunchOut, when_to_stop);
974 Session::auto_loop_changed (Location* location)
976 replace_event (Event::AutoLoop, location->end(), location->start());
978 if (transport_rolling() && play_loop) {
981 // if (_transport_frame > location->end()) {
983 if (_transport_frame < location->start() || _transport_frame > location->end()) {
984 // relocate to beginning of loop
985 clear_events (Event::LocateRoll);
987 request_locate (location->start(), true);
990 else if (Config->get_seamless_loop() && !loop_changing) {
992 // schedule a locate-roll to refill the diskstreams at the
994 loop_changing = true;
996 if (location->end() > last_loopend) {
997 clear_events (Event::LocateRoll);
998 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1005 last_loopend = location->end();
1009 Session::set_auto_punch_location (Location* location)
1013 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1014 auto_punch_start_changed_connection.disconnect();
1015 auto_punch_end_changed_connection.disconnect();
1016 auto_punch_changed_connection.disconnect();
1017 existing->set_auto_punch (false, this);
1018 remove_event (existing->start(), Event::PunchIn);
1019 clear_events (Event::PunchOut);
1020 auto_punch_location_changed (0);
1025 if (location == 0) {
1029 if (location->end() <= location->start()) {
1030 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1034 auto_punch_start_changed_connection.disconnect();
1035 auto_punch_end_changed_connection.disconnect();
1036 auto_punch_changed_connection.disconnect();
1038 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1039 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1040 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1042 location->set_auto_punch (true, this);
1045 auto_punch_changed (location);
1047 auto_punch_location_changed (location);
1051 Session::set_auto_loop_location (Location* location)
1055 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1056 auto_loop_start_changed_connection.disconnect();
1057 auto_loop_end_changed_connection.disconnect();
1058 auto_loop_changed_connection.disconnect();
1059 existing->set_auto_loop (false, this);
1060 remove_event (existing->end(), Event::AutoLoop);
1061 auto_loop_location_changed (0);
1066 if (location == 0) {
1070 if (location->end() <= location->start()) {
1071 error << _("Session: you can't use a mark for auto loop") << endmsg;
1075 last_loopend = location->end();
1077 auto_loop_start_changed_connection.disconnect();
1078 auto_loop_end_changed_connection.disconnect();
1079 auto_loop_changed_connection.disconnect();
1081 auto_loop_start_changed_connection = location->start_changed.connect (
1082 mem_fun (this, &Session::auto_loop_changed));
1083 auto_loop_end_changed_connection = location->end_changed.connect (
1084 mem_fun (this, &Session::auto_loop_changed));
1085 auto_loop_changed_connection = location->changed.connect (
1086 mem_fun (this, &Session::auto_loop_changed));
1088 location->set_auto_loop (true, this);
1090 /* take care of our stuff first */
1092 auto_loop_changed (location);
1094 /* now tell everyone else */
1096 auto_loop_location_changed (location);
1100 Session::locations_added (Location *)
1106 Session::locations_changed ()
1108 _locations.apply (*this, &Session::handle_locations_changed);
1112 Session::handle_locations_changed (Locations::LocationList& locations)
1114 Locations::LocationList::iterator i;
1116 bool set_loop = false;
1117 bool set_punch = false;
1119 for (i = locations.begin(); i != locations.end(); ++i) {
1123 if (location->is_auto_punch()) {
1124 set_auto_punch_location (location);
1127 if (location->is_auto_loop()) {
1128 set_auto_loop_location (location);
1132 if (location->is_start()) {
1133 start_location = location;
1135 if (location->is_end()) {
1136 end_location = location;
1141 set_auto_loop_location (0);
1144 set_auto_punch_location (0);
1151 Session::enable_record ()
1153 /* XXX really atomic compare+swap here */
1154 if (g_atomic_int_get (&_record_status) != Recording) {
1155 g_atomic_int_set (&_record_status, Recording);
1156 _last_record_location = _transport_frame;
1157 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1159 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1160 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1161 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1162 if ((*i)->record_enabled ()) {
1163 (*i)->monitor_input (true);
1168 RecordStateChanged ();
1173 Session::disable_record (bool rt_context, bool force)
1177 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1179 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1180 g_atomic_int_set (&_record_status, Disabled);
1182 if (rs == Recording) {
1183 g_atomic_int_set (&_record_status, Enabled);
1187 // FIXME: timestamp correct? [DR]
1188 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1189 // does this /need/ to be sent in all cases?
1191 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1193 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1194 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1196 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1197 if ((*i)->record_enabled ()) {
1198 (*i)->monitor_input (false);
1203 RecordStateChanged (); /* emit signal */
1206 remove_pending_capture_state ();
1212 Session::step_back_from_record ()
1214 /* XXX really atomic compare+swap here */
1215 if (g_atomic_int_get (&_record_status) == Recording) {
1216 g_atomic_int_set (&_record_status, Enabled);
1218 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1219 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1221 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1222 if ((*i)->record_enabled ()) {
1223 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1224 (*i)->monitor_input (false);
1232 Session::maybe_enable_record ()
1234 g_atomic_int_set (&_record_status, Enabled);
1236 /* this function is currently called from somewhere other than an RT thread.
1237 this save_state() call therefore doesn't impact anything.
1240 save_state ("", true);
1242 if (_transport_speed) {
1243 if (!config.get_punch_in()) {
1247 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1248 RecordStateChanged (); /* EMIT SIGNAL */
1255 Session::audible_frame () const
1261 /* the first of these two possible settings for "offset"
1262 mean that the audible frame is stationary until
1263 audio emerges from the latency compensation
1266 the second means that the audible frame is stationary
1267 until audio would emerge from a physical port
1268 in the absence of any plugin latency compensation
1271 offset = _worst_output_latency;
1273 if (offset > current_block_size) {
1274 offset -= current_block_size;
1276 /* XXX is this correct? if we have no external
1277 physical connections and everything is internal
1278 then surely this is zero? still, how
1279 likely is that anyway?
1281 offset = current_block_size;
1284 if (synced_to_jack()) {
1285 tf = _engine.transport_frame();
1287 tf = _transport_frame;
1292 if (!non_realtime_work_pending()) {
1296 /* check to see if we have passed the first guaranteed
1297 audible frame past our last start position. if not,
1298 return that last start point because in terms
1299 of audible frames, we have not moved yet.
1302 if (_transport_speed > 0.0f) {
1304 if (!play_loop || !have_looped) {
1305 if (tf < _last_roll_location + offset) {
1306 return _last_roll_location;
1314 } else if (_transport_speed < 0.0f) {
1316 /* XXX wot? no backward looping? */
1318 if (tf > _last_roll_location - offset) {
1319 return _last_roll_location;
1331 Session::set_frame_rate (nframes_t frames_per_second)
1333 /** \fn void Session::set_frame_size(nframes_t)
1334 the AudioEngine object that calls this guarantees
1335 that it will not be called while we are also in
1336 ::process(). Its fine to do things that block
1340 _base_frame_rate = frames_per_second;
1344 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1348 // XXX we need some equivalent to this, somehow
1349 // SndFileSource::setup_standard_crossfades (frames_per_second);
1353 /* XXX need to reset/reinstantiate all LADSPA plugins */
1357 Session::set_block_size (nframes_t nframes)
1359 /* the AudioEngine guarantees
1360 that it will not be called while we are also in
1361 ::process(). It is therefore fine to do things that block
1366 current_block_size = nframes;
1368 ensure_buffers(_scratch_buffers->available());
1370 delete [] _gain_automation_buffer;
1371 _gain_automation_buffer = new gain_t[nframes];
1373 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1375 boost::shared_ptr<RouteList> r = routes.reader ();
1377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1378 (*i)->set_block_size (nframes);
1381 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1382 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1383 (*i)->set_block_size (nframes);
1386 set_worst_io_latencies ();
1391 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1394 nframes_t fade_frames;
1396 /* Don't allow fade of less 1 frame */
1398 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1405 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1409 default_fade_msecs = fade_msecs;
1410 default_fade_steepness = steepness;
1413 // jlc, WTF is this!
1414 Glib::RWLock::ReaderLock lm (route_lock);
1415 AudioRegion::set_default_fade (steepness, fade_frames);
1420 /* XXX have to do this at some point */
1421 /* foreach region using default fade, reset, then
1422 refill_all_diskstream_buffers ();
1427 struct RouteSorter {
1428 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1429 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1431 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1434 if (r1->fed_by.empty()) {
1435 if (r2->fed_by.empty()) {
1436 /* no ardour-based connections inbound to either route. just use signal order */
1437 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1439 /* r2 has connections, r1 does not; run r1 early */
1443 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1450 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1452 shared_ptr<Route> r2;
1454 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1455 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1459 /* make a copy of the existing list of routes that feed r1 */
1461 set<weak_ptr<Route> > existing = r1->fed_by;
1463 /* for each route that feeds r1, recurse, marking it as feeding
1467 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1468 if (!(r2 = (*i).lock ())) {
1469 /* (*i) went away, ignore it */
1473 /* r2 is a route that feeds r1 which somehow feeds base. mark
1474 base as being fed by r2
1477 rbase->fed_by.insert (r2);
1481 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1485 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1489 /* now recurse, so that we can mark base as being fed by
1490 all routes that feed r2
1493 trace_terminal (r2, rbase);
1500 Session::resort_routes ()
1502 /* don't do anything here with signals emitted
1503 by Routes while we are being destroyed.
1506 if (_state_of_the_state & Deletion) {
1513 RCUWriter<RouteList> writer (routes);
1514 shared_ptr<RouteList> r = writer.get_copy ();
1515 resort_routes_using (r);
1516 /* writer goes out of scope and forces update */
1521 Session::resort_routes_using (shared_ptr<RouteList> r)
1523 RouteList::iterator i, j;
1525 for (i = r->begin(); i != r->end(); ++i) {
1527 (*i)->fed_by.clear ();
1529 for (j = r->begin(); j != r->end(); ++j) {
1531 /* although routes can feed themselves, it will
1532 cause an endless recursive descent if we
1533 detect it. so don't bother checking for
1541 if ((*j)->feeds (*i)) {
1542 (*i)->fed_by.insert (*j);
1547 for (i = r->begin(); i != r->end(); ++i) {
1548 trace_terminal (*i, *i);
1555 cerr << "finished route resort\n";
1557 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1558 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1565 list<boost::shared_ptr<MidiTrack> >
1566 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1568 char track_name[32];
1569 uint32_t track_id = 0;
1572 RouteList new_routes;
1573 list<boost::shared_ptr<MidiTrack> > ret;
1574 //uint32_t control_id;
1576 // FIXME: need physical I/O and autoconnect stuff for MIDI
1578 /* count existing midi tracks */
1581 shared_ptr<RouteList> r = routes.reader ();
1583 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1584 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1585 if (!(*i)->is_hidden()) {
1587 //channels_used += (*i)->n_inputs().n_midi();
1593 vector<string> physinputs;
1594 vector<string> physoutputs;
1596 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1597 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1599 // control_id = ntracks() + nbusses();
1603 /* check for duplicate route names, since we might have pre-existing
1604 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1605 save, close,restart,add new route - first named route is now
1613 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1615 if (route_by_name (track_name) == 0) {
1619 } while (track_id < (UINT_MAX-1));
1621 shared_ptr<MidiTrack> track;
1624 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1626 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1627 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1632 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1633 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1639 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1643 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1644 port = physinputs[(channels_used+x)%nphysical_in];
1647 if (port.length() && track->connect_input (track->input (x), port, this)) {
1653 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1657 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1658 port = physoutputs[(channels_used+x)%nphysical_out];
1659 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1661 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1665 if (port.length() && track->connect_output (track->output (x), port, this)) {
1670 channels_used += track->n_inputs ().n_midi();
1674 track->midi_diskstream()->non_realtime_input_change();
1675 track->set_route_group (route_group, 0);
1677 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1678 //track->set_remote_control_id (control_id);
1680 new_routes.push_back (track);
1681 ret.push_back (track);
1684 catch (failed_constructor &err) {
1685 error << _("Session: could not create new midi track.") << endmsg;
1688 /* we need to get rid of this, since the track failed to be created */
1689 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1692 RCUWriter<DiskstreamList> writer (diskstreams);
1693 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1694 ds->remove (track->midi_diskstream());
1701 catch (AudioEngine::PortRegistrationFailure& pfe) {
1703 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;
1706 /* we need to get rid of this, since the track failed to be created */
1707 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1710 RCUWriter<DiskstreamList> writer (diskstreams);
1711 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1712 ds->remove (track->midi_diskstream());
1723 if (!new_routes.empty()) {
1724 add_routes (new_routes, false);
1725 save_state (_current_snapshot_name);
1731 list<boost::shared_ptr<AudioTrack> >
1732 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1734 char track_name[32];
1735 uint32_t track_id = 0;
1737 uint32_t channels_used = 0;
1739 RouteList new_routes;
1740 list<boost::shared_ptr<AudioTrack> > ret;
1741 uint32_t control_id;
1743 /* count existing audio tracks */
1746 shared_ptr<RouteList> r = routes.reader ();
1748 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1749 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1750 if (!(*i)->is_hidden()) {
1752 channels_used += (*i)->n_inputs().n_audio();
1758 vector<string> physinputs;
1759 vector<string> physoutputs;
1761 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1762 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1764 control_id = ntracks() + nbusses() + 1;
1768 /* check for duplicate route names, since we might have pre-existing
1769 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1770 save, close,restart,add new route - first named route is now
1778 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1780 if (route_by_name (track_name) == 0) {
1784 } while (track_id < (UINT_MAX-1));
1786 shared_ptr<AudioTrack> track;
1789 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1790 // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1791 track = boost::shared_ptr<AudioTrack>(at);
1793 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1794 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1795 input_channels, output_channels)
1800 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1801 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1802 input_channels, output_channels)
1807 if (!physinputs.empty()) {
1808 uint32_t nphysical_in = physinputs.size();
1810 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1814 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1815 port = physinputs[(channels_used+x)%nphysical_in];
1818 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1824 if (!physoutputs.empty()) {
1825 uint32_t nphysical_out = physoutputs.size();
1827 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1830 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1831 port = physoutputs[(channels_used+x)%nphysical_out];
1832 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1833 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1834 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1838 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1844 channels_used += track->n_inputs ().n_audio();
1846 track->set_route_group (route_group, 0);
1848 track->audio_diskstream()->non_realtime_input_change();
1850 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1851 track->set_remote_control_id (control_id);
1854 new_routes.push_back (track);
1855 ret.push_back (track);
1858 catch (failed_constructor &err) {
1859 error << _("Session: could not create new audio track.") << endmsg;
1862 /* we need to get rid of this, since the track failed to be created */
1863 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1866 RCUWriter<DiskstreamList> writer (diskstreams);
1867 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1868 ds->remove (track->audio_diskstream());
1875 catch (AudioEngine::PortRegistrationFailure& pfe) {
1877 error << pfe.what() << endmsg;
1880 /* we need to get rid of this, since the track failed to be created */
1881 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1884 RCUWriter<DiskstreamList> writer (diskstreams);
1885 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1886 ds->remove (track->audio_diskstream());
1897 if (!new_routes.empty()) {
1898 add_routes (new_routes, true);
1905 Session::set_remote_control_ids ()
1907 RemoteModel m = Config->get_remote_model();
1909 shared_ptr<RouteList> r = routes.reader ();
1911 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1912 if ( MixerOrdered == m) {
1913 long order = (*i)->order_key(N_("signal"));
1914 (*i)->set_remote_control_id( order+1 );
1915 } else if ( EditorOrdered == m) {
1916 long order = (*i)->order_key(N_("editor"));
1917 (*i)->set_remote_control_id( order+1 );
1918 } else if ( UserOrdered == m) {
1919 //do nothing ... only changes to remote id's are initiated by user
1926 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1929 uint32_t bus_id = 1;
1931 uint32_t channels_used = 0;
1934 uint32_t control_id;
1936 /* count existing audio busses */
1939 shared_ptr<RouteList> r = routes.reader ();
1941 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1942 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1944 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1947 channels_used += (*i)->n_inputs().n_audio();
1953 vector<string> physinputs;
1954 vector<string> physoutputs;
1956 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1957 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1959 n_physical_audio_outputs = physoutputs.size();
1960 n_physical_audio_inputs = physinputs.size();
1962 control_id = ntracks() + nbusses() + 1;
1967 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1971 if (route_by_name (bus_name) == 0) {
1975 } while (bus_id < (UINT_MAX-1));
1978 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1980 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1981 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1982 input_channels, output_channels)
1988 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1989 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1990 input_channels, output_channels)
1995 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1998 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1999 port = physinputs[((n+x)%n_physical_audio_inputs)];
2002 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
2007 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
2010 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
2011 port = physoutputs[((n+x)%n_physical_outputs)];
2012 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
2014 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
2018 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
2023 channels_used += bus->n_inputs ().n_audio();
2025 bus->set_route_group (route_group, 0);
2026 bus->set_remote_control_id (control_id);
2030 bus->add_internal_return ();
2033 ret.push_back (bus);
2037 catch (failed_constructor &err) {
2038 error << _("Session: could not create new audio route.") << endmsg;
2042 catch (AudioEngine::PortRegistrationFailure& pfe) {
2043 error << pfe.what() << endmsg;
2053 add_routes (ret, true);
2061 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2065 uint32_t control_id;
2067 uint32_t number = 1;
2069 if (!tree.read (template_path.c_str())) {
2073 XMLNode* node = tree.root();
2075 control_id = ntracks() + nbusses() + 1;
2079 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2081 std::string node_name = IO::name_from_state (*node_copy.children().front());
2083 /* generate a new name by adding a number to the end of the template name */
2086 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2090 if (route_by_name (name) == 0) {
2094 } while (number < UINT_MAX);
2096 if (number == UINT_MAX) {
2097 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2101 IO::set_name_in_state (*node_copy.children().front(), name);
2103 Track::zero_diskstream_id_in_xml (node_copy);
2106 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2109 error << _("Session: cannot create track/bus from template description") << endmsg;
2113 if (boost::dynamic_pointer_cast<Track>(route)) {
2114 /* force input/output change signals so that the new diskstream
2115 picks up the configuration of the route. During session
2116 loading this normally happens in a different way.
2118 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2119 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2122 route->set_remote_control_id (control_id);
2125 ret.push_back (route);
2128 catch (failed_constructor &err) {
2129 error << _("Session: could not create new route from template") << endmsg;
2133 catch (AudioEngine::PortRegistrationFailure& pfe) {
2134 error << pfe.what() << endmsg;
2143 add_routes (ret, true);
2150 Session::add_routes (RouteList& new_routes, bool save)
2153 RCUWriter<RouteList> writer (routes);
2154 shared_ptr<RouteList> r = writer.get_copy ();
2155 r->insert (r->end(), new_routes.begin(), new_routes.end());
2158 /* if there is no control out and we're not in the middle of loading,
2159 resort the graph here. if there is a control out, we will resort
2160 toward the end of this method. if we are in the middle of loading,
2161 we will resort when done.
2164 if (!_control_out && IO::connecting_legal) {
2165 resort_routes_using (r);
2169 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2171 boost::weak_ptr<Route> wpr (*x);
2173 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2174 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2175 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2176 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2177 (*x)->processors_changed.connect (mem_fun (*this, &Session::route_processors_changed));
2178 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2180 if ((*x)->is_master()) {
2184 if ((*x)->is_control()) {
2185 _control_out = (*x);
2189 if (_control_out && IO::connecting_legal) {
2191 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2192 if ((*x)->is_control() || (*x)->is_master()) {
2195 (*x)->listen_via (_control_out,
2196 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2206 save_state (_current_snapshot_name);
2209 RouteAdded (new_routes); /* EMIT SIGNAL */
2213 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2215 boost::shared_ptr<RouteList> r = routes.reader ();
2216 boost::shared_ptr<Send> s;
2220 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2221 if (boost::dynamic_pointer_cast<Track>(*i)) {
2222 if ((s = (*i)->internal_send_for (dest)) != 0) {
2223 s->amp()->gain_control()->set_value (0.0);
2230 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2232 boost::shared_ptr<RouteList> r = routes.reader ();
2233 boost::shared_ptr<Send> s;
2237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238 if (boost::dynamic_pointer_cast<Track>(*i)) {
2239 if ((s = (*i)->internal_send_for (dest)) != 0) {
2240 s->amp()->gain_control()->set_value (1.0);
2247 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2249 boost::shared_ptr<RouteList> r = routes.reader ();
2250 boost::shared_ptr<Send> s;
2254 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2255 if (boost::dynamic_pointer_cast<Track>(*i)) {
2256 if ((s = (*i)->internal_send_for (dest)) != 0) {
2257 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2264 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2266 boost::shared_ptr<RouteList> r = routes.reader ();
2267 boost::shared_ptr<RouteList> t (new RouteList);
2269 /* only send tracks */
2271 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2272 if (boost::dynamic_pointer_cast<Track>(*i)) {
2277 add_internal_sends (dest, p, t);
2281 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2283 if (dest->is_control() || dest->is_master()) {
2287 if (!dest->internal_return()) {
2288 dest->add_internal_return();
2291 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2293 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2297 (*i)->listen_via (dest, p, true, true);
2304 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2306 /* need to do this in case we're rolling at the time, to prevent false underruns */
2307 dstream->do_refill_with_alloc ();
2309 dstream->set_block_size (current_block_size);
2312 RCUWriter<DiskstreamList> writer (diskstreams);
2313 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2314 ds->push_back (dstream);
2315 /* writer goes out of scope, copies ds back to main */
2318 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2319 /* this will connect to future changes, and check the current length */
2320 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2322 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2324 dstream->prepare ();
2329 Session::remove_route (shared_ptr<Route> route)
2332 RCUWriter<RouteList> writer (routes);
2333 shared_ptr<RouteList> rs = writer.get_copy ();
2337 /* deleting the master out seems like a dumb
2338 idea, but its more of a UI policy issue
2342 if (route == _master_out) {
2343 _master_out = shared_ptr<Route> ();
2346 if (route == _control_out) {
2348 /* cancel control outs for all routes */
2350 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2351 (*r)->drop_listen (_control_out);
2354 _control_out.reset ();
2357 update_route_solo_state ();
2359 /* writer goes out of scope, forces route list update */
2362 boost::shared_ptr<Track> t;
2363 boost::shared_ptr<Diskstream> ds;
2365 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2366 ds = t->diskstream();
2372 RCUWriter<DiskstreamList> dsl (diskstreams);
2373 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2378 find_current_end ();
2380 // We need to disconnect the routes inputs and outputs
2382 route->input()->disconnect (0);
2383 route->output()->disconnect (0);
2385 /* if the route had internal sends sending to it, remove them */
2386 if (route->internal_return()) {
2388 boost::shared_ptr<RouteList> r = routes.reader ();
2389 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2390 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2392 (*i)->remove_processor (s);
2397 update_latency_compensation (false, false);
2400 /* get rid of it from the dead wood collection in the route list manager */
2402 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2406 /* try to cause everyone to drop their references */
2408 route->drop_references ();
2410 sync_order_keys (N_("session"));
2412 /* save the new state of the world */
2414 if (save_state (_current_snapshot_name)) {
2415 save_history (_current_snapshot_name);
2420 Session::route_mute_changed (void* /*src*/)
2426 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2428 boost::shared_ptr<Route> route = wpr.lock();
2430 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2434 if (route->listening()) {
2436 } else if (_listen_cnt > 0) {
2442 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2444 if (solo_update_disabled) {
2449 boost::shared_ptr<Route> route = wpr.lock ();
2452 /* should not happen */
2453 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2457 shared_ptr<RouteList> r = routes.reader ();
2460 if (route->self_soloed()) {
2466 /* now mod the solo level of all other routes except master & control outs
2467 so that they will be silent if appropriate.
2470 solo_update_disabled = true;
2472 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2473 bool via_sends_only;
2476 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2478 } else if ((*i)->feeds (route, &via_sends_only)) {
2479 if (!via_sends_only) {
2480 (*i)->mod_solo_by_others (delta);
2485 /* make sure master is never muted by solo */
2487 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2488 _master_out->mod_solo_by_others (1);
2491 /* ditto for control outs make sure master is never muted by solo */
2493 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2494 _control_out->mod_solo_by_others (1);
2497 solo_update_disabled = false;
2498 update_route_solo_state (r);
2499 SoloChanged (); /* EMIT SIGNAL */
2504 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2506 /* now figure out if anything that matters is soloed */
2508 bool something_soloed = false;
2511 r = routes.reader();
2514 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2515 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2516 something_soloed = true;
2521 if (something_soloed != _non_soloed_outs_muted) {
2522 _non_soloed_outs_muted = something_soloed;
2523 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2527 boost::shared_ptr<RouteList>
2528 Session::get_routes_with_internal_returns() const
2530 shared_ptr<RouteList> r = routes.reader ();
2531 boost::shared_ptr<RouteList> rl (new RouteList);
2533 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2534 if ((*i)->internal_return ()) {
2542 Session::route_by_name (string name)
2544 shared_ptr<RouteList> r = routes.reader ();
2546 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2547 if ((*i)->name() == name) {
2552 return shared_ptr<Route> ((Route*) 0);
2556 Session::route_by_id (PBD::ID id)
2558 shared_ptr<RouteList> r = routes.reader ();
2560 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2561 if ((*i)->id() == id) {
2566 return shared_ptr<Route> ((Route*) 0);
2570 Session::route_by_remote_id (uint32_t id)
2572 shared_ptr<RouteList> r = routes.reader ();
2574 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2575 if ((*i)->remote_control_id() == id) {
2580 return shared_ptr<Route> ((Route*) 0);
2584 Session::find_current_end ()
2586 if (_state_of_the_state & Loading) {
2590 nframes_t max = get_maximum_extent ();
2592 if (max > end_location->end()) {
2593 end_location->set_end (max);
2595 DurationChanged(); /* EMIT SIGNAL */
2600 Session::get_maximum_extent () const
2605 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2607 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2608 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2610 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2611 if ((me = pl->get_maximum_extent()) > max) {
2619 boost::shared_ptr<Diskstream>
2620 Session::diskstream_by_name (string name)
2622 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2624 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2625 if ((*i)->name() == name) {
2630 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2633 boost::shared_ptr<Diskstream>
2634 Session::diskstream_by_id (const PBD::ID& id)
2636 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2638 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2639 if ((*i)->id() == id) {
2644 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2647 /* Region management */
2650 Session::new_region_name (string old)
2652 string::size_type last_period;
2654 string::size_type len = old.length() + 64;
2657 if ((last_period = old.find_last_of ('.')) == string::npos) {
2659 /* no period present - add one explicitly */
2662 last_period = old.length() - 1;
2667 number = atoi (old.substr (last_period+1).c_str());
2671 while (number < (UINT_MAX-1)) {
2673 RegionList::const_iterator i;
2678 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2681 for (i = regions.begin(); i != regions.end(); ++i) {
2682 if (i->second->name() == sbuf) {
2687 if (i == regions.end()) {
2692 if (number != (UINT_MAX-1)) {
2696 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2701 Session::region_name (string& result, string base, bool newlevel)
2706 if (base.find("/") != string::npos) {
2707 base = base.substr(base.find_last_of("/") + 1);
2712 Glib::Mutex::Lock lm (region_lock);
2714 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2723 string::size_type pos;
2725 pos = base.find_last_of ('.');
2727 /* pos may be npos, but then we just use entire base */
2729 subbase = base.substr (0, pos);
2734 Glib::Mutex::Lock lm (region_lock);
2736 map<string,uint32_t>::iterator x;
2740 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2742 region_name_map[subbase] = 1;
2745 snprintf (buf, sizeof (buf), ".%d", x->second);
2756 Session::add_region (boost::shared_ptr<Region> region)
2758 vector<boost::shared_ptr<Region> > v;
2759 v.push_back (region);
2764 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2769 Glib::Mutex::Lock lm (region_lock);
2771 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2773 boost::shared_ptr<Region> region = *ii;
2777 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2781 RegionList::iterator x;
2783 for (x = regions.begin(); x != regions.end(); ++x) {
2785 if (region->region_list_equivalent (x->second)) {
2790 if (x == regions.end()) {
2792 pair<RegionList::key_type,RegionList::mapped_type> entry;
2794 entry.first = region->id();
2795 entry.second = region;
2797 pair<RegionList::iterator,bool> x = regions.insert (entry);
2809 /* mark dirty because something has changed even if we didn't
2810 add the region to the region list.
2817 vector<boost::weak_ptr<Region> > v;
2818 boost::shared_ptr<Region> first_r;
2820 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2822 boost::shared_ptr<Region> region = *ii;
2826 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2829 v.push_back (region);
2836 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2837 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2839 update_region_name_map (region);
2843 RegionsAdded (v); /* EMIT SIGNAL */
2849 Session::update_region_name_map (boost::shared_ptr<Region> region)
2851 string::size_type last_period = region->name().find_last_of ('.');
2853 if (last_period != string::npos && last_period < region->name().length() - 1) {
2855 string base = region->name().substr (0, last_period);
2856 string number = region->name().substr (last_period+1);
2857 map<string,uint32_t>::iterator x;
2859 /* note that if there is no number, we get zero from atoi,
2863 region_name_map[base] = atoi (number);
2868 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2870 boost::shared_ptr<Region> region (weak_region.lock ());
2876 if (what_changed & Region::HiddenChanged) {
2877 /* relay hidden changes */
2878 RegionHiddenChange (region);
2881 if (what_changed & NameChanged) {
2882 update_region_name_map (region);
2887 Session::remove_region (boost::weak_ptr<Region> weak_region)
2889 RegionList::iterator i;
2890 boost::shared_ptr<Region> region (weak_region.lock ());
2896 bool removed = false;
2899 Glib::Mutex::Lock lm (region_lock);
2901 if ((i = regions.find (region->id())) != regions.end()) {
2907 /* mark dirty because something has changed even if we didn't
2908 remove the region from the region list.
2914 RegionRemoved(region); /* EMIT SIGNAL */
2918 boost::shared_ptr<Region>
2919 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2921 RegionList::iterator i;
2922 boost::shared_ptr<Region> region;
2924 Glib::Mutex::Lock lm (region_lock);
2926 for (i = regions.begin(); i != regions.end(); ++i) {
2930 if (region->whole_file()) {
2932 if (child->source_equivalent (region)) {
2938 return boost::shared_ptr<Region> ();
2942 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2944 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2945 (*i)->get_region_list_equivalent_regions (region, result);
2949 Session::destroy_region (boost::shared_ptr<Region> region)
2951 vector<boost::shared_ptr<Source> > srcs;
2954 if (region->playlist()) {
2955 region->playlist()->destroy_region (region);
2958 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2959 srcs.push_back (region->source (n));
2963 region->drop_references ();
2965 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2967 (*i)->mark_for_remove ();
2968 (*i)->drop_references ();
2970 cerr << "source was not used by any playlist\n";
2977 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2979 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2980 destroy_region (*i);
2986 Session::remove_last_capture ()
2988 list<boost::shared_ptr<Region> > r;
2990 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2992 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2993 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2996 r.insert (r.end(), l.begin(), l.end());
3001 destroy_regions (r);
3003 save_state (_current_snapshot_name);
3009 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3015 /* Source Management */
3018 Session::add_source (boost::shared_ptr<Source> source)
3020 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3021 pair<SourceMap::iterator,bool> result;
3023 entry.first = source->id();
3024 entry.second = source;
3027 Glib::Mutex::Lock lm (source_lock);
3028 result = sources.insert (entry);
3031 if (result.second) {
3032 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3036 boost::shared_ptr<AudioFileSource> afs;
3038 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3039 if (Config->get_auto_analyse_audio()) {
3040 Analyser::queue_source_for_analysis (source, false);
3046 Session::remove_source (boost::weak_ptr<Source> src)
3048 SourceMap::iterator i;
3049 boost::shared_ptr<Source> source = src.lock();
3056 Glib::Mutex::Lock lm (source_lock);
3058 if ((i = sources.find (source->id())) != sources.end()) {
3063 if (!_state_of_the_state & InCleanup) {
3065 /* save state so we don't end up with a session file
3066 referring to non-existent sources.
3069 save_state (_current_snapshot_name);
3073 /** Return the number of playlists (not regions) that contain @a src */
3075 Session::source_use_count (boost::shared_ptr<const Source> src) const
3078 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3079 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3080 r != (*p)->region_list().end(); ++r) {
3081 if ((*r)->uses_source(src)) {
3090 boost::shared_ptr<Source>
3091 Session::source_by_id (const PBD::ID& id)
3093 Glib::Mutex::Lock lm (source_lock);
3094 SourceMap::iterator i;
3095 boost::shared_ptr<Source> source;
3097 if ((i = sources.find (id)) != sources.end()) {
3104 boost::shared_ptr<Source>
3105 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3107 Glib::Mutex::Lock lm (source_lock);
3109 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3110 cerr << "comparing " << path << " with " << i->second->name() << endl;
3111 boost::shared_ptr<AudioFileSource> afs
3112 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3114 if (afs && afs->path() == path && chn == afs->channel()) {
3118 return boost::shared_ptr<Source>();
3123 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3126 string old_basename = PBD::basename_nosuffix (oldname);
3127 string new_legalized = legalize_for_path (newname);
3129 /* note: we know (or assume) the old path is already valid */
3133 /* destructive file sources have a name of the form:
3135 /path/to/Tnnnn-NAME(%[LR])?.wav
3137 the task here is to replace NAME with the new name.
3140 /* find last slash */
3144 string::size_type slash;
3145 string::size_type dash;
3147 if ((slash = path.find_last_of ('/')) == string::npos) {
3151 dir = path.substr (0, slash+1);
3153 /* '-' is not a legal character for the NAME part of the path */
3155 if ((dash = path.find_last_of ('-')) == string::npos) {
3159 prefix = path.substr (slash+1, dash-(slash+1));
3164 path += new_legalized;
3165 path += ".wav"; /* XXX gag me with a spoon */
3169 /* non-destructive file sources have a name of the form:
3171 /path/to/NAME-nnnnn(%[LR])?.ext
3173 the task here is to replace NAME with the new name.
3178 string::size_type slash;
3179 string::size_type dash;
3180 string::size_type postfix;
3182 /* find last slash */
3184 if ((slash = path.find_last_of ('/')) == string::npos) {
3188 dir = path.substr (0, slash+1);
3190 /* '-' is not a legal character for the NAME part of the path */
3192 if ((dash = path.find_last_of ('-')) == string::npos) {
3196 suffix = path.substr (dash+1);
3198 // Suffix is now everything after the dash. Now we need to eliminate
3199 // the nnnnn part, which is done by either finding a '%' or a '.'
3201 postfix = suffix.find_last_of ("%");
3202 if (postfix == string::npos) {
3203 postfix = suffix.find_last_of ('.');
3206 if (postfix != string::npos) {
3207 suffix = suffix.substr (postfix);
3209 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3213 const uint32_t limit = 10000;
3214 char buf[PATH_MAX+1];
3216 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3218 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3220 if (access (buf, F_OK) != 0) {
3228 error << "FATAL ERROR! Could not find a " << endl;
3236 /** Return the full path (in some session directory) for a new within-session source.
3237 * \a name must be a session-unique name that does not contain slashes
3238 * (e.g. as returned by new_*_source_name)
3241 Session::new_source_path_from_name (DataType type, const string& name)
3243 assert(name.find("/") == string::npos);
3245 SessionDirectory sdir(get_best_session_directory_for_new_source());
3248 if (type == DataType::AUDIO) {
3249 p = sdir.sound_path();
3250 } else if (type == DataType::MIDI) {
3251 p = sdir.midi_path();
3253 error << "Unknown source type, unable to create file path" << endmsg;
3258 return p.to_string();
3262 Session::peak_path (Glib::ustring base) const
3264 sys::path peakfile_path(_session_dir->peak_path());
3265 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3266 return peakfile_path.to_string();
3269 /** Return a unique name based on \a base for a new internal audio source */
3271 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3275 char buf[PATH_MAX+1];
3276 const uint32_t limit = 10000;
3280 legalized = legalize_for_path (base);
3282 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3283 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3285 vector<space_and_path>::iterator i;
3286 uint32_t existing = 0;
3288 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3290 SessionDirectory sdir((*i).path);
3292 spath = sdir.sound_path().to_string();
3297 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3298 spath.c_str(), cnt, legalized.c_str());
3299 } else if (nchan == 2) {
3301 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3302 spath.c_str(), cnt, legalized.c_str());
3304 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3305 spath.c_str(), cnt, legalized.c_str());
3307 } else if (nchan < 26) {
3308 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3309 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3311 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3312 spath.c_str(), cnt, legalized.c_str());
3321 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3322 } else if (nchan == 2) {
3324 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3326 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3328 } else if (nchan < 26) {
3329 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3331 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3335 if (sys::exists(buf)) {
3341 if (existing == 0) {
3346 error << string_compose(
3347 _("There are already %1 recordings for %2, which I consider too many."),
3348 limit, base) << endmsg;
3350 throw failed_constructor();
3354 return Glib::path_get_basename(buf);
3357 /** Create a new within-session audio source */
3358 boost::shared_ptr<AudioFileSource>
3359 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3361 const size_t n_chans = ds.n_channels().n_audio();
3362 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3363 const string path = new_source_path_from_name(DataType::AUDIO, name);
3365 return boost::dynamic_pointer_cast<AudioFileSource> (
3366 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3369 /** Return a unique name based on \a base for a new internal MIDI source */
3371 Session::new_midi_source_name (const string& base)
3374 char buf[PATH_MAX+1];
3375 const uint32_t limit = 10000;
3379 legalized = legalize_for_path (base);
3381 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3382 for (cnt = 1; cnt <= limit; ++cnt) {
3384 vector<space_and_path>::iterator i;
3385 uint32_t existing = 0;
3387 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3389 SessionDirectory sdir((*i).path);
3391 sys::path p = sdir.midi_path();
3394 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3396 if (sys::exists (buf)) {
3401 if (existing == 0) {
3406 error << string_compose(
3407 _("There are already %1 recordings for %2, which I consider too many."),
3408 limit, base) << endmsg;
3410 throw failed_constructor();
3414 return Glib::path_get_basename(buf);
3418 /** Create a new within-session MIDI source */
3419 boost::shared_ptr<MidiSource>
3420 Session::create_midi_source_for_session (MidiDiskstream& ds)
3422 const string name = new_midi_source_name (ds.name());
3423 const string path = new_source_path_from_name (DataType::MIDI, name);
3425 return boost::dynamic_pointer_cast<SMFSource> (
3426 SourceFactory::createWritable (
3427 DataType::MIDI, *this, path, false, frame_rate()));
3431 /* Playlist management */
3433 boost::shared_ptr<Playlist>
3434 Session::playlist_by_name (string name)
3436 Glib::Mutex::Lock lm (playlist_lock);
3437 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3438 if ((*i)->name() == name) {
3442 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3443 if ((*i)->name() == name) {
3448 return boost::shared_ptr<Playlist>();
3452 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3454 Glib::Mutex::Lock lm (playlist_lock);
3455 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3456 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3457 list.push_back (*i);
3460 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3461 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3462 list.push_back (*i);
3468 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3470 if (playlist->hidden()) {
3475 Glib::Mutex::Lock lm (playlist_lock);
3476 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3477 playlists.insert (playlists.begin(), playlist);
3478 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3479 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3484 playlist->release();
3489 PlaylistAdded (playlist); /* EMIT SIGNAL */
3493 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3496 Glib::Mutex::Lock lm (playlist_lock);
3497 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3500 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3507 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3509 boost::shared_ptr<Playlist> pl(wpl.lock());
3515 PlaylistList::iterator x;
3518 /* its not supposed to be visible */
3523 Glib::Mutex::Lock lm (playlist_lock);
3527 unused_playlists.insert (pl);
3529 if ((x = playlists.find (pl)) != playlists.end()) {
3530 playlists.erase (x);
3536 playlists.insert (pl);
3538 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3539 unused_playlists.erase (x);
3546 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3548 if (_state_of_the_state & Deletion) {
3552 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3559 Glib::Mutex::Lock lm (playlist_lock);
3561 PlaylistList::iterator i;
3563 i = find (playlists.begin(), playlists.end(), playlist);
3564 if (i != playlists.end()) {
3565 playlists.erase (i);
3568 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3569 if (i != unused_playlists.end()) {
3570 unused_playlists.erase (i);
3577 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3581 Session::set_audition (boost::shared_ptr<Region> r)
3583 pending_audition_region = r;
3584 add_post_transport_work (PostTransportAudition);
3585 _butler->schedule_transport_work ();
3589 Session::audition_playlist ()
3591 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3592 ev->region.reset ();
3597 Session::non_realtime_set_audition ()
3599 if (!pending_audition_region) {
3600 auditioner->audition_current_playlist ();
3602 auditioner->audition_region (pending_audition_region);
3603 pending_audition_region.reset ();
3605 AuditionActive (true); /* EMIT SIGNAL */
3609 Session::audition_region (boost::shared_ptr<Region> r)
3611 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3617 Session::cancel_audition ()
3619 if (auditioner->active()) {
3620 auditioner->cancel_audition ();
3621 AuditionActive (false); /* EMIT SIGNAL */
3626 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3628 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3632 Session::remove_empty_sounds ()
3634 vector<string> audio_filenames;
3636 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3638 Glib::Mutex::Lock lm (source_lock);
3640 TapeFileMatcher tape_file_matcher;
3642 remove_if (audio_filenames.begin(), audio_filenames.end(),
3643 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3645 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3647 sys::path audio_file_path (_session_dir->sound_path());
3649 audio_file_path /= *i;
3651 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3655 sys::remove (audio_file_path);
3656 const string peakfile = peak_path (audio_file_path.to_string());
3657 sys::remove (peakfile);
3659 catch (const sys::filesystem_error& err)
3661 error << err.what() << endmsg;
3668 Session::is_auditioning () const
3670 /* can be called before we have an auditioner object */
3672 return auditioner->active();
3679 Session::set_all_solo (bool yn)
3681 shared_ptr<RouteList> r = routes.reader ();
3683 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3684 if (!(*i)->is_hidden()) {
3685 (*i)->set_solo (yn, this);
3693 Session::set_all_listen (bool yn)
3695 shared_ptr<RouteList> r = routes.reader ();
3697 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3698 if (!(*i)->is_hidden()) {
3699 (*i)->set_listen (yn, this);
3707 Session::set_all_mute (bool yn)
3709 shared_ptr<RouteList> r = routes.reader ();
3711 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3712 if (!(*i)->is_hidden()) {
3713 (*i)->set_mute (yn, this);
3721 Session::n_diskstreams () const
3725 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3727 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3728 if (!(*i)->hidden()) {
3736 Session::graph_reordered ()
3738 /* don't do this stuff if we are setting up connections
3739 from a set_state() call or creating new tracks. Ditto for deletion.
3742 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3746 /* every track/bus asked for this to be handled but it was deferred because
3747 we were connecting. do it now.
3750 request_input_change_handling ();
3754 /* force all diskstreams to update their capture offset values to
3755 reflect any changes in latencies within the graph.
3758 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3760 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3761 (*i)->set_capture_offset ();
3766 Session::record_disenable_all ()
3768 record_enable_change_all (false);
3772 Session::record_enable_all ()
3774 record_enable_change_all (true);
3778 Session::record_enable_change_all (bool yn)
3780 shared_ptr<RouteList> r = routes.reader ();
3782 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3783 boost::shared_ptr<Track> t;
3785 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3786 t->set_record_enable (yn, this);
3790 /* since we don't keep rec-enable state, don't mark session dirty */
3794 Session::add_processor (Processor* processor)
3796 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3801 Session::remove_processor (Processor* processor)
3805 PortInsert* port_insert;
3807 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3808 insert_bitset[port_insert->bit_slot()] = false;
3809 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3810 send_bitset[send->bit_slot()] = false;
3811 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3812 return_bitset[retrn->bit_slot()] = false;
3819 Session::available_capture_duration ()
3821 float sample_bytes_on_disk = 4.0; // keep gcc happy
3823 switch (config.get_native_file_data_format()) {
3825 sample_bytes_on_disk = 4.0;
3829 sample_bytes_on_disk = 3.0;
3833 sample_bytes_on_disk = 2.0;
3837 /* impossible, but keep some gcc versions happy */
3838 fatal << string_compose (_("programming error: %1"),
3839 X_("illegal native file data format"))
3844 double scale = 4096.0 / sample_bytes_on_disk;
3846 if (_total_free_4k_blocks * scale > (double) max_frames) {
3850 return (nframes_t) floor (_total_free_4k_blocks * scale);
3854 Session::add_bundle (shared_ptr<Bundle> bundle)
3857 RCUWriter<BundleList> writer (_bundles);
3858 boost::shared_ptr<BundleList> b = writer.get_copy ();
3859 b->push_back (bundle);
3862 BundleAdded (bundle); /* EMIT SIGNAL */
3868 Session::remove_bundle (shared_ptr<Bundle> bundle)
3870 bool removed = false;
3873 RCUWriter<BundleList> writer (_bundles);
3874 boost::shared_ptr<BundleList> b = writer.get_copy ();
3875 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3877 if (i != b->end()) {
3884 BundleRemoved (bundle); /* EMIT SIGNAL */
3891 Session::bundle_by_name (string name) const
3893 boost::shared_ptr<BundleList> b = _bundles.reader ();
3895 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3896 if ((*i)->name() == name) {
3901 return boost::shared_ptr<Bundle> ();
3905 Session::tempo_map_changed (Change)
3909 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3910 (*i)->update_after_tempo_map_change ();
3913 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3914 (*i)->update_after_tempo_map_change ();
3920 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3921 * the given count with the current block size.
3924 Session::ensure_buffers (ChanCount howmany)
3926 if (current_block_size == 0) {
3927 return; // too early? (is this ok?)
3930 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3931 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3932 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3933 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3934 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3937 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3941 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3943 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3944 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3949 Session::next_insert_id ()
3951 /* this doesn't really loop forever. just think about it */
3954 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3955 if (!insert_bitset[n]) {
3956 insert_bitset[n] = true;
3962 /* none available, so resize and try again */
3964 insert_bitset.resize (insert_bitset.size() + 16, false);
3969 Session::next_send_id ()
3971 /* this doesn't really loop forever. just think about it */
3974 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3975 if (!send_bitset[n]) {
3976 send_bitset[n] = true;
3982 /* none available, so resize and try again */
3984 send_bitset.resize (send_bitset.size() + 16, false);
3989 Session::next_return_id ()
3991 /* this doesn't really loop forever. just think about it */
3994 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3995 if (!return_bitset[n]) {
3996 return_bitset[n] = true;
4002 /* none available, so resize and try again */
4004 return_bitset.resize (return_bitset.size() + 16, false);
4009 Session::mark_send_id (uint32_t id)
4011 if (id >= send_bitset.size()) {
4012 send_bitset.resize (id+16, false);
4014 if (send_bitset[id]) {
4015 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
4017 send_bitset[id] = true;
4021 Session::mark_return_id (uint32_t id)
4023 if (id >= return_bitset.size()) {
4024 return_bitset.resize (id+16, false);
4026 if (return_bitset[id]) {
4027 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
4029 return_bitset[id] = true;
4033 Session::mark_insert_id (uint32_t id)
4035 if (id >= insert_bitset.size()) {
4036 insert_bitset.resize (id+16, false);
4038 if (insert_bitset[id]) {
4039 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4041 insert_bitset[id] = true;
4044 /* Named Selection management */
4047 Session::named_selection_by_name (string name)
4049 Glib::Mutex::Lock lm (named_selection_lock);
4050 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
4051 if ((*i)->name == name) {
4059 Session::add_named_selection (NamedSelection* named_selection)
4062 Glib::Mutex::Lock lm (named_selection_lock);
4063 named_selections.insert (named_selections.begin(), named_selection);
4066 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4072 NamedSelectionAdded (); /* EMIT SIGNAL */
4076 Session::remove_named_selection (NamedSelection* named_selection)
4078 bool removed = false;
4081 Glib::Mutex::Lock lm (named_selection_lock);
4083 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4085 if (i != named_selections.end()) {
4087 named_selections.erase (i);
4094 NamedSelectionRemoved (); /* EMIT SIGNAL */
4099 Session::reset_native_file_format ()
4101 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4103 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4104 (*i)->reset_write_sources (false);
4109 Session::route_name_unique (string n) const
4111 shared_ptr<RouteList> r = routes.reader ();
4113 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4114 if ((*i)->name() == n) {
4123 Session::route_name_internal (string n) const
4125 if (auditioner && auditioner->name() == n) {
4129 if (_click_io && _click_io->name() == n) {
4137 Session::n_playlists () const
4139 Glib::Mutex::Lock lm (playlist_lock);
4140 return playlists.size();
4144 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4146 if (!force && howmany <= _npan_buffers) {
4150 if (_pan_automation_buffer) {
4152 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4153 delete [] _pan_automation_buffer[i];
4156 delete [] _pan_automation_buffer;
4159 _pan_automation_buffer = new pan_t*[howmany];
4161 for (uint32_t i = 0; i < howmany; ++i) {
4162 _pan_automation_buffer[i] = new pan_t[nframes];
4165 _npan_buffers = howmany;
4169 Session::freeze (InterThreadInfo& itt)
4171 shared_ptr<RouteList> r = routes.reader ();
4173 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4175 boost::shared_ptr<Track> t;
4177 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4178 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4188 boost::shared_ptr<Region>
4189 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4190 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4191 InterThreadInfo& itt, bool enable_processing)
4193 boost::shared_ptr<Region> result;
4194 boost::shared_ptr<Playlist> playlist;
4195 boost::shared_ptr<AudioFileSource> fsource;
4197 char buf[PATH_MAX+1];
4198 ChanCount nchans(track.audio_diskstream()->n_channels());
4200 nframes_t this_chunk;
4203 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4204 const string sound_dir = sdir.sound_path().to_string();
4205 nframes_t len = end - start;
4208 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4209 end, start) << endmsg;
4213 // any bigger than this seems to cause stack overflows in called functions
4214 const nframes_t chunk_size = (128 * 1024)/4;
4216 // block all process callback handling
4218 block_processing ();
4220 /* call tree *MUST* hold route_lock */
4222 if ((playlist = track.diskstream()->playlist()) == 0) {
4226 /* external redirects will be a problem */
4228 if (track.has_external_redirects()) {
4232 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4234 for (x = 0; x < 99999; ++x) {
4235 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4236 if (access (buf, F_OK) != 0) {
4242 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4247 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4248 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4251 catch (failed_constructor& err) {
4252 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4256 srcs.push_back (fsource);
4259 /* XXX need to flush all redirects */
4264 /* create a set of reasonably-sized buffers */
4265 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4266 buffers.set_count(nchans);
4268 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4269 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4271 afs->prepare_for_peakfile_writes ();
4274 while (to_do && !itt.cancel) {
4276 this_chunk = min (to_do, chunk_size);
4278 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4283 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4284 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4287 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4293 start += this_chunk;
4294 to_do -= this_chunk;
4296 itt.progress = (float) (1.0 - ((double) to_do / len));
4305 xnow = localtime (&now);
4307 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4308 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4311 afs->update_header (position, *xnow, now);
4312 afs->flush_header ();
4316 /* construct a region to represent the bounced material */
4318 result = RegionFactory::create (srcs, 0,
4319 srcs.front()->length(srcs.front()->timeline_position()),
4320 region_name_from_path (srcs.front()->name(), true));
4325 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4326 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4329 afs->mark_for_remove ();
4332 (*src)->drop_references ();
4336 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4337 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4340 afs->done_with_peakfile_writes ();
4344 unblock_processing ();
4350 Session::get_silent_buffers (ChanCount count)
4352 assert(_silent_buffers->available() >= count);
4353 _silent_buffers->set_count(count);
4355 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4356 for (size_t i= 0; i < count.get(*t); ++i) {
4357 _silent_buffers->get(*t, i).clear();
4361 return *_silent_buffers;
4365 Session::get_scratch_buffers (ChanCount count)
4367 if (count != ChanCount::ZERO) {
4368 assert(_scratch_buffers->available() >= count);
4369 _scratch_buffers->set_count(count);
4371 _scratch_buffers->set_count (_scratch_buffers->available());
4374 return *_scratch_buffers;
4378 Session::get_mix_buffers (ChanCount count)
4380 assert(_mix_buffers->available() >= count);
4381 _mix_buffers->set_count(count);
4382 return *_mix_buffers;
4386 Session::ntracks () const
4389 shared_ptr<RouteList> r = routes.reader ();
4391 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4392 if (boost::dynamic_pointer_cast<Track> (*i)) {
4401 Session::nbusses () const
4404 shared_ptr<RouteList> r = routes.reader ();
4406 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4407 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4416 Session::add_automation_list(AutomationList *al)
4418 automation_lists[al->id()] = al;
4422 Session::compute_initial_length ()
4424 return _engine.frame_rate() * 60 * 5;
4428 Session::sync_order_keys (std::string const & base)
4430 if (!Config->get_sync_all_route_ordering()) {
4431 /* leave order keys as they are */
4435 boost::shared_ptr<RouteList> r = routes.reader ();
4437 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4438 (*i)->sync_order_keys (base);
4441 Route::SyncOrderKeys (base); // EMIT SIGNAL
4445 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4447 Session::have_rec_enabled_diskstream () const
4449 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4452 /** Update the state of our rec-enabled diskstreams flag */
4454 Session::update_have_rec_enabled_diskstream ()
4456 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4457 DiskstreamList::iterator i = dsl->begin ();
4458 while (i != dsl->end () && (*i)->record_enabled () == false) {
4462 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4464 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4466 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4467 RecordStateChanged (); /* EMIT SIGNAL */
4472 Session::listen_position_changed ()
4476 switch (Config->get_listen_position()) {
4477 case AfterFaderListen:
4481 case PreFaderListen:
4486 boost::shared_ptr<RouteList> r = routes.reader ();
4488 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4489 (*i)->put_control_outs_at (p);
4494 Session::solo_control_mode_changed ()
4496 /* cancel all solo or all listen when solo control mode changes */
4498 if (Config->get_solo_control_is_listen_control()) {
4499 set_all_solo (false);
4501 set_all_listen (false);
4506 Session::route_group_changed ()
4508 RouteGroupChanged (); /* EMIT SIGNAL */
4512 Session::get_available_sync_options () const
4514 vector<SyncSource> ret;
4516 ret.push_back (JACK);
4519 ret.push_back (MTC);
4522 if (midi_clock_port()) {
4523 ret.push_back (MIDIClock);
4529 boost::shared_ptr<RouteList>
4530 Session::get_routes_with_regions_at (nframes64_t const p) const
4532 shared_ptr<RouteList> r = routes.reader ();
4533 shared_ptr<RouteList> rl (new RouteList);
4535 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4536 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4541 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4546 boost::shared_ptr<Playlist> pl = ds->playlist ();
4551 if (pl->has_region_at (p)) {