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 update_latency_compensation (false, false);
2388 /* get rid of it from the dead wood collection in the route list manager */
2390 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2394 /* try to cause everyone to drop their references */
2396 route->drop_references ();
2398 sync_order_keys (N_("session"));
2400 /* save the new state of the world */
2402 if (save_state (_current_snapshot_name)) {
2403 save_history (_current_snapshot_name);
2408 Session::route_mute_changed (void* /*src*/)
2414 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2416 boost::shared_ptr<Route> route = wpr.lock();
2418 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2422 if (route->listening()) {
2424 } else if (_listen_cnt > 0) {
2430 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2432 if (solo_update_disabled) {
2437 boost::shared_ptr<Route> route = wpr.lock ();
2440 /* should not happen */
2441 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2445 shared_ptr<RouteList> r = routes.reader ();
2448 if (route->self_soloed()) {
2454 /* now mod the solo level of all other routes except master & control outs
2455 so that they will be silent if appropriate.
2458 solo_update_disabled = true;
2460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2461 bool via_sends_only;
2464 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2466 } else if ((*i)->feeds (route, &via_sends_only)) {
2467 if (!via_sends_only) {
2468 (*i)->mod_solo_by_others (delta);
2473 /* make sure master is never muted by solo */
2475 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2476 _master_out->mod_solo_by_others (1);
2479 /* ditto for control outs make sure master is never muted by solo */
2481 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2482 _control_out->mod_solo_by_others (1);
2485 solo_update_disabled = false;
2486 update_route_solo_state (r);
2487 SoloChanged (); /* EMIT SIGNAL */
2492 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2494 /* now figure out if anything that matters is soloed */
2496 bool something_soloed = false;
2499 r = routes.reader();
2502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2503 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2504 something_soloed = true;
2509 if (something_soloed != _non_soloed_outs_muted) {
2510 _non_soloed_outs_muted = something_soloed;
2511 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2515 boost::shared_ptr<RouteList>
2516 Session::get_routes_with_internal_returns() const
2518 shared_ptr<RouteList> r = routes.reader ();
2519 boost::shared_ptr<RouteList> rl (new RouteList);
2521 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2522 if ((*i)->internal_return ()) {
2530 Session::route_by_name (string name)
2532 shared_ptr<RouteList> r = routes.reader ();
2534 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2535 if ((*i)->name() == name) {
2540 return shared_ptr<Route> ((Route*) 0);
2544 Session::route_by_id (PBD::ID id)
2546 shared_ptr<RouteList> r = routes.reader ();
2548 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2549 if ((*i)->id() == id) {
2554 return shared_ptr<Route> ((Route*) 0);
2558 Session::route_by_remote_id (uint32_t id)
2560 shared_ptr<RouteList> r = routes.reader ();
2562 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2563 if ((*i)->remote_control_id() == id) {
2568 return shared_ptr<Route> ((Route*) 0);
2572 Session::find_current_end ()
2574 if (_state_of_the_state & Loading) {
2578 nframes_t max = get_maximum_extent ();
2580 if (max > end_location->end()) {
2581 end_location->set_end (max);
2583 DurationChanged(); /* EMIT SIGNAL */
2588 Session::get_maximum_extent () const
2593 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2595 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2596 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2598 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2599 if ((me = pl->get_maximum_extent()) > max) {
2607 boost::shared_ptr<Diskstream>
2608 Session::diskstream_by_name (string name)
2610 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2612 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2613 if ((*i)->name() == name) {
2618 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2621 boost::shared_ptr<Diskstream>
2622 Session::diskstream_by_id (const PBD::ID& id)
2624 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2626 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2627 if ((*i)->id() == id) {
2632 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2635 /* Region management */
2638 Session::new_region_name (string old)
2640 string::size_type last_period;
2642 string::size_type len = old.length() + 64;
2645 if ((last_period = old.find_last_of ('.')) == string::npos) {
2647 /* no period present - add one explicitly */
2650 last_period = old.length() - 1;
2655 number = atoi (old.substr (last_period+1).c_str());
2659 while (number < (UINT_MAX-1)) {
2661 RegionList::const_iterator i;
2666 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2669 for (i = regions.begin(); i != regions.end(); ++i) {
2670 if (i->second->name() == sbuf) {
2675 if (i == regions.end()) {
2680 if (number != (UINT_MAX-1)) {
2684 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2689 Session::region_name (string& result, string base, bool newlevel)
2694 if (base.find("/") != string::npos) {
2695 base = base.substr(base.find_last_of("/") + 1);
2700 Glib::Mutex::Lock lm (region_lock);
2702 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2711 string::size_type pos;
2713 pos = base.find_last_of ('.');
2715 /* pos may be npos, but then we just use entire base */
2717 subbase = base.substr (0, pos);
2722 Glib::Mutex::Lock lm (region_lock);
2724 map<string,uint32_t>::iterator x;
2728 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2730 region_name_map[subbase] = 1;
2733 snprintf (buf, sizeof (buf), ".%d", x->second);
2744 Session::add_region (boost::shared_ptr<Region> region)
2746 vector<boost::shared_ptr<Region> > v;
2747 v.push_back (region);
2752 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2757 Glib::Mutex::Lock lm (region_lock);
2759 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2761 boost::shared_ptr<Region> region = *ii;
2765 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2769 RegionList::iterator x;
2771 for (x = regions.begin(); x != regions.end(); ++x) {
2773 if (region->region_list_equivalent (x->second)) {
2778 if (x == regions.end()) {
2780 pair<RegionList::key_type,RegionList::mapped_type> entry;
2782 entry.first = region->id();
2783 entry.second = region;
2785 pair<RegionList::iterator,bool> x = regions.insert (entry);
2797 /* mark dirty because something has changed even if we didn't
2798 add the region to the region list.
2805 vector<boost::weak_ptr<Region> > v;
2806 boost::shared_ptr<Region> first_r;
2808 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2810 boost::shared_ptr<Region> region = *ii;
2814 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2817 v.push_back (region);
2824 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2825 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2827 update_region_name_map (region);
2831 RegionsAdded (v); /* EMIT SIGNAL */
2837 Session::update_region_name_map (boost::shared_ptr<Region> region)
2839 string::size_type last_period = region->name().find_last_of ('.');
2841 if (last_period != string::npos && last_period < region->name().length() - 1) {
2843 string base = region->name().substr (0, last_period);
2844 string number = region->name().substr (last_period+1);
2845 map<string,uint32_t>::iterator x;
2847 /* note that if there is no number, we get zero from atoi,
2851 region_name_map[base] = atoi (number);
2856 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2858 boost::shared_ptr<Region> region (weak_region.lock ());
2864 if (what_changed & Region::HiddenChanged) {
2865 /* relay hidden changes */
2866 RegionHiddenChange (region);
2869 if (what_changed & NameChanged) {
2870 update_region_name_map (region);
2875 Session::remove_region (boost::weak_ptr<Region> weak_region)
2877 RegionList::iterator i;
2878 boost::shared_ptr<Region> region (weak_region.lock ());
2884 bool removed = false;
2887 Glib::Mutex::Lock lm (region_lock);
2889 if ((i = regions.find (region->id())) != regions.end()) {
2895 /* mark dirty because something has changed even if we didn't
2896 remove the region from the region list.
2902 RegionRemoved(region); /* EMIT SIGNAL */
2906 boost::shared_ptr<Region>
2907 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2909 RegionList::iterator i;
2910 boost::shared_ptr<Region> region;
2912 Glib::Mutex::Lock lm (region_lock);
2914 for (i = regions.begin(); i != regions.end(); ++i) {
2918 if (region->whole_file()) {
2920 if (child->source_equivalent (region)) {
2926 return boost::shared_ptr<Region> ();
2930 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2932 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2933 (*i)->get_region_list_equivalent_regions (region, result);
2937 Session::destroy_region (boost::shared_ptr<Region> region)
2939 vector<boost::shared_ptr<Source> > srcs;
2942 if (region->playlist()) {
2943 region->playlist()->destroy_region (region);
2946 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2947 srcs.push_back (region->source (n));
2951 region->drop_references ();
2953 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2955 (*i)->mark_for_remove ();
2956 (*i)->drop_references ();
2958 cerr << "source was not used by any playlist\n";
2965 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2967 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2968 destroy_region (*i);
2974 Session::remove_last_capture ()
2976 list<boost::shared_ptr<Region> > r;
2978 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2980 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2981 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2984 r.insert (r.end(), l.begin(), l.end());
2989 destroy_regions (r);
2991 save_state (_current_snapshot_name);
2997 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
3003 /* Source Management */
3006 Session::add_source (boost::shared_ptr<Source> source)
3008 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
3009 pair<SourceMap::iterator,bool> result;
3011 entry.first = source->id();
3012 entry.second = source;
3015 Glib::Mutex::Lock lm (source_lock);
3016 result = sources.insert (entry);
3019 if (result.second) {
3020 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3024 boost::shared_ptr<AudioFileSource> afs;
3026 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3027 if (Config->get_auto_analyse_audio()) {
3028 Analyser::queue_source_for_analysis (source, false);
3034 Session::remove_source (boost::weak_ptr<Source> src)
3036 SourceMap::iterator i;
3037 boost::shared_ptr<Source> source = src.lock();
3044 Glib::Mutex::Lock lm (source_lock);
3046 if ((i = sources.find (source->id())) != sources.end()) {
3051 if (!_state_of_the_state & InCleanup) {
3053 /* save state so we don't end up with a session file
3054 referring to non-existent sources.
3057 save_state (_current_snapshot_name);
3061 /** Return the number of playlists (not regions) that contain @a src */
3063 Session::source_use_count (boost::shared_ptr<const Source> src) const
3066 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3067 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3068 r != (*p)->region_list().end(); ++r) {
3069 if ((*r)->uses_source(src)) {
3078 boost::shared_ptr<Source>
3079 Session::source_by_id (const PBD::ID& id)
3081 Glib::Mutex::Lock lm (source_lock);
3082 SourceMap::iterator i;
3083 boost::shared_ptr<Source> source;
3085 if ((i = sources.find (id)) != sources.end()) {
3092 boost::shared_ptr<Source>
3093 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3095 Glib::Mutex::Lock lm (source_lock);
3097 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3098 cerr << "comparing " << path << " with " << i->second->name() << endl;
3099 boost::shared_ptr<AudioFileSource> afs
3100 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3102 if (afs && afs->path() == path && chn == afs->channel()) {
3106 return boost::shared_ptr<Source>();
3111 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3114 string old_basename = PBD::basename_nosuffix (oldname);
3115 string new_legalized = legalize_for_path (newname);
3117 /* note: we know (or assume) the old path is already valid */
3121 /* destructive file sources have a name of the form:
3123 /path/to/Tnnnn-NAME(%[LR])?.wav
3125 the task here is to replace NAME with the new name.
3128 /* find last slash */
3132 string::size_type slash;
3133 string::size_type dash;
3135 if ((slash = path.find_last_of ('/')) == string::npos) {
3139 dir = path.substr (0, slash+1);
3141 /* '-' is not a legal character for the NAME part of the path */
3143 if ((dash = path.find_last_of ('-')) == string::npos) {
3147 prefix = path.substr (slash+1, dash-(slash+1));
3152 path += new_legalized;
3153 path += ".wav"; /* XXX gag me with a spoon */
3157 /* non-destructive file sources have a name of the form:
3159 /path/to/NAME-nnnnn(%[LR])?.ext
3161 the task here is to replace NAME with the new name.
3166 string::size_type slash;
3167 string::size_type dash;
3168 string::size_type postfix;
3170 /* find last slash */
3172 if ((slash = path.find_last_of ('/')) == string::npos) {
3176 dir = path.substr (0, slash+1);
3178 /* '-' is not a legal character for the NAME part of the path */
3180 if ((dash = path.find_last_of ('-')) == string::npos) {
3184 suffix = path.substr (dash+1);
3186 // Suffix is now everything after the dash. Now we need to eliminate
3187 // the nnnnn part, which is done by either finding a '%' or a '.'
3189 postfix = suffix.find_last_of ("%");
3190 if (postfix == string::npos) {
3191 postfix = suffix.find_last_of ('.');
3194 if (postfix != string::npos) {
3195 suffix = suffix.substr (postfix);
3197 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3201 const uint32_t limit = 10000;
3202 char buf[PATH_MAX+1];
3204 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3206 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3208 if (access (buf, F_OK) != 0) {
3216 error << "FATAL ERROR! Could not find a " << endl;
3224 /** Return the full path (in some session directory) for a new within-session source.
3225 * \a name must be a session-unique name that does not contain slashes
3226 * (e.g. as returned by new_*_source_name)
3229 Session::new_source_path_from_name (DataType type, const string& name)
3231 assert(name.find("/") == string::npos);
3233 SessionDirectory sdir(get_best_session_directory_for_new_source());
3236 if (type == DataType::AUDIO) {
3237 p = sdir.sound_path();
3238 } else if (type == DataType::MIDI) {
3239 p = sdir.midi_path();
3241 error << "Unknown source type, unable to create file path" << endmsg;
3246 return p.to_string();
3250 Session::peak_path (Glib::ustring base) const
3252 sys::path peakfile_path(_session_dir->peak_path());
3253 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3254 return peakfile_path.to_string();
3257 /** Return a unique name based on \a base for a new internal audio source */
3259 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3263 char buf[PATH_MAX+1];
3264 const uint32_t limit = 10000;
3268 legalized = legalize_for_path (base);
3270 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3271 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3273 vector<space_and_path>::iterator i;
3274 uint32_t existing = 0;
3276 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3278 SessionDirectory sdir((*i).path);
3280 spath = sdir.sound_path().to_string();
3285 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3286 spath.c_str(), cnt, legalized.c_str());
3287 } else if (nchan == 2) {
3289 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3290 spath.c_str(), cnt, legalized.c_str());
3292 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3293 spath.c_str(), cnt, legalized.c_str());
3295 } else if (nchan < 26) {
3296 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3297 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3299 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3300 spath.c_str(), cnt, legalized.c_str());
3309 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3310 } else if (nchan == 2) {
3312 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3314 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3316 } else if (nchan < 26) {
3317 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3319 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3323 if (sys::exists(buf)) {
3329 if (existing == 0) {
3334 error << string_compose(
3335 _("There are already %1 recordings for %2, which I consider too many."),
3336 limit, base) << endmsg;
3338 throw failed_constructor();
3342 return Glib::path_get_basename(buf);
3345 /** Create a new within-session audio source */
3346 boost::shared_ptr<AudioFileSource>
3347 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3349 const size_t n_chans = ds.n_channels().n_audio();
3350 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3351 const string path = new_source_path_from_name(DataType::AUDIO, name);
3353 return boost::dynamic_pointer_cast<AudioFileSource> (
3354 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3357 /** Return a unique name based on \a base for a new internal MIDI source */
3359 Session::new_midi_source_name (const string& base)
3362 char buf[PATH_MAX+1];
3363 const uint32_t limit = 10000;
3367 legalized = legalize_for_path (base);
3369 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3370 for (cnt = 1; cnt <= limit; ++cnt) {
3372 vector<space_and_path>::iterator i;
3373 uint32_t existing = 0;
3375 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3377 SessionDirectory sdir((*i).path);
3379 sys::path p = sdir.midi_path();
3382 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3384 if (sys::exists (buf)) {
3389 if (existing == 0) {
3394 error << string_compose(
3395 _("There are already %1 recordings for %2, which I consider too many."),
3396 limit, base) << endmsg;
3398 throw failed_constructor();
3402 return Glib::path_get_basename(buf);
3406 /** Create a new within-session MIDI source */
3407 boost::shared_ptr<MidiSource>
3408 Session::create_midi_source_for_session (MidiDiskstream& ds)
3410 const string name = new_midi_source_name (ds.name());
3411 const string path = new_source_path_from_name (DataType::MIDI, name);
3413 return boost::dynamic_pointer_cast<SMFSource> (
3414 SourceFactory::createWritable (
3415 DataType::MIDI, *this, path, false, frame_rate()));
3419 /* Playlist management */
3421 boost::shared_ptr<Playlist>
3422 Session::playlist_by_name (string name)
3424 Glib::Mutex::Lock lm (playlist_lock);
3425 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3426 if ((*i)->name() == name) {
3430 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3431 if ((*i)->name() == name) {
3436 return boost::shared_ptr<Playlist>();
3440 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3442 Glib::Mutex::Lock lm (playlist_lock);
3443 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3444 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3445 list.push_back (*i);
3448 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3449 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3450 list.push_back (*i);
3456 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3458 if (playlist->hidden()) {
3463 Glib::Mutex::Lock lm (playlist_lock);
3464 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3465 playlists.insert (playlists.begin(), playlist);
3466 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3467 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3472 playlist->release();
3477 PlaylistAdded (playlist); /* EMIT SIGNAL */
3481 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3484 Glib::Mutex::Lock lm (playlist_lock);
3485 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3488 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3495 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3497 boost::shared_ptr<Playlist> pl(wpl.lock());
3503 PlaylistList::iterator x;
3506 /* its not supposed to be visible */
3511 Glib::Mutex::Lock lm (playlist_lock);
3515 unused_playlists.insert (pl);
3517 if ((x = playlists.find (pl)) != playlists.end()) {
3518 playlists.erase (x);
3524 playlists.insert (pl);
3526 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3527 unused_playlists.erase (x);
3534 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3536 if (_state_of_the_state & Deletion) {
3540 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3547 Glib::Mutex::Lock lm (playlist_lock);
3549 PlaylistList::iterator i;
3551 i = find (playlists.begin(), playlists.end(), playlist);
3552 if (i != playlists.end()) {
3553 playlists.erase (i);
3556 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3557 if (i != unused_playlists.end()) {
3558 unused_playlists.erase (i);
3565 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3569 Session::set_audition (boost::shared_ptr<Region> r)
3571 pending_audition_region = r;
3572 add_post_transport_work (PostTransportAudition);
3573 _butler->schedule_transport_work ();
3577 Session::audition_playlist ()
3579 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3580 ev->region.reset ();
3585 Session::non_realtime_set_audition ()
3587 if (!pending_audition_region) {
3588 auditioner->audition_current_playlist ();
3590 auditioner->audition_region (pending_audition_region);
3591 pending_audition_region.reset ();
3593 AuditionActive (true); /* EMIT SIGNAL */
3597 Session::audition_region (boost::shared_ptr<Region> r)
3599 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3605 Session::cancel_audition ()
3607 if (auditioner->active()) {
3608 auditioner->cancel_audition ();
3609 AuditionActive (false); /* EMIT SIGNAL */
3614 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3616 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3620 Session::remove_empty_sounds ()
3622 vector<string> audio_filenames;
3624 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3626 Glib::Mutex::Lock lm (source_lock);
3628 TapeFileMatcher tape_file_matcher;
3630 remove_if (audio_filenames.begin(), audio_filenames.end(),
3631 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3633 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3635 sys::path audio_file_path (_session_dir->sound_path());
3637 audio_file_path /= *i;
3639 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3643 sys::remove (audio_file_path);
3644 const string peakfile = peak_path (audio_file_path.to_string());
3645 sys::remove (peakfile);
3647 catch (const sys::filesystem_error& err)
3649 error << err.what() << endmsg;
3656 Session::is_auditioning () const
3658 /* can be called before we have an auditioner object */
3660 return auditioner->active();
3667 Session::set_all_solo (bool yn)
3669 shared_ptr<RouteList> r = routes.reader ();
3671 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3672 if (!(*i)->is_hidden()) {
3673 (*i)->set_solo (yn, this);
3681 Session::set_all_listen (bool yn)
3683 shared_ptr<RouteList> r = routes.reader ();
3685 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3686 if (!(*i)->is_hidden()) {
3687 (*i)->set_listen (yn, this);
3695 Session::set_all_mute (bool yn)
3697 shared_ptr<RouteList> r = routes.reader ();
3699 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3700 if (!(*i)->is_hidden()) {
3701 (*i)->set_mute (yn, this);
3709 Session::n_diskstreams () const
3713 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3715 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3716 if (!(*i)->hidden()) {
3724 Session::graph_reordered ()
3726 /* don't do this stuff if we are setting up connections
3727 from a set_state() call or creating new tracks. Ditto for deletion.
3730 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3734 /* every track/bus asked for this to be handled but it was deferred because
3735 we were connecting. do it now.
3738 request_input_change_handling ();
3742 /* force all diskstreams to update their capture offset values to
3743 reflect any changes in latencies within the graph.
3746 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3748 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3749 (*i)->set_capture_offset ();
3754 Session::record_disenable_all ()
3756 record_enable_change_all (false);
3760 Session::record_enable_all ()
3762 record_enable_change_all (true);
3766 Session::record_enable_change_all (bool yn)
3768 shared_ptr<RouteList> r = routes.reader ();
3770 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3771 boost::shared_ptr<Track> t;
3773 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3774 t->set_record_enable (yn, this);
3778 /* since we don't keep rec-enable state, don't mark session dirty */
3782 Session::add_processor (Processor* processor)
3784 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3789 Session::remove_processor (Processor* processor)
3793 PortInsert* port_insert;
3795 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3796 insert_bitset[port_insert->bit_slot()] = false;
3797 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3798 send_bitset[send->bit_slot()] = false;
3799 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3800 return_bitset[retrn->bit_slot()] = false;
3807 Session::available_capture_duration ()
3809 float sample_bytes_on_disk = 4.0; // keep gcc happy
3811 switch (config.get_native_file_data_format()) {
3813 sample_bytes_on_disk = 4.0;
3817 sample_bytes_on_disk = 3.0;
3821 sample_bytes_on_disk = 2.0;
3825 /* impossible, but keep some gcc versions happy */
3826 fatal << string_compose (_("programming error: %1"),
3827 X_("illegal native file data format"))
3832 double scale = 4096.0 / sample_bytes_on_disk;
3834 if (_total_free_4k_blocks * scale > (double) max_frames) {
3838 return (nframes_t) floor (_total_free_4k_blocks * scale);
3842 Session::add_bundle (shared_ptr<Bundle> bundle)
3845 RCUWriter<BundleList> writer (_bundles);
3846 boost::shared_ptr<BundleList> b = writer.get_copy ();
3847 b->push_back (bundle);
3850 BundleAdded (bundle); /* EMIT SIGNAL */
3856 Session::remove_bundle (shared_ptr<Bundle> bundle)
3858 bool removed = false;
3861 RCUWriter<BundleList> writer (_bundles);
3862 boost::shared_ptr<BundleList> b = writer.get_copy ();
3863 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3865 if (i != b->end()) {
3872 BundleRemoved (bundle); /* EMIT SIGNAL */
3879 Session::bundle_by_name (string name) const
3881 boost::shared_ptr<BundleList> b = _bundles.reader ();
3883 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3884 if ((*i)->name() == name) {
3889 return boost::shared_ptr<Bundle> ();
3893 Session::tempo_map_changed (Change)
3897 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3898 (*i)->update_after_tempo_map_change ();
3901 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3902 (*i)->update_after_tempo_map_change ();
3908 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3909 * the given count with the current block size.
3912 Session::ensure_buffers (ChanCount howmany)
3914 if (current_block_size == 0) {
3915 return; // too early? (is this ok?)
3918 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3919 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3920 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3921 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3922 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3925 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3929 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3931 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3932 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3937 Session::next_insert_id ()
3939 /* this doesn't really loop forever. just think about it */
3942 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3943 if (!insert_bitset[n]) {
3944 insert_bitset[n] = true;
3950 /* none available, so resize and try again */
3952 insert_bitset.resize (insert_bitset.size() + 16, false);
3957 Session::next_send_id ()
3959 /* this doesn't really loop forever. just think about it */
3962 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3963 if (!send_bitset[n]) {
3964 send_bitset[n] = true;
3970 /* none available, so resize and try again */
3972 send_bitset.resize (send_bitset.size() + 16, false);
3977 Session::next_return_id ()
3979 /* this doesn't really loop forever. just think about it */
3982 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3983 if (!return_bitset[n]) {
3984 return_bitset[n] = true;
3990 /* none available, so resize and try again */
3992 return_bitset.resize (return_bitset.size() + 16, false);
3997 Session::mark_send_id (uint32_t id)
3999 if (id >= send_bitset.size()) {
4000 send_bitset.resize (id+16, false);
4002 if (send_bitset[id]) {
4003 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
4005 send_bitset[id] = true;
4009 Session::mark_return_id (uint32_t id)
4011 if (id >= return_bitset.size()) {
4012 return_bitset.resize (id+16, false);
4014 if (return_bitset[id]) {
4015 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
4017 return_bitset[id] = true;
4021 Session::mark_insert_id (uint32_t id)
4023 if (id >= insert_bitset.size()) {
4024 insert_bitset.resize (id+16, false);
4026 if (insert_bitset[id]) {
4027 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4029 insert_bitset[id] = true;
4032 /* Named Selection management */
4035 Session::named_selection_by_name (string name)
4037 Glib::Mutex::Lock lm (named_selection_lock);
4038 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
4039 if ((*i)->name == name) {
4047 Session::add_named_selection (NamedSelection* named_selection)
4050 Glib::Mutex::Lock lm (named_selection_lock);
4051 named_selections.insert (named_selections.begin(), named_selection);
4054 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4060 NamedSelectionAdded (); /* EMIT SIGNAL */
4064 Session::remove_named_selection (NamedSelection* named_selection)
4066 bool removed = false;
4069 Glib::Mutex::Lock lm (named_selection_lock);
4071 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4073 if (i != named_selections.end()) {
4075 named_selections.erase (i);
4082 NamedSelectionRemoved (); /* EMIT SIGNAL */
4087 Session::reset_native_file_format ()
4089 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4091 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4092 (*i)->reset_write_sources (false);
4097 Session::route_name_unique (string n) const
4099 shared_ptr<RouteList> r = routes.reader ();
4101 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4102 if ((*i)->name() == n) {
4111 Session::route_name_internal (string n) const
4113 if (auditioner && auditioner->name() == n) {
4117 if (_click_io && _click_io->name() == n) {
4125 Session::n_playlists () const
4127 Glib::Mutex::Lock lm (playlist_lock);
4128 return playlists.size();
4132 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4134 if (!force && howmany <= _npan_buffers) {
4138 if (_pan_automation_buffer) {
4140 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4141 delete [] _pan_automation_buffer[i];
4144 delete [] _pan_automation_buffer;
4147 _pan_automation_buffer = new pan_t*[howmany];
4149 for (uint32_t i = 0; i < howmany; ++i) {
4150 _pan_automation_buffer[i] = new pan_t[nframes];
4153 _npan_buffers = howmany;
4157 Session::freeze (InterThreadInfo& itt)
4159 shared_ptr<RouteList> r = routes.reader ();
4161 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4163 boost::shared_ptr<Track> t;
4165 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4166 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4176 boost::shared_ptr<Region>
4177 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4178 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4179 InterThreadInfo& itt, bool enable_processing)
4181 boost::shared_ptr<Region> result;
4182 boost::shared_ptr<Playlist> playlist;
4183 boost::shared_ptr<AudioFileSource> fsource;
4185 char buf[PATH_MAX+1];
4186 ChanCount nchans(track.audio_diskstream()->n_channels());
4188 nframes_t this_chunk;
4191 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4192 const string sound_dir = sdir.sound_path().to_string();
4193 nframes_t len = end - start;
4196 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4197 end, start) << endmsg;
4201 // any bigger than this seems to cause stack overflows in called functions
4202 const nframes_t chunk_size = (128 * 1024)/4;
4204 // block all process callback handling
4206 block_processing ();
4208 /* call tree *MUST* hold route_lock */
4210 if ((playlist = track.diskstream()->playlist()) == 0) {
4214 /* external redirects will be a problem */
4216 if (track.has_external_redirects()) {
4220 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4222 for (x = 0; x < 99999; ++x) {
4223 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4224 if (access (buf, F_OK) != 0) {
4230 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4235 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4236 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4239 catch (failed_constructor& err) {
4240 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4244 srcs.push_back (fsource);
4247 /* XXX need to flush all redirects */
4252 /* create a set of reasonably-sized buffers */
4253 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4254 buffers.set_count(nchans);
4256 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4257 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4259 afs->prepare_for_peakfile_writes ();
4262 while (to_do && !itt.cancel) {
4264 this_chunk = min (to_do, chunk_size);
4266 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4271 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4272 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4275 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4281 start += this_chunk;
4282 to_do -= this_chunk;
4284 itt.progress = (float) (1.0 - ((double) to_do / len));
4293 xnow = localtime (&now);
4295 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4296 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4299 afs->update_header (position, *xnow, now);
4300 afs->flush_header ();
4304 /* construct a region to represent the bounced material */
4306 result = RegionFactory::create (srcs, 0,
4307 srcs.front()->length(srcs.front()->timeline_position()),
4308 region_name_from_path (srcs.front()->name(), true));
4313 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4314 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4317 afs->mark_for_remove ();
4320 (*src)->drop_references ();
4324 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4325 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4328 afs->done_with_peakfile_writes ();
4332 unblock_processing ();
4338 Session::get_silent_buffers (ChanCount count)
4340 assert(_silent_buffers->available() >= count);
4341 _silent_buffers->set_count(count);
4343 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4344 for (size_t i= 0; i < count.get(*t); ++i) {
4345 _silent_buffers->get(*t, i).clear();
4349 return *_silent_buffers;
4353 Session::get_scratch_buffers (ChanCount count)
4355 if (count != ChanCount::ZERO) {
4356 assert(_scratch_buffers->available() >= count);
4357 _scratch_buffers->set_count(count);
4359 _scratch_buffers->set_count (_scratch_buffers->available());
4362 return *_scratch_buffers;
4366 Session::get_mix_buffers (ChanCount count)
4368 assert(_mix_buffers->available() >= count);
4369 _mix_buffers->set_count(count);
4370 return *_mix_buffers;
4374 Session::ntracks () const
4377 shared_ptr<RouteList> r = routes.reader ();
4379 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4380 if (boost::dynamic_pointer_cast<Track> (*i)) {
4389 Session::nbusses () const
4392 shared_ptr<RouteList> r = routes.reader ();
4394 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4395 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4404 Session::add_automation_list(AutomationList *al)
4406 automation_lists[al->id()] = al;
4410 Session::compute_initial_length ()
4412 return _engine.frame_rate() * 60 * 5;
4416 Session::sync_order_keys (std::string const & base)
4418 if (!Config->get_sync_all_route_ordering()) {
4419 /* leave order keys as they are */
4423 boost::shared_ptr<RouteList> r = routes.reader ();
4425 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4426 (*i)->sync_order_keys (base);
4429 Route::SyncOrderKeys (base); // EMIT SIGNAL
4433 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4435 Session::have_rec_enabled_diskstream () const
4437 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4440 /** Update the state of our rec-enabled diskstreams flag */
4442 Session::update_have_rec_enabled_diskstream ()
4444 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4445 DiskstreamList::iterator i = dsl->begin ();
4446 while (i != dsl->end () && (*i)->record_enabled () == false) {
4450 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4452 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4454 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4455 RecordStateChanged (); /* EMIT SIGNAL */
4460 Session::listen_position_changed ()
4464 switch (Config->get_listen_position()) {
4465 case AfterFaderListen:
4469 case PreFaderListen:
4474 boost::shared_ptr<RouteList> r = routes.reader ();
4476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4477 (*i)->put_control_outs_at (p);
4482 Session::solo_control_mode_changed ()
4484 /* cancel all solo or all listen when solo control mode changes */
4486 if (Config->get_solo_control_is_listen_control()) {
4487 set_all_solo (false);
4489 set_all_listen (false);
4494 Session::route_group_changed ()
4496 RouteGroupChanged (); /* EMIT SIGNAL */
4500 Session::get_available_sync_options () const
4502 vector<SyncSource> ret;
4504 ret.push_back (JACK);
4507 ret.push_back (MTC);
4510 if (midi_clock_port()) {
4511 ret.push_back (MIDIClock);
4517 boost::shared_ptr<RouteList>
4518 Session::get_routes_with_regions_at (nframes64_t const p) const
4520 shared_ptr<RouteList> r = routes.reader ();
4521 shared_ptr<RouteList> rl (new RouteList);
4523 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4524 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4529 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4534 boost::shared_ptr<Playlist> pl = ds->playlist ();
4539 if (pl->has_region_at (p)) {