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;
103 bool Session::_disable_all_loaded_plugins = false;
105 sigc::signal<void,std::string> Session::Dialog;
106 sigc::signal<int> Session::AskAboutPendingState;
107 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
108 sigc::signal<void> Session::SendFeedback;
110 sigc::signal<void> Session::TimecodeOffsetChanged;
111 sigc::signal<void> Session::StartTimeChanged;
112 sigc::signal<void> Session::EndTimeChanged;
113 sigc::signal<void> Session::AutoBindingOn;
114 sigc::signal<void> Session::AutoBindingOff;
115 sigc::signal<void, std::string, std::string> Session::Exported;
117 Session::Session (AudioEngine &eng,
118 const string& fullpath,
119 const string& snapshot_name,
123 _target_transport_speed (0.0),
124 _requested_return_frame (-1),
125 _scratch_buffers(new BufferSet()),
126 _silent_buffers(new BufferSet()),
127 _mix_buffers(new BufferSet()),
129 _mmc_port (default_mmc_port),
130 _mtc_port (default_mtc_port),
131 _midi_port (default_midi_port),
132 _midi_clock_port (default_midi_clock_port),
133 _session_dir (new SessionDirectory(fullpath)),
134 pending_events (2048),
136 _butler (new Butler (this)),
137 _post_transport_work (0),
138 _send_timecode_update (false),
139 midi_thread (pthread_t (0)),
140 midi_requests (128), // the size of this should match the midi request pool size
141 diskstreams (new DiskstreamList),
142 routes (new RouteList),
143 _total_free_4k_blocks (0),
144 _bundles (new BundleList),
145 _bundle_xml_node (0),
148 click_emphasis_data (0),
150 _metadata (new SessionMetadata()),
151 _have_rec_enabled_diskstream (false)
156 interpolation.add_channel_to (0, 0);
158 if (!eng.connected()) {
159 throw failed_constructor();
162 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
164 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
165 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
167 first_stage_init (fullpath, snapshot_name);
169 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
172 if (create (new_session, mix_template, compute_initial_length())) {
174 throw failed_constructor ();
178 if (second_stage_init (new_session)) {
180 throw failed_constructor ();
183 store_recent_sessions(_name, _path);
185 bool was_dirty = dirty();
187 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
189 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
190 config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true));
193 DirtyChanged (); /* EMIT SIGNAL */
197 Session::Session (AudioEngine &eng,
199 string snapshot_name,
200 AutoConnectOption input_ac,
201 AutoConnectOption output_ac,
202 uint32_t control_out_channels,
203 uint32_t master_out_channels,
204 uint32_t requested_physical_in,
205 uint32_t requested_physical_out,
206 nframes_t initial_length)
209 _target_transport_speed (0.0),
210 _requested_return_frame (-1),
211 _scratch_buffers(new BufferSet()),
212 _silent_buffers(new BufferSet()),
213 _mix_buffers(new BufferSet()),
215 _mmc_port (default_mmc_port),
216 _mtc_port (default_mtc_port),
217 _midi_port (default_midi_port),
218 _midi_clock_port (default_midi_clock_port),
219 _session_dir ( new SessionDirectory(fullpath)),
220 pending_events (2048),
222 _butler (new Butler (this)),
223 _post_transport_work (0),
224 _send_timecode_update (false),
225 midi_thread (pthread_t (0)),
227 diskstreams (new DiskstreamList),
228 routes (new RouteList),
229 _total_free_4k_blocks (0),
230 _bundles (new BundleList),
231 _bundle_xml_node (0),
232 _click_io ((IO *) 0),
234 click_emphasis_data (0),
236 _metadata (new SessionMetadata()),
237 _have_rec_enabled_diskstream (false)
241 interpolation.add_channel_to (0, 0);
243 if (!eng.connected()) {
244 throw failed_constructor();
247 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
249 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
250 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
252 if (n_physical_inputs) {
253 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
256 if (n_physical_outputs) {
257 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
260 first_stage_init (fullpath, snapshot_name);
262 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
265 if (create (new_session, string(), initial_length)) {
267 throw failed_constructor ();
272 /* set up Master Out and Control Out if necessary */
277 if (master_out_channels) {
278 ChanCount count(DataType::AUDIO, master_out_channels);
279 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
280 r->input()->ensure_io (count, false, this);
281 r->output()->ensure_io (count, false, this);
282 r->set_remote_control_id (control_id);
286 /* prohibit auto-connect to master, because there isn't one */
287 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
290 if (control_out_channels) {
291 ChanCount count(DataType::AUDIO, control_out_channels);
292 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
293 r->input()->ensure_io (count, false, this);
294 r->output()->ensure_io (count, false, this);
295 r->set_remote_control_id (control_id++);
301 add_routes (rl, false);
306 if (no_auto_connect()) {
307 input_ac = AutoConnectOption (0);
308 output_ac = AutoConnectOption (0);
311 Config->set_input_auto_connect (input_ac);
312 Config->set_output_auto_connect (output_ac);
314 if (second_stage_init (new_session)) {
316 throw failed_constructor ();
319 store_recent_sessions (_name, _path);
321 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
323 Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false));
334 vector<void*> debug_pointers;
336 /* if we got to here, leaving pending capture state around
340 remove_pending_capture_state ();
342 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
344 _engine.remove_session ();
346 GoingAway (); /* EMIT SIGNAL */
352 /* clear history so that no references to objects are held any more */
356 /* clear state tree so that no references to objects are held any more */
360 /* reset dynamic state version back to default */
362 Stateful::loading_state_version = 0;
364 _butler->terminate_thread ();
365 //terminate_midi_thread ();
367 if (click_data != default_click) {
368 delete [] click_data;
371 if (click_emphasis_data != default_click_emphasis) {
372 delete [] click_emphasis_data;
377 delete _scratch_buffers;
378 delete _silent_buffers;
381 AudioDiskstream::free_working_buffers();
383 Route::SyncOrderKeys.clear();
385 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
386 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
387 NamedSelectionList::iterator tmp;
396 DEBUG_TRACE (DEBUG::Destruction, "delete playlists\n");
397 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
398 PlaylistList::iterator tmp;
403 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
404 (*i)->drop_references ();
405 DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
410 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
411 PlaylistList::iterator tmp;
416 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
417 (*i)->drop_references ();
418 DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %2\n", (*i).use_count()));
424 unused_playlists.clear ();
426 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
427 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
428 RegionList::iterator tmp;
433 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
434 i->second->drop_references ();
435 DEBUG_TRACE(DEBUG::Destruction, string_compose ("\tpost-ref%2\n", i->second.use_count()));
442 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
444 RCUWriter<RouteList> writer (routes);
445 boost::shared_ptr<RouteList> r = writer.get_copy ();
446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
447 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
448 (*i)->drop_references ();
449 DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
450 debug_pointers.push_back ((*i).get());
453 /* writer goes out of scope and updates master */
457 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
459 RCUWriter<DiskstreamList> dwriter (diskstreams);
460 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
461 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
462 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
463 (*i)->drop_references ();
464 DEBUG_TRACE(DEBUG::Destruction, string_compose ("post-ref = %1\n", (*i).use_count()));
468 diskstreams.flush ();
470 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
471 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
472 SourceMap::iterator tmp;
477 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
478 i->second->drop_references ();
479 DEBUG_TRACE(DEBUG::Destruction, string_compose ("\tpost-ref%1\n", i->second.use_count()));
483 cerr << "Pre source clear, we have " << sources.size() << endl;
485 cerr << "Post source clear, we have " << sources.size() << endl;
487 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
488 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
492 Crossfade::set_buffer_size (0);
496 for (vector<void*>::iterator x = debug_pointers.begin(); x != debug_pointers.end(); ++x) {
497 boost_debug_shared_ptr_show (cerr, *x);
502 Session::set_worst_io_latencies ()
504 _worst_output_latency = 0;
505 _worst_input_latency = 0;
507 if (!_engine.connected()) {
511 boost::shared_ptr<RouteList> r = routes.reader ();
513 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
514 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
515 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
520 Session::when_engine_running ()
522 string first_physical_output;
524 BootMessage (_("Set block size and sample rate"));
526 set_block_size (_engine.frames_per_cycle());
527 set_frame_rate (_engine.frame_rate());
529 BootMessage (_("Using configuration"));
531 Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false));
533 /* every time we reconnect, recompute worst case output latencies */
535 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
537 if (synced_to_jack()) {
538 _engine.transport_stop ();
541 if (config.get_jack_time_master()) {
542 _engine.transport_locate (_transport_frame);
550 _click_io.reset (new ClickIO (*this, "click"));
552 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
554 /* existing state for Click */
557 if (Stateful::loading_state_version < 3000) {
558 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
560 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
565 _clicking = Config->get_clicking ();
569 error << _("could not setup Click I/O") << endmsg;
576 /* default state for Click: dual-mono to first 2 physical outputs */
578 for (int physport = 0; physport < 2; ++physport) {
579 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
581 if (physical_output.length()) {
582 if (_click_io->add_port (physical_output, this)) {
583 // relax, even though its an error
588 if (_click_io->n_ports () > ChanCount::ZERO) {
589 _clicking = Config->get_clicking ();
594 catch (failed_constructor& err) {
595 error << _("cannot setup Click I/O") << endmsg;
598 BootMessage (_("Compute I/O Latencies"));
600 set_worst_io_latencies ();
603 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
606 BootMessage (_("Set up standard connections"));
608 /* Create a set of Bundle objects that map
609 to the physical I/O currently available. We create both
610 mono and stereo bundles, so that the common cases of mono
611 and stereo tracks get bundles to put in their mixer strip
612 in / out menus. There may be a nicer way of achieving that;
613 it doesn't really scale that well to higher channel counts
616 /* mono output bundles */
618 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
620 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
622 shared_ptr<Bundle> c (new Bundle (buf, true));
623 c->add_channel (_("mono"));
624 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
629 /* stereo output bundles */
631 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
632 if (np + 1 < n_physical_outputs) {
634 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
635 shared_ptr<Bundle> c (new Bundle (buf, true));
636 c->add_channel (_("L"));
637 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
638 c->add_channel (_("R"));
639 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
645 /* mono input bundles */
647 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
649 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
651 shared_ptr<Bundle> c (new Bundle (buf, false));
652 c->add_channel (_("mono"));
653 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
658 /* stereo input bundles */
660 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
661 if (np + 1 < n_physical_inputs) {
663 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
665 shared_ptr<Bundle> c (new Bundle (buf, false));
666 c->add_channel (_("L"));
667 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
668 c->add_channel (_("R"));
669 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
675 BootMessage (_("Setup signal flow and plugins"));
679 if (!no_auto_connect()) {
681 if (_master_out && Config->get_auto_connect_standard_busses()) {
683 /* if requested auto-connect the outputs to the first N physical ports.
686 uint32_t limit = _master_out->n_outputs().n_total();
688 for (uint32_t n = 0; n < limit; ++n) {
689 Port* p = _master_out->output()->nth (n);
690 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
692 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
693 if (_master_out->output()->connect (p, connect_to, this)) {
694 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
704 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
705 are undefined, at best.
708 /* control out listens to master bus (but ignores it
709 under some conditions)
712 uint32_t limit = _control_out->n_inputs().n_audio();
715 for (uint32_t n = 0; n < limit; ++n) {
716 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
717 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
720 string connect_to = o->name();
721 if (_control_out->input()->connect (p, connect_to, this)) {
722 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
730 /* if control out is not connected,
731 connect control out to physical outs, but use ones after the master if possible
734 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
736 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
738 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
741 _control_out->output()->connect_ports_to_bundle (b, this);
743 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
744 Config->get_monitor_bus_preferred_bundle())
750 /* XXX this logic is wrong for mixed port types */
752 uint32_t shift = _master_out->n_outputs().n_audio();
753 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
754 limit = _control_out->n_outputs().n_audio();
756 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
758 for (uint32_t n = 0; n < limit; ++n) {
760 Port* p = _control_out->output()->nth (n);
761 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
763 if (!connect_to.empty()) {
764 if (_control_out->output()->connect (p, connect_to, this)) {
765 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
776 /* catch up on send+insert cnts */
778 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
780 /* hook us up to the engine */
782 BootMessage (_("Connect to engine"));
784 _engine.set_session (this);
788 Session::hookup_io ()
790 /* stop graph reordering notifications from
791 causing resorts, etc.
794 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
799 /* we delay creating the auditioner till now because
800 it makes its own connections to ports.
801 the engine has to be running for this to work.
805 auditioner.reset (new Auditioner (*this));
808 catch (failed_constructor& err) {
809 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
813 /* load bundles, which we may have postponed earlier on */
814 if (_bundle_xml_node) {
815 load_bundles (*_bundle_xml_node);
816 delete _bundle_xml_node;
819 /* Tell all IO objects to connect themselves together */
821 IO::enable_connecting ();
823 /* Now reset all panners */
825 Delivery::reset_panners ();
827 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
831 boost::shared_ptr<RouteList> r = routes.reader ();
833 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
835 if ((*x)->is_control() || (*x)->is_master()) {
839 (*x)->listen_via (_control_out,
840 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
845 /* Anyone who cares about input state, wake up and do something */
847 IOConnectionsComplete (); /* EMIT SIGNAL */
849 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
851 /* now handle the whole enchilada as if it was one
857 /* update the full solo state, which can't be
858 correctly determined on a per-route basis, but
859 needs the global overview that only the session
863 update_route_solo_state ();
867 Session::playlist_length_changed ()
869 /* we can't just increase end_location->end() if pl->get_maximum_extent()
870 if larger. if the playlist used to be the longest playlist,
871 and its now shorter, we have to decrease end_location->end(). hence,
872 we have to iterate over all diskstreams and check the
873 playlists currently in use.
879 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
881 boost::shared_ptr<Diskstream> dstream = wp.lock ();
886 boost::shared_ptr<Playlist> playlist;
888 if ((playlist = dstream->playlist()) != 0) {
889 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
892 /* see comment in playlist_length_changed () */
897 Session::record_enabling_legal () const
899 /* this used to be in here, but survey says.... we don't need to restrict it */
900 // if (record_status() == Recording) {
904 if (Config->get_all_safe()) {
911 Session::reset_input_monitor_state ()
913 if (transport_rolling()) {
915 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
917 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
918 if ((*i)->record_enabled ()) {
919 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
920 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
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 = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
929 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
936 Session::auto_punch_start_changed (Location* location)
938 replace_event (Event::PunchIn, location->start());
940 if (get_record_enabled() && config.get_punch_in()) {
941 /* capture start has been changed, so save new pending state */
942 save_state ("", true);
947 Session::auto_punch_end_changed (Location* location)
949 nframes_t when_to_stop = location->end();
950 // when_to_stop += _worst_output_latency + _worst_input_latency;
951 replace_event (Event::PunchOut, when_to_stop);
955 Session::auto_punch_changed (Location* location)
957 nframes_t when_to_stop = location->end();
959 replace_event (Event::PunchIn, location->start());
960 //when_to_stop += _worst_output_latency + _worst_input_latency;
961 replace_event (Event::PunchOut, when_to_stop);
965 Session::auto_loop_changed (Location* location)
967 replace_event (Event::AutoLoop, location->end(), location->start());
969 if (transport_rolling() && play_loop) {
972 // if (_transport_frame > location->end()) {
974 if (_transport_frame < location->start() || _transport_frame > location->end()) {
975 // relocate to beginning of loop
976 clear_events (Event::LocateRoll);
978 request_locate (location->start(), true);
981 else if (Config->get_seamless_loop() && !loop_changing) {
983 // schedule a locate-roll to refill the diskstreams at the
985 loop_changing = true;
987 if (location->end() > last_loopend) {
988 clear_events (Event::LocateRoll);
989 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
996 last_loopend = location->end();
1000 Session::set_auto_punch_location (Location* location)
1004 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1005 auto_punch_start_changed_connection.disconnect();
1006 auto_punch_end_changed_connection.disconnect();
1007 auto_punch_changed_connection.disconnect();
1008 existing->set_auto_punch (false, this);
1009 remove_event (existing->start(), Event::PunchIn);
1010 clear_events (Event::PunchOut);
1011 auto_punch_location_changed (0);
1016 if (location == 0) {
1020 if (location->end() <= location->start()) {
1021 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1025 auto_punch_start_changed_connection.disconnect();
1026 auto_punch_end_changed_connection.disconnect();
1027 auto_punch_changed_connection.disconnect();
1029 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1030 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1031 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1033 location->set_auto_punch (true, this);
1036 auto_punch_changed (location);
1038 auto_punch_location_changed (location);
1042 Session::set_auto_loop_location (Location* location)
1046 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1047 auto_loop_start_changed_connection.disconnect();
1048 auto_loop_end_changed_connection.disconnect();
1049 auto_loop_changed_connection.disconnect();
1050 existing->set_auto_loop (false, this);
1051 remove_event (existing->end(), Event::AutoLoop);
1052 auto_loop_location_changed (0);
1057 if (location == 0) {
1061 if (location->end() <= location->start()) {
1062 error << _("Session: you can't use a mark for auto loop") << endmsg;
1066 last_loopend = location->end();
1068 auto_loop_start_changed_connection.disconnect();
1069 auto_loop_end_changed_connection.disconnect();
1070 auto_loop_changed_connection.disconnect();
1072 auto_loop_start_changed_connection = location->start_changed.connect (
1073 mem_fun (this, &Session::auto_loop_changed));
1074 auto_loop_end_changed_connection = location->end_changed.connect (
1075 mem_fun (this, &Session::auto_loop_changed));
1076 auto_loop_changed_connection = location->changed.connect (
1077 mem_fun (this, &Session::auto_loop_changed));
1079 location->set_auto_loop (true, this);
1081 /* take care of our stuff first */
1083 auto_loop_changed (location);
1085 /* now tell everyone else */
1087 auto_loop_location_changed (location);
1091 Session::locations_added (Location *)
1097 Session::locations_changed ()
1099 _locations.apply (*this, &Session::handle_locations_changed);
1103 Session::handle_locations_changed (Locations::LocationList& locations)
1105 Locations::LocationList::iterator i;
1107 bool set_loop = false;
1108 bool set_punch = false;
1110 for (i = locations.begin(); i != locations.end(); ++i) {
1114 if (location->is_auto_punch()) {
1115 set_auto_punch_location (location);
1118 if (location->is_auto_loop()) {
1119 set_auto_loop_location (location);
1123 if (location->is_start()) {
1124 start_location = location;
1126 if (location->is_end()) {
1127 end_location = location;
1132 set_auto_loop_location (0);
1135 set_auto_punch_location (0);
1142 Session::enable_record ()
1144 /* XXX really atomic compare+swap here */
1145 if (g_atomic_int_get (&_record_status) != Recording) {
1146 g_atomic_int_set (&_record_status, Recording);
1147 _last_record_location = _transport_frame;
1148 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1150 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1151 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1152 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1153 if ((*i)->record_enabled ()) {
1154 (*i)->monitor_input (true);
1159 RecordStateChanged ();
1164 Session::disable_record (bool rt_context, bool force)
1168 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1170 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1171 g_atomic_int_set (&_record_status, Disabled);
1173 if (rs == Recording) {
1174 g_atomic_int_set (&_record_status, Enabled);
1178 // FIXME: timestamp correct? [DR]
1179 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1180 // does this /need/ to be sent in all cases?
1182 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1184 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1185 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1187 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1188 if ((*i)->record_enabled ()) {
1189 (*i)->monitor_input (false);
1194 RecordStateChanged (); /* emit signal */
1197 remove_pending_capture_state ();
1203 Session::step_back_from_record ()
1205 /* XXX really atomic compare+swap here */
1206 if (g_atomic_int_get (&_record_status) == Recording) {
1207 g_atomic_int_set (&_record_status, Enabled);
1209 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1210 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1212 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1213 if ((*i)->record_enabled ()) {
1214 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1215 (*i)->monitor_input (false);
1223 Session::maybe_enable_record ()
1225 g_atomic_int_set (&_record_status, Enabled);
1227 /* this function is currently called from somewhere other than an RT thread.
1228 this save_state() call therefore doesn't impact anything.
1231 save_state ("", true);
1233 if (_transport_speed) {
1234 if (!config.get_punch_in()) {
1238 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1239 RecordStateChanged (); /* EMIT SIGNAL */
1246 Session::audible_frame () const
1252 /* the first of these two possible settings for "offset"
1253 mean that the audible frame is stationary until
1254 audio emerges from the latency compensation
1257 the second means that the audible frame is stationary
1258 until audio would emerge from a physical port
1259 in the absence of any plugin latency compensation
1262 offset = _worst_output_latency;
1264 if (offset > current_block_size) {
1265 offset -= current_block_size;
1267 /* XXX is this correct? if we have no external
1268 physical connections and everything is internal
1269 then surely this is zero? still, how
1270 likely is that anyway?
1272 offset = current_block_size;
1275 if (synced_to_jack()) {
1276 tf = _engine.transport_frame();
1278 tf = _transport_frame;
1283 if (!non_realtime_work_pending()) {
1287 /* check to see if we have passed the first guaranteed
1288 audible frame past our last start position. if not,
1289 return that last start point because in terms
1290 of audible frames, we have not moved yet.
1293 if (_transport_speed > 0.0f) {
1295 if (!play_loop || !have_looped) {
1296 if (tf < _last_roll_location + offset) {
1297 return _last_roll_location;
1305 } else if (_transport_speed < 0.0f) {
1307 /* XXX wot? no backward looping? */
1309 if (tf > _last_roll_location - offset) {
1310 return _last_roll_location;
1322 Session::set_frame_rate (nframes_t frames_per_second)
1324 /** \fn void Session::set_frame_size(nframes_t)
1325 the AudioEngine object that calls this guarantees
1326 that it will not be called while we are also in
1327 ::process(). Its fine to do things that block
1331 _base_frame_rate = frames_per_second;
1335 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1339 // XXX we need some equivalent to this, somehow
1340 // SndFileSource::setup_standard_crossfades (frames_per_second);
1344 /* XXX need to reset/reinstantiate all LADSPA plugins */
1348 Session::set_block_size (nframes_t nframes)
1350 /* the AudioEngine guarantees
1351 that it will not be called while we are also in
1352 ::process(). It is therefore fine to do things that block
1357 current_block_size = nframes;
1359 ensure_buffers(_scratch_buffers->available());
1361 delete [] _gain_automation_buffer;
1362 _gain_automation_buffer = new gain_t[nframes];
1364 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1366 boost::shared_ptr<RouteList> r = routes.reader ();
1368 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1369 (*i)->set_block_size (nframes);
1372 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1373 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1374 (*i)->set_block_size (nframes);
1377 set_worst_io_latencies ();
1382 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1385 nframes_t fade_frames;
1387 /* Don't allow fade of less 1 frame */
1389 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1396 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1400 default_fade_msecs = fade_msecs;
1401 default_fade_steepness = steepness;
1404 // jlc, WTF is this!
1405 Glib::RWLock::ReaderLock lm (route_lock);
1406 AudioRegion::set_default_fade (steepness, fade_frames);
1411 /* XXX have to do this at some point */
1412 /* foreach region using default fade, reset, then
1413 refill_all_diskstream_buffers ();
1418 struct RouteSorter {
1419 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1420 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1422 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1425 if (r1->fed_by.empty()) {
1426 if (r2->fed_by.empty()) {
1427 /* no ardour-based connections inbound to either route. just use signal order */
1428 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1430 /* r2 has connections, r1 does not; run r1 early */
1434 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1441 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1443 shared_ptr<Route> r2;
1445 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1446 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1450 /* make a copy of the existing list of routes that feed r1 */
1452 set<shared_ptr<Route> > existing = r1->fed_by;
1454 /* for each route that feeds r1, recurse, marking it as feeding
1458 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1461 /* r2 is a route that feeds r1 which somehow feeds base. mark
1462 base as being fed by r2
1465 rbase->fed_by.insert (r2);
1469 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1473 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1477 /* now recurse, so that we can mark base as being fed by
1478 all routes that feed r2
1481 trace_terminal (r2, rbase);
1488 Session::resort_routes ()
1490 /* don't do anything here with signals emitted
1491 by Routes while we are being destroyed.
1494 if (_state_of_the_state & Deletion) {
1501 RCUWriter<RouteList> writer (routes);
1502 shared_ptr<RouteList> r = writer.get_copy ();
1503 resort_routes_using (r);
1504 /* writer goes out of scope and forces update */
1509 Session::resort_routes_using (shared_ptr<RouteList> r)
1511 RouteList::iterator i, j;
1513 for (i = r->begin(); i != r->end(); ++i) {
1515 (*i)->fed_by.clear ();
1517 for (j = r->begin(); j != r->end(); ++j) {
1519 /* although routes can feed themselves, it will
1520 cause an endless recursive descent if we
1521 detect it. so don't bother checking for
1529 if ((*j)->feeds (*i)) {
1530 (*i)->fed_by.insert (*j);
1535 for (i = r->begin(); i != r->end(); ++i) {
1536 trace_terminal (*i, *i);
1543 cerr << "finished route resort\n";
1545 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1546 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1553 list<boost::shared_ptr<MidiTrack> >
1554 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1556 char track_name[32];
1557 uint32_t track_id = 0;
1560 RouteList new_routes;
1561 list<boost::shared_ptr<MidiTrack> > ret;
1562 //uint32_t control_id;
1564 // FIXME: need physical I/O and autoconnect stuff for MIDI
1566 /* count existing midi tracks */
1569 shared_ptr<RouteList> r = routes.reader ();
1571 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1572 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1573 if (!(*i)->is_hidden()) {
1575 //channels_used += (*i)->n_inputs().n_midi();
1581 vector<string> physinputs;
1582 vector<string> physoutputs;
1584 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1585 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1587 // control_id = ntracks() + nbusses();
1591 /* check for duplicate route names, since we might have pre-existing
1592 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1593 save, close,restart,add new route - first named route is now
1601 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1603 if (route_by_name (track_name) == 0) {
1607 } while (track_id < (UINT_MAX-1));
1609 shared_ptr<MidiTrack> track;
1612 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1614 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1615 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1620 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1621 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1627 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1631 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1632 port = physinputs[(channels_used+x)%nphysical_in];
1635 if (port.length() && track->connect_input (track->input (x), port, this)) {
1641 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1645 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1646 port = physoutputs[(channels_used+x)%nphysical_out];
1647 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1649 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1653 if (port.length() && track->connect_output (track->output (x), port, this)) {
1658 channels_used += track->n_inputs ().n_midi();
1662 track->midi_diskstream()->non_realtime_input_change();
1663 track->set_route_group (route_group, 0);
1665 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1666 //track->set_remote_control_id (control_id);
1668 new_routes.push_back (track);
1669 ret.push_back (track);
1672 catch (failed_constructor &err) {
1673 error << _("Session: could not create new midi track.") << endmsg;
1676 /* we need to get rid of this, since the track failed to be created */
1677 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1680 RCUWriter<DiskstreamList> writer (diskstreams);
1681 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1682 ds->remove (track->midi_diskstream());
1689 catch (AudioEngine::PortRegistrationFailure& pfe) {
1691 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;
1694 /* we need to get rid of this, since the track failed to be created */
1695 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1698 RCUWriter<DiskstreamList> writer (diskstreams);
1699 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1700 ds->remove (track->midi_diskstream());
1711 if (!new_routes.empty()) {
1712 add_routes (new_routes, false);
1713 save_state (_current_snapshot_name);
1719 list<boost::shared_ptr<AudioTrack> >
1720 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1722 char track_name[32];
1723 uint32_t track_id = 0;
1725 uint32_t channels_used = 0;
1727 RouteList new_routes;
1728 list<boost::shared_ptr<AudioTrack> > ret;
1729 uint32_t control_id;
1731 /* count existing audio tracks */
1734 shared_ptr<RouteList> r = routes.reader ();
1736 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1737 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1738 if (!(*i)->is_hidden()) {
1740 channels_used += (*i)->n_inputs().n_audio();
1746 vector<string> physinputs;
1747 vector<string> physoutputs;
1749 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1750 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1752 control_id = ntracks() + nbusses() + 1;
1756 /* check for duplicate route names, since we might have pre-existing
1757 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1758 save, close,restart,add new route - first named route is now
1766 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1768 if (route_by_name (track_name) == 0) {
1772 } while (track_id < (UINT_MAX-1));
1774 shared_ptr<AudioTrack> track;
1777 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1778 boost_debug_shared_ptr_mark_interesting (at, typeid (at).name());
1779 track = boost::shared_ptr<AudioTrack>(at);
1781 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1782 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1783 input_channels, output_channels)
1788 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1789 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1790 input_channels, output_channels)
1795 if (!physinputs.empty()) {
1796 uint32_t nphysical_in = physinputs.size();
1798 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1802 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1803 port = physinputs[(channels_used+x)%nphysical_in];
1806 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1812 if (!physoutputs.empty()) {
1813 uint32_t nphysical_out = physoutputs.size();
1815 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1818 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1819 port = physoutputs[(channels_used+x)%nphysical_out];
1820 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1821 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1822 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1826 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1832 channels_used += track->n_inputs ().n_audio();
1834 track->set_route_group (route_group, 0);
1836 track->audio_diskstream()->non_realtime_input_change();
1838 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1839 track->set_remote_control_id (control_id);
1842 new_routes.push_back (track);
1843 ret.push_back (track);
1846 catch (failed_constructor &err) {
1847 error << _("Session: could not create new audio track.") << endmsg;
1850 /* we need to get rid of this, since the track failed to be created */
1851 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1854 RCUWriter<DiskstreamList> writer (diskstreams);
1855 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1856 ds->remove (track->audio_diskstream());
1863 catch (AudioEngine::PortRegistrationFailure& pfe) {
1865 error << pfe.what() << endmsg;
1868 /* we need to get rid of this, since the track failed to be created */
1869 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1872 RCUWriter<DiskstreamList> writer (diskstreams);
1873 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1874 ds->remove (track->audio_diskstream());
1885 if (!new_routes.empty()) {
1886 add_routes (new_routes, true);
1893 Session::set_remote_control_ids ()
1895 RemoteModel m = Config->get_remote_model();
1897 shared_ptr<RouteList> r = routes.reader ();
1899 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1900 if ( MixerOrdered == m) {
1901 long order = (*i)->order_key(N_("signal"));
1902 (*i)->set_remote_control_id( order+1 );
1903 } else if ( EditorOrdered == m) {
1904 long order = (*i)->order_key(N_("editor"));
1905 (*i)->set_remote_control_id( order+1 );
1906 } else if ( UserOrdered == m) {
1907 //do nothing ... only changes to remote id's are initiated by user
1914 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1917 uint32_t bus_id = 1;
1919 uint32_t channels_used = 0;
1922 uint32_t control_id;
1924 /* count existing audio busses */
1927 shared_ptr<RouteList> r = routes.reader ();
1929 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1930 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1932 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1935 channels_used += (*i)->n_inputs().n_audio();
1941 vector<string> physinputs;
1942 vector<string> physoutputs;
1944 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1945 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1947 n_physical_audio_outputs = physoutputs.size();
1948 n_physical_audio_inputs = physinputs.size();
1950 control_id = ntracks() + nbusses() + 1;
1955 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1959 if (route_by_name (bus_name) == 0) {
1963 } while (bus_id < (UINT_MAX-1));
1966 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1968 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1969 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1970 input_channels, output_channels)
1976 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1977 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1978 input_channels, output_channels)
1983 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1986 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1987 port = physinputs[((n+x)%n_physical_audio_inputs)];
1990 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1995 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1998 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1999 port = physoutputs[((n+x)%n_physical_outputs)];
2000 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
2002 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
2006 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
2011 channels_used += bus->n_inputs ().n_audio();
2013 bus->set_route_group (route_group, 0);
2014 bus->set_remote_control_id (control_id);
2018 bus->add_internal_return ();
2021 ret.push_back (bus);
2025 catch (failed_constructor &err) {
2026 error << _("Session: could not create new audio route.") << endmsg;
2030 catch (AudioEngine::PortRegistrationFailure& pfe) {
2031 error << pfe.what() << endmsg;
2041 add_routes (ret, true);
2049 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2053 uint32_t control_id;
2055 uint32_t number = 1;
2057 if (!tree.read (template_path.c_str())) {
2061 XMLNode* node = tree.root();
2063 control_id = ntracks() + nbusses() + 1;
2067 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2069 std::string node_name = IO::name_from_state (*node_copy.children().front());
2071 /* generate a new name by adding a number to the end of the template name */
2074 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2078 if (route_by_name (name) == 0) {
2082 } while (number < UINT_MAX);
2084 if (number == UINT_MAX) {
2085 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2089 IO::set_name_in_state (*node_copy.children().front(), name);
2091 Track::zero_diskstream_id_in_xml (node_copy);
2094 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2097 error << _("Session: cannot create track/bus from template description") << endmsg;
2101 if (boost::dynamic_pointer_cast<Track>(route)) {
2102 /* force input/output change signals so that the new diskstream
2103 picks up the configuration of the route. During session
2104 loading this normally happens in a different way.
2106 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2107 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2110 route->set_remote_control_id (control_id);
2113 ret.push_back (route);
2116 catch (failed_constructor &err) {
2117 error << _("Session: could not create new route from template") << endmsg;
2121 catch (AudioEngine::PortRegistrationFailure& pfe) {
2122 error << pfe.what() << endmsg;
2131 add_routes (ret, true);
2138 Session::add_routes (RouteList& new_routes, bool save)
2141 RCUWriter<RouteList> writer (routes);
2142 shared_ptr<RouteList> r = writer.get_copy ();
2143 r->insert (r->end(), new_routes.begin(), new_routes.end());
2146 /* if there is no control out and we're not in the middle of loading,
2147 resort the graph here. if there is a control out, we will resort
2148 toward the end of this method. if we are in the middle of loading,
2149 we will resort when done.
2152 if (!_control_out && IO::connecting_legal) {
2153 resort_routes_using (r);
2157 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2159 boost::weak_ptr<Route> wpr (*x);
2161 (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr));
2162 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2163 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2164 (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2165 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2166 (*x)->route_group_changed.connect (hide (mem_fun (*this, &Session::route_group_changed)));
2168 if ((*x)->is_master()) {
2172 if ((*x)->is_control()) {
2173 _control_out = (*x);
2177 if (_control_out && IO::connecting_legal) {
2179 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2180 if ((*x)->is_control() || (*x)->is_master()) {
2183 (*x)->listen_via (_control_out,
2184 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2194 save_state (_current_snapshot_name);
2197 RouteAdded (new_routes); /* EMIT SIGNAL */
2201 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2203 boost::shared_ptr<RouteList> r = routes.reader ();
2204 boost::shared_ptr<Send> s;
2208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2209 if (boost::dynamic_pointer_cast<Track>(*i)) {
2210 if ((s = (*i)->internal_send_for (dest)) != 0) {
2211 s->amp()->gain_control()->set_value (0.0);
2218 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2220 boost::shared_ptr<RouteList> r = routes.reader ();
2221 boost::shared_ptr<Send> s;
2225 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 if (boost::dynamic_pointer_cast<Track>(*i)) {
2227 if ((s = (*i)->internal_send_for (dest)) != 0) {
2228 s->amp()->gain_control()->set_value (1.0);
2235 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2237 boost::shared_ptr<RouteList> r = routes.reader ();
2238 boost::shared_ptr<Send> s;
2242 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2243 if (boost::dynamic_pointer_cast<Track>(*i)) {
2244 if ((s = (*i)->internal_send_for (dest)) != 0) {
2245 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2252 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2254 boost::shared_ptr<RouteList> r = routes.reader ();
2255 boost::shared_ptr<RouteList> t (new RouteList);
2257 /* only send tracks */
2259 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2260 if (boost::dynamic_pointer_cast<Track>(*i)) {
2265 add_internal_sends (dest, p, t);
2269 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2271 if (dest->is_control() || dest->is_master()) {
2275 if (!dest->internal_return()) {
2276 dest->add_internal_return();
2279 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2281 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2285 (*i)->listen_via (dest, p, true, true);
2292 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2294 /* need to do this in case we're rolling at the time, to prevent false underruns */
2295 dstream->do_refill_with_alloc ();
2297 dstream->set_block_size (current_block_size);
2300 RCUWriter<DiskstreamList> writer (diskstreams);
2301 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2302 ds->push_back (dstream);
2303 /* writer goes out of scope, copies ds back to main */
2306 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
2307 /* this will connect to future changes, and check the current length */
2308 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2310 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2312 dstream->prepare ();
2317 Session::remove_route (shared_ptr<Route> route)
2320 RCUWriter<RouteList> writer (routes);
2321 shared_ptr<RouteList> rs = writer.get_copy ();
2325 /* deleting the master out seems like a dumb
2326 idea, but its more of a UI policy issue
2330 if (route == _master_out) {
2331 _master_out = shared_ptr<Route> ();
2334 if (route == _control_out) {
2336 /* cancel control outs for all routes */
2338 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2339 (*r)->drop_listen (_control_out);
2342 _control_out.reset ();
2345 update_route_solo_state ();
2347 /* writer goes out of scope, forces route list update */
2350 boost::shared_ptr<Track> t;
2351 boost::shared_ptr<Diskstream> ds;
2353 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2354 ds = t->diskstream();
2360 RCUWriter<DiskstreamList> dsl (diskstreams);
2361 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2366 find_current_end ();
2368 // We need to disconnect the routes inputs and outputs
2370 route->input()->disconnect (0);
2371 route->output()->disconnect (0);
2373 update_latency_compensation (false, false);
2376 /* get rid of it from the dead wood collection in the route list manager */
2378 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2382 /* try to cause everyone to drop their references */
2384 route->drop_references ();
2386 sync_order_keys (N_("session"));
2388 /* save the new state of the world */
2390 if (save_state (_current_snapshot_name)) {
2391 save_history (_current_snapshot_name);
2396 Session::route_mute_changed (void* /*src*/)
2402 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2404 boost::shared_ptr<Route> route = wpr.lock();
2406 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2410 if (route->listening()) {
2412 } else if (_listen_cnt > 0) {
2418 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2420 if (solo_update_disabled) {
2425 boost::shared_ptr<Route> route = wpr.lock ();
2428 /* should not happen */
2429 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2433 shared_ptr<RouteList> r = routes.reader ();
2436 if (route->self_soloed()) {
2442 /* now mod the solo level of all other routes except master & control outs
2443 so that they will be silent if appropriate.
2446 solo_update_disabled = true;
2448 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2449 bool via_sends_only;
2452 if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) {
2454 } else if ((*i)->feeds (route, &via_sends_only)) {
2455 if (!via_sends_only) {
2456 (*i)->mod_solo_by_others (delta);
2461 /* make sure master is never muted by solo */
2463 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2464 _master_out->mod_solo_by_others (1);
2467 /* ditto for control outs make sure master is never muted by solo */
2469 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2470 _control_out->mod_solo_by_others (1);
2473 solo_update_disabled = false;
2474 update_route_solo_state (r);
2475 SoloChanged (); /* EMIT SIGNAL */
2480 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2482 /* now figure out if anything that matters is soloed */
2484 bool something_soloed = false;
2487 r = routes.reader();
2490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2491 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2492 something_soloed = true;
2497 if (something_soloed != _non_soloed_outs_muted) {
2498 _non_soloed_outs_muted = something_soloed;
2499 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2503 boost::shared_ptr<RouteList>
2504 Session::get_routes_with_internal_returns() const
2506 shared_ptr<RouteList> r = routes.reader ();
2507 boost::shared_ptr<RouteList> rl (new RouteList);
2509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2510 if ((*i)->internal_return ()) {
2518 Session::route_by_name (string name)
2520 shared_ptr<RouteList> r = routes.reader ();
2522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2523 if ((*i)->name() == name) {
2528 return shared_ptr<Route> ((Route*) 0);
2532 Session::route_by_id (PBD::ID id)
2534 shared_ptr<RouteList> r = routes.reader ();
2536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2537 if ((*i)->id() == id) {
2542 return shared_ptr<Route> ((Route*) 0);
2546 Session::route_by_remote_id (uint32_t id)
2548 shared_ptr<RouteList> r = routes.reader ();
2550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2551 if ((*i)->remote_control_id() == id) {
2556 return shared_ptr<Route> ((Route*) 0);
2560 Session::find_current_end ()
2562 if (_state_of_the_state & Loading) {
2566 nframes_t max = get_maximum_extent ();
2568 if (max > end_location->end()) {
2569 end_location->set_end (max);
2571 DurationChanged(); /* EMIT SIGNAL */
2576 Session::get_maximum_extent () const
2581 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2583 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2584 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2586 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2587 if ((me = pl->get_maximum_extent()) > max) {
2595 boost::shared_ptr<Diskstream>
2596 Session::diskstream_by_name (string name)
2598 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2600 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2601 if ((*i)->name() == name) {
2606 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2609 boost::shared_ptr<Diskstream>
2610 Session::diskstream_by_id (const PBD::ID& id)
2612 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2614 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2615 if ((*i)->id() == id) {
2620 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2623 /* Region management */
2626 Session::new_region_name (string old)
2628 string::size_type last_period;
2630 string::size_type len = old.length() + 64;
2633 if ((last_period = old.find_last_of ('.')) == string::npos) {
2635 /* no period present - add one explicitly */
2638 last_period = old.length() - 1;
2643 number = atoi (old.substr (last_period+1).c_str());
2647 while (number < (UINT_MAX-1)) {
2649 RegionList::const_iterator i;
2654 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2657 for (i = regions.begin(); i != regions.end(); ++i) {
2658 if (i->second->name() == sbuf) {
2663 if (i == regions.end()) {
2668 if (number != (UINT_MAX-1)) {
2672 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2677 Session::region_name (string& result, string base, bool newlevel)
2682 if (base.find("/") != string::npos) {
2683 base = base.substr(base.find_last_of("/") + 1);
2688 Glib::Mutex::Lock lm (region_lock);
2690 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2699 string::size_type pos;
2701 pos = base.find_last_of ('.');
2703 /* pos may be npos, but then we just use entire base */
2705 subbase = base.substr (0, pos);
2710 Glib::Mutex::Lock lm (region_lock);
2712 map<string,uint32_t>::iterator x;
2716 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2718 region_name_map[subbase] = 1;
2721 snprintf (buf, sizeof (buf), ".%d", x->second);
2732 Session::add_region (boost::shared_ptr<Region> region)
2734 vector<boost::shared_ptr<Region> > v;
2735 v.push_back (region);
2740 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2745 Glib::Mutex::Lock lm (region_lock);
2747 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2749 boost::shared_ptr<Region> region = *ii;
2753 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2757 RegionList::iterator x;
2759 for (x = regions.begin(); x != regions.end(); ++x) {
2761 if (region->region_list_equivalent (x->second)) {
2766 if (x == regions.end()) {
2768 pair<RegionList::key_type,RegionList::mapped_type> entry;
2770 entry.first = region->id();
2771 entry.second = region;
2773 pair<RegionList::iterator,bool> x = regions.insert (entry);
2785 /* mark dirty because something has changed even if we didn't
2786 add the region to the region list.
2793 vector<boost::weak_ptr<Region> > v;
2794 boost::shared_ptr<Region> first_r;
2796 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2798 boost::shared_ptr<Region> region = *ii;
2802 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2805 v.push_back (region);
2812 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2813 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2815 update_region_name_map (region);
2819 RegionsAdded (v); /* EMIT SIGNAL */
2825 Session::update_region_name_map (boost::shared_ptr<Region> region)
2827 string::size_type last_period = region->name().find_last_of ('.');
2829 if (last_period != string::npos && last_period < region->name().length() - 1) {
2831 string base = region->name().substr (0, last_period);
2832 string number = region->name().substr (last_period+1);
2833 map<string,uint32_t>::iterator x;
2835 /* note that if there is no number, we get zero from atoi,
2839 region_name_map[base] = atoi (number);
2844 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2846 boost::shared_ptr<Region> region (weak_region.lock ());
2852 if (what_changed & Region::HiddenChanged) {
2853 /* relay hidden changes */
2854 RegionHiddenChange (region);
2857 if (what_changed & NameChanged) {
2858 update_region_name_map (region);
2863 Session::remove_region (boost::weak_ptr<Region> weak_region)
2865 RegionList::iterator i;
2866 boost::shared_ptr<Region> region (weak_region.lock ());
2872 bool removed = false;
2875 Glib::Mutex::Lock lm (region_lock);
2877 if ((i = regions.find (region->id())) != regions.end()) {
2883 /* mark dirty because something has changed even if we didn't
2884 remove the region from the region list.
2890 RegionRemoved(region); /* EMIT SIGNAL */
2894 boost::shared_ptr<Region>
2895 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2897 RegionList::iterator i;
2898 boost::shared_ptr<Region> region;
2900 Glib::Mutex::Lock lm (region_lock);
2902 for (i = regions.begin(); i != regions.end(); ++i) {
2906 if (region->whole_file()) {
2908 if (child->source_equivalent (region)) {
2914 return boost::shared_ptr<Region> ();
2918 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2920 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2921 (*i)->get_region_list_equivalent_regions (region, result);
2925 Session::destroy_region (boost::shared_ptr<Region> region)
2927 vector<boost::shared_ptr<Source> > srcs;
2930 if (region->playlist()) {
2931 region->playlist()->destroy_region (region);
2934 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2935 srcs.push_back (region->source (n));
2939 region->drop_references ();
2941 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2943 (*i)->mark_for_remove ();
2944 (*i)->drop_references ();
2946 cerr << "source was not used by any playlist\n";
2953 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2955 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2956 destroy_region (*i);
2962 Session::remove_last_capture ()
2964 list<boost::shared_ptr<Region> > r;
2966 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2968 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2969 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2972 r.insert (r.end(), l.begin(), l.end());
2977 destroy_regions (r);
2979 save_state (_current_snapshot_name);
2985 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2991 /* Source Management */
2994 Session::add_source (boost::shared_ptr<Source> source)
2996 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2997 pair<SourceMap::iterator,bool> result;
2999 entry.first = source->id();
3000 entry.second = source;
3003 Glib::Mutex::Lock lm (source_lock);
3004 result = sources.insert (entry);
3007 if (result.second) {
3008 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
3012 boost::shared_ptr<AudioFileSource> afs;
3014 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3015 if (Config->get_auto_analyse_audio()) {
3016 Analyser::queue_source_for_analysis (source, false);
3022 Session::remove_source (boost::weak_ptr<Source> src)
3024 SourceMap::iterator i;
3025 boost::shared_ptr<Source> source = src.lock();
3032 Glib::Mutex::Lock lm (source_lock);
3034 if ((i = sources.find (source->id())) != sources.end()) {
3039 if (!_state_of_the_state & InCleanup) {
3041 /* save state so we don't end up with a session file
3042 referring to non-existent sources.
3045 save_state (_current_snapshot_name);
3049 /** Return the number of playlists (not regions) that contain @a src */
3051 Session::source_use_count (boost::shared_ptr<const Source> src) const
3054 for (PlaylistList::const_iterator p = playlists.begin(); p != playlists.end(); ++p) {
3055 for (Playlist::RegionList::const_iterator r = (*p)->region_list().begin();
3056 r != (*p)->region_list().end(); ++r) {
3057 if ((*r)->uses_source(src)) {
3066 boost::shared_ptr<Source>
3067 Session::source_by_id (const PBD::ID& id)
3069 Glib::Mutex::Lock lm (source_lock);
3070 SourceMap::iterator i;
3071 boost::shared_ptr<Source> source;
3073 if ((i = sources.find (id)) != sources.end()) {
3080 boost::shared_ptr<Source>
3081 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3083 Glib::Mutex::Lock lm (source_lock);
3085 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3086 cerr << "comparing " << path << " with " << i->second->name() << endl;
3087 boost::shared_ptr<AudioFileSource> afs
3088 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3090 if (afs && afs->path() == path && chn == afs->channel()) {
3094 return boost::shared_ptr<Source>();
3099 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3102 string old_basename = PBD::basename_nosuffix (oldname);
3103 string new_legalized = legalize_for_path (newname);
3105 /* note: we know (or assume) the old path is already valid */
3109 /* destructive file sources have a name of the form:
3111 /path/to/Tnnnn-NAME(%[LR])?.wav
3113 the task here is to replace NAME with the new name.
3116 /* find last slash */
3120 string::size_type slash;
3121 string::size_type dash;
3123 if ((slash = path.find_last_of ('/')) == string::npos) {
3127 dir = path.substr (0, slash+1);
3129 /* '-' is not a legal character for the NAME part of the path */
3131 if ((dash = path.find_last_of ('-')) == string::npos) {
3135 prefix = path.substr (slash+1, dash-(slash+1));
3140 path += new_legalized;
3141 path += ".wav"; /* XXX gag me with a spoon */
3145 /* non-destructive file sources have a name of the form:
3147 /path/to/NAME-nnnnn(%[LR])?.ext
3149 the task here is to replace NAME with the new name.
3154 string::size_type slash;
3155 string::size_type dash;
3156 string::size_type postfix;
3158 /* find last slash */
3160 if ((slash = path.find_last_of ('/')) == string::npos) {
3164 dir = path.substr (0, slash+1);
3166 /* '-' is not a legal character for the NAME part of the path */
3168 if ((dash = path.find_last_of ('-')) == string::npos) {
3172 suffix = path.substr (dash+1);
3174 // Suffix is now everything after the dash. Now we need to eliminate
3175 // the nnnnn part, which is done by either finding a '%' or a '.'
3177 postfix = suffix.find_last_of ("%");
3178 if (postfix == string::npos) {
3179 postfix = suffix.find_last_of ('.');
3182 if (postfix != string::npos) {
3183 suffix = suffix.substr (postfix);
3185 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3189 const uint32_t limit = 10000;
3190 char buf[PATH_MAX+1];
3192 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3194 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3196 if (access (buf, F_OK) != 0) {
3204 error << "FATAL ERROR! Could not find a " << endl;
3212 /** Return the full path (in some session directory) for a new embedded source.
3213 * \a name must be a session-unique name that does not contain slashes
3214 * (e.g. as returned by new_*_source_name)
3217 Session::new_source_path_from_name (DataType type, const string& name)
3219 assert(name.find("/") == string::npos);
3221 SessionDirectory sdir(get_best_session_directory_for_new_source());
3224 if (type == DataType::AUDIO) {
3225 p = sdir.sound_path();
3226 } else if (type == DataType::MIDI) {
3227 p = sdir.midi_path();
3229 error << "Unknown source type, unable to create file path" << endmsg;
3234 return p.to_string();
3238 Session::peak_path (Glib::ustring base) const
3240 sys::path peakfile_path(_session_dir->peak_path());
3241 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3242 return peakfile_path.to_string();
3245 /** Return a unique name based on \a base for a new internal audio source */
3247 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3251 char buf[PATH_MAX+1];
3252 const uint32_t limit = 10000;
3256 legalized = legalize_for_path (base);
3258 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3259 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3261 vector<space_and_path>::iterator i;
3262 uint32_t existing = 0;
3264 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3266 SessionDirectory sdir((*i).path);
3268 spath = sdir.sound_path().to_string();
3273 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3274 spath.c_str(), cnt, legalized.c_str());
3275 } else if (nchan == 2) {
3277 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3278 spath.c_str(), cnt, legalized.c_str());
3280 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3281 spath.c_str(), cnt, legalized.c_str());
3283 } else if (nchan < 26) {
3284 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3285 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3287 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3288 spath.c_str(), cnt, legalized.c_str());
3297 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3298 } else if (nchan == 2) {
3300 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3302 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3304 } else if (nchan < 26) {
3305 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3307 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3311 if (sys::exists(buf)) {
3317 if (existing == 0) {
3322 error << string_compose(
3323 _("There are already %1 recordings for %2, which I consider too many."),
3324 limit, base) << endmsg;
3326 throw failed_constructor();
3330 return Glib::path_get_basename(buf);
3333 /** Create a new embedded audio source */
3334 boost::shared_ptr<AudioFileSource>
3335 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3337 const size_t n_chans = ds.n_channels().n_audio();
3338 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3339 const string path = new_source_path_from_name(DataType::AUDIO, name);
3341 return boost::dynamic_pointer_cast<AudioFileSource> (
3342 SourceFactory::createWritable (DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3345 /** Return a unique name based on \a base for a new internal MIDI source */
3347 Session::new_midi_source_name (const string& base)
3350 char buf[PATH_MAX+1];
3351 const uint32_t limit = 10000;
3355 legalized = legalize_for_path (base);
3357 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3358 for (cnt = 1; cnt <= limit; ++cnt) {
3360 vector<space_and_path>::iterator i;
3361 uint32_t existing = 0;
3363 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3365 SessionDirectory sdir((*i).path);
3367 sys::path p = sdir.midi_path();
3370 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3372 if (sys::exists (buf)) {
3377 if (existing == 0) {
3382 error << string_compose(
3383 _("There are already %1 recordings for %2, which I consider too many."),
3384 limit, base) << endmsg;
3386 throw failed_constructor();
3390 return Glib::path_get_basename(buf);
3394 /** Create a new embedded MIDI source */
3395 boost::shared_ptr<MidiSource>
3396 Session::create_midi_source_for_session (MidiDiskstream& ds)
3398 const string name = new_midi_source_name (ds.name());
3399 const string path = new_source_path_from_name (DataType::MIDI, name);
3401 return boost::dynamic_pointer_cast<SMFSource> (
3402 SourceFactory::createWritable (
3403 DataType::MIDI, *this, path, true, false, frame_rate()));
3407 /* Playlist management */
3409 boost::shared_ptr<Playlist>
3410 Session::playlist_by_name (string name)
3412 Glib::Mutex::Lock lm (playlist_lock);
3413 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3414 if ((*i)->name() == name) {
3418 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3419 if ((*i)->name() == name) {
3424 return boost::shared_ptr<Playlist>();
3428 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3430 Glib::Mutex::Lock lm (playlist_lock);
3431 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3432 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3433 list.push_back (*i);
3436 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3437 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3438 list.push_back (*i);
3444 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3446 if (playlist->hidden()) {
3451 Glib::Mutex::Lock lm (playlist_lock);
3452 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3453 playlists.insert (playlists.begin(), playlist);
3454 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3455 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3460 playlist->release();
3465 PlaylistAdded (playlist); /* EMIT SIGNAL */
3469 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3472 Glib::Mutex::Lock lm (playlist_lock);
3473 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3476 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3483 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3485 boost::shared_ptr<Playlist> pl(wpl.lock());
3491 PlaylistList::iterator x;
3494 /* its not supposed to be visible */
3499 Glib::Mutex::Lock lm (playlist_lock);
3503 unused_playlists.insert (pl);
3505 if ((x = playlists.find (pl)) != playlists.end()) {
3506 playlists.erase (x);
3512 playlists.insert (pl);
3514 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3515 unused_playlists.erase (x);
3522 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3524 if (_state_of_the_state & Deletion) {
3528 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3535 Glib::Mutex::Lock lm (playlist_lock);
3537 PlaylistList::iterator i;
3539 i = find (playlists.begin(), playlists.end(), playlist);
3540 if (i != playlists.end()) {
3541 playlists.erase (i);
3544 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3545 if (i != unused_playlists.end()) {
3546 unused_playlists.erase (i);
3553 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3557 Session::set_audition (boost::shared_ptr<Region> r)
3559 pending_audition_region = r;
3560 add_post_transport_work (PostTransportAudition);
3561 _butler->schedule_transport_work ();
3565 Session::audition_playlist ()
3567 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3568 ev->region.reset ();
3573 Session::non_realtime_set_audition ()
3575 if (!pending_audition_region) {
3576 auditioner->audition_current_playlist ();
3578 auditioner->audition_region (pending_audition_region);
3579 pending_audition_region.reset ();
3581 AuditionActive (true); /* EMIT SIGNAL */
3585 Session::audition_region (boost::shared_ptr<Region> r)
3587 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3593 Session::cancel_audition ()
3595 if (auditioner->active()) {
3596 auditioner->cancel_audition ();
3597 AuditionActive (false); /* EMIT SIGNAL */
3602 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3604 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3608 Session::remove_empty_sounds ()
3610 vector<string> audio_filenames;
3612 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3614 Glib::Mutex::Lock lm (source_lock);
3616 TapeFileMatcher tape_file_matcher;
3618 remove_if (audio_filenames.begin(), audio_filenames.end(),
3619 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3621 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3623 sys::path audio_file_path (_session_dir->sound_path());
3625 audio_file_path /= *i;
3627 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3631 sys::remove (audio_file_path);
3632 const string peakfile = peak_path (audio_file_path.to_string());
3633 sys::remove (peakfile);
3635 catch (const sys::filesystem_error& err)
3637 error << err.what() << endmsg;
3644 Session::is_auditioning () const
3646 /* can be called before we have an auditioner object */
3648 return auditioner->active();
3655 Session::set_all_solo (bool yn)
3657 shared_ptr<RouteList> r = routes.reader ();
3659 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3660 if (!(*i)->is_hidden()) {
3661 (*i)->set_solo (yn, this);
3669 Session::set_all_listen (bool yn)
3671 shared_ptr<RouteList> r = routes.reader ();
3673 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3674 if (!(*i)->is_hidden()) {
3675 (*i)->set_listen (yn, this);
3683 Session::set_all_mute (bool yn)
3685 shared_ptr<RouteList> r = routes.reader ();
3687 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3688 if (!(*i)->is_hidden()) {
3689 (*i)->set_mute (yn, this);
3697 Session::n_diskstreams () const
3701 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3703 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3704 if (!(*i)->hidden()) {
3712 Session::graph_reordered ()
3714 /* don't do this stuff if we are setting up connections
3715 from a set_state() call or creating new tracks.
3718 if (_state_of_the_state & InitialConnecting) {
3722 /* every track/bus asked for this to be handled but it was deferred because
3723 we were connecting. do it now.
3726 request_input_change_handling ();
3730 /* force all diskstreams to update their capture offset values to
3731 reflect any changes in latencies within the graph.
3734 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3736 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3737 (*i)->set_capture_offset ();
3742 Session::record_disenable_all ()
3744 record_enable_change_all (false);
3748 Session::record_enable_all ()
3750 record_enable_change_all (true);
3754 Session::record_enable_change_all (bool yn)
3756 shared_ptr<RouteList> r = routes.reader ();
3758 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3759 boost::shared_ptr<Track> t;
3761 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3762 t->set_record_enable (yn, this);
3766 /* since we don't keep rec-enable state, don't mark session dirty */
3770 Session::add_processor (Processor* processor)
3772 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3777 Session::remove_processor (Processor* processor)
3781 PortInsert* port_insert;
3783 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3784 insert_bitset[port_insert->bit_slot()] = false;
3785 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3786 send_bitset[send->bit_slot()] = false;
3787 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3788 return_bitset[retrn->bit_slot()] = false;
3795 Session::available_capture_duration ()
3797 float sample_bytes_on_disk = 4.0; // keep gcc happy
3799 switch (config.get_native_file_data_format()) {
3801 sample_bytes_on_disk = 4.0;
3805 sample_bytes_on_disk = 3.0;
3809 sample_bytes_on_disk = 2.0;
3813 /* impossible, but keep some gcc versions happy */
3814 fatal << string_compose (_("programming error: %1"),
3815 X_("illegal native file data format"))
3820 double scale = 4096.0 / sample_bytes_on_disk;
3822 if (_total_free_4k_blocks * scale > (double) max_frames) {
3826 return (nframes_t) floor (_total_free_4k_blocks * scale);
3830 Session::add_bundle (shared_ptr<Bundle> bundle)
3833 RCUWriter<BundleList> writer (_bundles);
3834 boost::shared_ptr<BundleList> b = writer.get_copy ();
3835 b->push_back (bundle);
3838 BundleAdded (bundle); /* EMIT SIGNAL */
3844 Session::remove_bundle (shared_ptr<Bundle> bundle)
3846 bool removed = false;
3849 RCUWriter<BundleList> writer (_bundles);
3850 boost::shared_ptr<BundleList> b = writer.get_copy ();
3851 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3853 if (i != b->end()) {
3860 BundleRemoved (bundle); /* EMIT SIGNAL */
3867 Session::bundle_by_name (string name) const
3869 boost::shared_ptr<BundleList> b = _bundles.reader ();
3871 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3872 if ((*i)->name() == name) {
3877 return boost::shared_ptr<Bundle> ();
3881 Session::tempo_map_changed (Change)
3885 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3886 (*i)->update_after_tempo_map_change ();
3889 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3890 (*i)->update_after_tempo_map_change ();
3896 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3897 * the given count with the current block size.
3900 Session::ensure_buffers (ChanCount howmany)
3902 if (current_block_size == 0) {
3903 return; // too early? (is this ok?)
3906 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3907 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3908 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3909 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3910 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3913 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3917 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3919 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3920 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3925 Session::next_insert_id ()
3927 /* this doesn't really loop forever. just think about it */
3930 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3931 if (!insert_bitset[n]) {
3932 insert_bitset[n] = true;
3938 /* none available, so resize and try again */
3940 insert_bitset.resize (insert_bitset.size() + 16, false);
3945 Session::next_send_id ()
3947 /* this doesn't really loop forever. just think about it */
3950 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3951 if (!send_bitset[n]) {
3952 send_bitset[n] = true;
3958 /* none available, so resize and try again */
3960 send_bitset.resize (send_bitset.size() + 16, false);
3965 Session::next_return_id ()
3967 /* this doesn't really loop forever. just think about it */
3970 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3971 if (!return_bitset[n]) {
3972 return_bitset[n] = true;
3978 /* none available, so resize and try again */
3980 return_bitset.resize (return_bitset.size() + 16, false);
3985 Session::mark_send_id (uint32_t id)
3987 if (id >= send_bitset.size()) {
3988 send_bitset.resize (id+16, false);
3990 if (send_bitset[id]) {
3991 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3993 send_bitset[id] = true;
3997 Session::mark_return_id (uint32_t id)
3999 if (id >= return_bitset.size()) {
4000 return_bitset.resize (id+16, false);
4002 if (return_bitset[id]) {
4003 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
4005 return_bitset[id] = true;
4009 Session::mark_insert_id (uint32_t id)
4011 if (id >= insert_bitset.size()) {
4012 insert_bitset.resize (id+16, false);
4014 if (insert_bitset[id]) {
4015 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
4017 insert_bitset[id] = true;
4020 /* Named Selection management */
4023 Session::named_selection_by_name (string name)
4025 Glib::Mutex::Lock lm (named_selection_lock);
4026 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
4027 if ((*i)->name == name) {
4035 Session::add_named_selection (NamedSelection* named_selection)
4038 Glib::Mutex::Lock lm (named_selection_lock);
4039 named_selections.insert (named_selections.begin(), named_selection);
4042 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
4048 NamedSelectionAdded (); /* EMIT SIGNAL */
4052 Session::remove_named_selection (NamedSelection* named_selection)
4054 bool removed = false;
4057 Glib::Mutex::Lock lm (named_selection_lock);
4059 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
4061 if (i != named_selections.end()) {
4063 named_selections.erase (i);
4070 NamedSelectionRemoved (); /* EMIT SIGNAL */
4075 Session::reset_native_file_format ()
4077 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4079 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4080 (*i)->reset_write_sources (false);
4085 Session::route_name_unique (string n) const
4087 shared_ptr<RouteList> r = routes.reader ();
4089 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4090 if ((*i)->name() == n) {
4099 Session::route_name_internal (string n) const
4101 if (auditioner && auditioner->name() == n) {
4105 if (_click_io && _click_io->name() == n) {
4113 Session::n_playlists () const
4115 Glib::Mutex::Lock lm (playlist_lock);
4116 return playlists.size();
4120 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4122 if (!force && howmany <= _npan_buffers) {
4126 if (_pan_automation_buffer) {
4128 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4129 delete [] _pan_automation_buffer[i];
4132 delete [] _pan_automation_buffer;
4135 _pan_automation_buffer = new pan_t*[howmany];
4137 for (uint32_t i = 0; i < howmany; ++i) {
4138 _pan_automation_buffer[i] = new pan_t[nframes];
4141 _npan_buffers = howmany;
4145 Session::freeze (InterThreadInfo& itt)
4147 shared_ptr<RouteList> r = routes.reader ();
4149 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4151 boost::shared_ptr<Track> t;
4153 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4154 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4164 boost::shared_ptr<Region>
4165 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4166 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
4167 InterThreadInfo& itt, bool enable_processing)
4169 boost::shared_ptr<Region> result;
4170 boost::shared_ptr<Playlist> playlist;
4171 boost::shared_ptr<AudioFileSource> fsource;
4173 char buf[PATH_MAX+1];
4174 ChanCount nchans(track.audio_diskstream()->n_channels());
4176 nframes_t this_chunk;
4179 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4180 const string sound_dir = sdir.sound_path().to_string();
4181 nframes_t len = end - start;
4184 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4185 end, start) << endmsg;
4189 // any bigger than this seems to cause stack overflows in called functions
4190 const nframes_t chunk_size = (128 * 1024)/4;
4192 // block all process callback handling
4194 block_processing ();
4196 /* call tree *MUST* hold route_lock */
4198 if ((playlist = track.diskstream()->playlist()) == 0) {
4202 /* external redirects will be a problem */
4204 if (track.has_external_redirects()) {
4208 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4210 for (x = 0; x < 99999; ++x) {
4211 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4212 if (access (buf, F_OK) != 0) {
4218 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4223 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4224 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4227 catch (failed_constructor& err) {
4228 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4232 srcs.push_back (fsource);
4235 /* XXX need to flush all redirects */
4240 /* create a set of reasonably-sized buffers */
4241 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4242 buffers.set_count(nchans);
4244 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4245 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4247 afs->prepare_for_peakfile_writes ();
4250 while (to_do && !itt.cancel) {
4252 this_chunk = min (to_do, chunk_size);
4254 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4259 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4260 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4263 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4269 start += this_chunk;
4270 to_do -= this_chunk;
4272 itt.progress = (float) (1.0 - ((double) to_do / len));
4281 xnow = localtime (&now);
4283 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4284 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4287 afs->update_header (position, *xnow, now);
4288 afs->flush_header ();
4292 /* construct a region to represent the bounced material */
4294 result = RegionFactory::create (srcs, 0,
4295 srcs.front()->length(srcs.front()->timeline_position()),
4296 region_name_from_path (srcs.front()->name(), true));
4301 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4302 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4305 afs->mark_for_remove ();
4308 (*src)->drop_references ();
4312 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4313 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4316 afs->done_with_peakfile_writes ();
4320 unblock_processing ();
4326 Session::get_silent_buffers (ChanCount count)
4328 assert(_silent_buffers->available() >= count);
4329 _silent_buffers->set_count(count);
4331 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4332 for (size_t i= 0; i < count.get(*t); ++i) {
4333 _silent_buffers->get(*t, i).clear();
4337 return *_silent_buffers;
4341 Session::get_scratch_buffers (ChanCount count)
4343 if (count != ChanCount::ZERO) {
4344 assert(_scratch_buffers->available() >= count);
4345 _scratch_buffers->set_count(count);
4347 _scratch_buffers->set_count (_scratch_buffers->available());
4350 return *_scratch_buffers;
4354 Session::get_mix_buffers (ChanCount count)
4356 assert(_mix_buffers->available() >= count);
4357 _mix_buffers->set_count(count);
4358 return *_mix_buffers;
4362 Session::ntracks () const
4365 shared_ptr<RouteList> r = routes.reader ();
4367 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4368 if (boost::dynamic_pointer_cast<Track> (*i)) {
4377 Session::nbusses () const
4380 shared_ptr<RouteList> r = routes.reader ();
4382 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4383 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4392 Session::add_automation_list(AutomationList *al)
4394 automation_lists[al->id()] = al;
4398 Session::compute_initial_length ()
4400 return _engine.frame_rate() * 60 * 5;
4404 Session::sync_order_keys (std::string const & base)
4406 if (!Config->get_sync_all_route_ordering()) {
4407 /* leave order keys as they are */
4411 boost::shared_ptr<RouteList> r = routes.reader ();
4413 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4414 (*i)->sync_order_keys (base);
4417 Route::SyncOrderKeys (base); // EMIT SIGNAL
4421 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4423 Session::have_rec_enabled_diskstream () const
4425 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4428 /** Update the state of our rec-enabled diskstreams flag */
4430 Session::update_have_rec_enabled_diskstream ()
4432 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4433 DiskstreamList::iterator i = dsl->begin ();
4434 while (i != dsl->end () && (*i)->record_enabled () == false) {
4438 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4440 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4442 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4443 RecordStateChanged (); /* EMIT SIGNAL */
4448 Session::listen_position_changed ()
4452 switch (Config->get_listen_position()) {
4453 case AfterFaderListen:
4457 case PreFaderListen:
4462 boost::shared_ptr<RouteList> r = routes.reader ();
4464 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4465 (*i)->put_control_outs_at (p);
4470 Session::solo_control_mode_changed ()
4472 /* cancel all solo or all listen when solo control mode changes */
4474 if (Config->get_solo_control_is_listen_control()) {
4475 set_all_solo (false);
4477 set_all_listen (false);
4482 Session::route_group_changed ()
4484 RouteGroupChanged (); /* EMIT SIGNAL */
4488 Session::get_available_sync_options () const
4490 vector<SyncSource> ret;
4492 ret.push_back (JACK);
4495 ret.push_back (MTC);
4498 if (midi_clock_port()) {
4499 ret.push_back (MIDIClock);