remove entire "stub" file concept; open new audio and MIDI files on demand (at first...
[ardour2.git] / libs / ardour / session.cc
blobf1f2919b5f7244f2fe18c8f0c4e58c929cc65d1a
1 /*
2 Copyright (C) 1999-2010 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.
20 #include <stdint.h>
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25 #include <sstream>
26 #include <fstream>
27 #include <cstdio> /* sprintf(3) ... grrr */
28 #include <cmath>
29 #include <cerrno>
30 #include <unistd.h>
31 #include <limits.h>
33 #include <glibmm/thread.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
37 #include <boost/algorithm/string/erase.hpp>
39 #include "pbd/error.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"
46 #include "pbd/convert.h"
47 #include "pbd/strsplit.h"
49 #include "ardour/amp.h"
50 #include "ardour/analyser.h"
51 #include "ardour/audio_buffer.h"
52 #include "ardour/audio_diskstream.h"
53 #include "ardour/audio_port.h"
54 #include "ardour/audio_track.h"
55 #include "ardour/audioengine.h"
56 #include "ardour/audiofilesource.h"
57 #include "ardour/audioplaylist.h"
58 #include "ardour/audioregion.h"
59 #include "ardour/auditioner.h"
60 #include "ardour/buffer_manager.h"
61 #include "ardour/buffer_set.h"
62 #include "ardour/bundle.h"
63 #include "ardour/butler.h"
64 #include "ardour/click.h"
65 #include "ardour/configuration.h"
66 #include "ardour/crossfade.h"
67 #include "ardour/cycle_timer.h"
68 #include "ardour/data_type.h"
69 #include "ardour/debug.h"
70 #include "ardour/filename_extensions.h"
71 #include "ardour/internal_send.h"
72 #include "ardour/io_processor.h"
73 #include "ardour/midi_diskstream.h"
74 #include "ardour/midi_playlist.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/midi_track.h"
77 #include "ardour/midi_ui.h"
78 #include "ardour/named_selection.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/playlist.h"
81 #include "ardour/plugin_insert.h"
82 #include "ardour/port_insert.h"
83 #include "ardour/processor.h"
84 #include "ardour/rc_configuration.h"
85 #include "ardour/recent_sessions.h"
86 #include "ardour/region_factory.h"
87 #include "ardour/return.h"
88 #include "ardour/route_group.h"
89 #include "ardour/send.h"
90 #include "ardour/session.h"
91 #include "ardour/session_directory.h"
92 #include "ardour/session_directory.h"
93 #include "ardour/session_metadata.h"
94 #include "ardour/session_playlists.h"
95 #include "ardour/slave.h"
96 #include "ardour/smf_source.h"
97 #include "ardour/source_factory.h"
98 #include "ardour/tape_file_matcher.h"
99 #include "ardour/tempo.h"
100 #include "ardour/utils.h"
101 #include "ardour/graph.h"
102 #include "ardour/speakers.h"
103 #include "ardour/operations.h"
105 #include "midi++/port.h"
106 #include "midi++/mmc.h"
107 #include "midi++/manager.h"
109 #include "i18n.h"
111 using namespace std;
112 using namespace ARDOUR;
113 using namespace PBD;
115 bool Session::_disable_all_loaded_plugins = false;
117 PBD::Signal1<void,std::string> Session::Dialog;
118 PBD::Signal0<int> Session::AskAboutPendingState;
119 PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
120 PBD::Signal0<void> Session::SendFeedback;
121 PBD::Signal3<int,Session*,std::string,DataType> Session::MissingFile;
123 PBD::Signal1<void, framepos_t> Session::StartTimeChanged;
124 PBD::Signal1<void, framepos_t> Session::EndTimeChanged;
125 PBD::Signal0<void> Session::AutoBindingOn;
126 PBD::Signal0<void> Session::AutoBindingOff;
127 PBD::Signal2<void,std::string, std::string> Session::Exported;
128 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
129 PBD::Signal0<void> Session::Quit;
131 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
132 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
134 Session::Session (AudioEngine &eng,
135 const string& fullpath,
136 const string& snapshot_name,
137 BusProfile* bus_profile,
138 string mix_template)
139 : _engine (eng)
140 , _target_transport_speed (0.0)
141 , _requested_return_frame (-1)
142 , _session_dir (new SessionDirectory(fullpath))
143 , state_tree (0)
144 , _state_of_the_state (Clean)
145 , _butler (new Butler (*this))
146 , _post_transport_work (0)
147 , _send_timecode_update (false)
148 , _all_route_group (new RouteGroup (*this, "all"))
149 , route_graph (new Graph(*this))
150 , routes (new RouteList)
151 , _total_free_4k_blocks (0)
152 , _bundles (new BundleList)
153 , _bundle_xml_node (0)
154 , _current_trans (0)
155 , _click_io ((IO*) 0)
156 , click_data (0)
157 , click_emphasis_data (0)
158 , main_outs (0)
159 , _metadata (new SessionMetadata())
160 , _have_rec_enabled_track (false)
161 , _suspend_timecode_transmission (0)
163 _locations = new Locations (*this);
165 playlists.reset (new SessionPlaylists);
167 _all_route_group->set_active (true, this);
169 interpolation.add_channel_to (0, 0);
171 if (!eng.connected()) {
172 throw failed_constructor();
175 n_physical_outputs = _engine.n_physical_outputs ();
176 n_physical_inputs = _engine.n_physical_inputs ();
178 first_stage_init (fullpath, snapshot_name);
180 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
182 if (_is_new) {
183 if (create (mix_template, bus_profile)) {
184 destroy ();
185 throw failed_constructor ();
189 if (second_stage_init ()) {
190 destroy ();
191 throw failed_constructor ();
194 store_recent_sessions(_name, _path);
196 bool was_dirty = dirty();
198 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
200 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
201 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
203 if (was_dirty) {
204 DirtyChanged (); /* EMIT SIGNAL */
207 StartTimeChanged.connect_same_thread (*this, boost::bind (&Session::start_time_changed, this, _1));
208 EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
210 _is_new = false;
213 Session::~Session ()
215 destroy ();
218 void
219 Session::destroy ()
221 vector<void*> debug_pointers;
223 /* if we got to here, leaving pending capture state around
224 is a mistake.
227 remove_pending_capture_state ();
229 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
231 _engine.remove_session ();
233 /* clear history so that no references to objects are held any more */
235 _history.clear ();
237 /* clear state tree so that no references to objects are held any more */
239 delete state_tree;
241 /* reset dynamic state version back to default */
243 Stateful::loading_state_version = 0;
245 _butler->drop_references ();
246 delete _butler;
247 delete midi_control_ui;
248 delete _all_route_group;
250 if (click_data != default_click) {
251 delete [] click_data;
254 if (click_emphasis_data != default_click_emphasis) {
255 delete [] click_emphasis_data;
258 clear_clicks ();
260 /* clear out any pending dead wood from RCU managed objects */
262 routes.flush ();
263 _bundles.flush ();
265 AudioDiskstream::free_working_buffers();
267 /* tell everyone who is still standing that we're about to die */
268 drop_references ();
270 /* tell everyone to drop references and delete objects as we go */
272 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
273 named_selections.clear ();
275 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
276 RegionFactory::delete_all_regions ();
278 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
280 /* reset these three references to special routes before we do the usual route delete thing */
282 auditioner.reset ();
283 _master_out.reset ();
284 _monitor_out.reset ();
287 RCUWriter<RouteList> writer (routes);
288 boost::shared_ptr<RouteList> r = writer.get_copy ();
290 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
291 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
292 (*i)->drop_references ();
295 r->clear ();
296 /* writer goes out of scope and updates master */
298 routes.flush ();
300 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
301 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
302 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
303 i->second->drop_references ();
306 sources.clear ();
308 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
309 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
311 delete *i;
314 Crossfade::set_buffer_size (0);
316 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
317 playlists.reset ();
319 delete _locations;
321 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
323 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
324 boost_debug_list_ptrs ();
325 #endif
328 void
329 Session::set_worst_io_latencies ()
331 _worst_output_latency = 0;
332 _worst_input_latency = 0;
334 if (!_engine.connected()) {
335 return;
338 boost::shared_ptr<RouteList> r = routes.reader ();
340 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
341 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
342 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
346 void
347 Session::when_engine_running ()
349 string first_physical_output;
351 BootMessage (_("Set block size and sample rate"));
353 set_block_size (_engine.frames_per_cycle());
354 set_frame_rate (_engine.frame_rate());
356 BootMessage (_("Using configuration"));
358 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
359 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
361 Config->map_parameters (ff);
362 config.map_parameters (ft);
364 /* every time we reconnect, recompute worst case output latencies */
366 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
368 if (synced_to_jack()) {
369 _engine.transport_stop ();
372 if (config.get_jack_time_master()) {
373 _engine.transport_locate (_transport_frame);
376 _clicking = false;
378 try {
379 XMLNode* child = 0;
381 _click_io.reset (new ClickIO (*this, "click"));
383 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
385 /* existing state for Click */
386 int c;
388 if (Stateful::loading_state_version < 3000) {
389 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
390 } else {
391 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
395 if (c == 0) {
396 _clicking = Config->get_clicking ();
398 } else {
400 error << _("could not setup Click I/O") << endmsg;
401 _clicking = false;
405 } else {
407 /* default state for Click: dual-mono to first 2 physical outputs */
409 vector<string> outs;
410 _engine.get_physical_outputs (DataType::AUDIO, outs);
412 for (uint32_t physport = 0; physport < 2; ++physport) {
413 if (outs.size() > physport) {
414 if (_click_io->add_port (outs[physport], this)) {
415 // relax, even though its an error
420 if (_click_io->n_ports () > ChanCount::ZERO) {
421 _clicking = Config->get_clicking ();
426 catch (failed_constructor& err) {
427 error << _("cannot setup Click I/O") << endmsg;
430 BootMessage (_("Compute I/O Latencies"));
432 set_worst_io_latencies ();
434 if (_clicking) {
435 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
438 BootMessage (_("Set up standard connections"));
440 vector<string> inputs[DataType::num_types];
441 vector<string> outputs[DataType::num_types];
442 for (uint32_t i = 0; i < DataType::num_types; ++i) {
443 _engine.get_physical_inputs (DataType (DataType::Symbol (i)), inputs[i]);
444 _engine.get_physical_outputs (DataType (DataType::Symbol (i)), outputs[i]);
447 /* Create a set of Bundle objects that map
448 to the physical I/O currently available. We create both
449 mono and stereo bundles, so that the common cases of mono
450 and stereo tracks get bundles to put in their mixer strip
451 in / out menus. There may be a nicer way of achieving that;
452 it doesn't really scale that well to higher channel counts
455 /* mono output bundles */
457 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); ++np) {
458 char buf[32];
459 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
461 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
462 c->add_channel (_("mono"), DataType::AUDIO);
463 c->set_port (0, outputs[DataType::AUDIO][np]);
465 add_bundle (c);
468 /* stereo output bundles */
470 for (uint32_t np = 0; np < outputs[DataType::AUDIO].size(); np += 2) {
471 if (np + 1 < outputs[DataType::AUDIO].size()) {
472 char buf[32];
473 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
474 boost::shared_ptr<Bundle> c (new Bundle (buf, true));
475 c->add_channel (_("L"), DataType::AUDIO);
476 c->set_port (0, outputs[DataType::AUDIO][np]);
477 c->add_channel (_("R"), DataType::AUDIO);
478 c->set_port (1, outputs[DataType::AUDIO][np + 1]);
480 add_bundle (c);
484 /* mono input bundles */
486 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); ++np) {
487 char buf[32];
488 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
490 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
491 c->add_channel (_("mono"), DataType::AUDIO);
492 c->set_port (0, inputs[DataType::AUDIO][np]);
494 add_bundle (c);
497 /* stereo input bundles */
499 for (uint32_t np = 0; np < inputs[DataType::AUDIO].size(); np += 2) {
500 if (np + 1 < inputs[DataType::AUDIO].size()) {
501 char buf[32];
502 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
504 boost::shared_ptr<Bundle> c (new Bundle (buf, false));
505 c->add_channel (_("L"), DataType::AUDIO);
506 c->set_port (0, inputs[DataType::AUDIO][np]);
507 c->add_channel (_("R"), DataType::AUDIO);
508 c->set_port (1, inputs[DataType::AUDIO][np + 1]);
510 add_bundle (c);
514 /* MIDI input bundles */
516 for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
517 string n = inputs[DataType::MIDI][np];
518 boost::erase_first (n, X_("alsa_pcm:"));
520 boost::shared_ptr<Bundle> c (new Bundle (n, false));
521 c->add_channel ("", DataType::MIDI);
522 c->set_port (0, inputs[DataType::MIDI][np]);
523 add_bundle (c);
526 /* MIDI output bundles */
528 for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
529 string n = outputs[DataType::MIDI][np];
530 boost::erase_first (n, X_("alsa_pcm:"));
532 boost::shared_ptr<Bundle> c (new Bundle (n, true));
533 c->add_channel ("", DataType::MIDI);
534 c->set_port (0, outputs[DataType::MIDI][np]);
535 add_bundle (c);
538 BootMessage (_("Setup signal flow and plugins"));
540 hookup_io ();
542 if (_is_new && !no_auto_connect()) {
544 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
546 /* don't connect the master bus outputs if there is a monitor bus */
548 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
550 /* if requested auto-connect the outputs to the first N physical ports.
553 uint32_t limit = _master_out->n_outputs().n_total();
555 for (uint32_t n = 0; n < limit; ++n) {
556 Port* p = _master_out->output()->nth (n);
557 string connect_to;
558 if (outputs[p->type()].size() > n) {
559 connect_to = outputs[p->type()][n];
562 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
563 if (_master_out->output()->connect (p, connect_to, this)) {
564 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
565 << endmsg;
566 break;
572 if (_monitor_out) {
574 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
575 are undefined, at best.
578 /* control out listens to master bus (but ignores it
579 under some conditions)
582 uint32_t limit = _monitor_out->n_inputs().n_audio();
584 if (_master_out) {
585 for (uint32_t n = 0; n < limit; ++n) {
586 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
587 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
589 if (o) {
590 string connect_to = o->name();
591 if (_monitor_out->input()->connect (p, connect_to, this)) {
592 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
593 << endmsg;
594 break;
600 /* if control out is not connected, connect control out to physical outs
603 if (!_monitor_out->output()->connected ()) {
605 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
607 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
609 if (b) {
610 _monitor_out->output()->connect_ports_to_bundle (b, this);
611 } else {
612 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
613 Config->get_monitor_bus_preferred_bundle())
614 << endmsg;
617 } else {
619 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
620 uint32_t mod = n_physical_outputs.get (*t);
621 uint32_t limit = _monitor_out->n_outputs().get(*t);
623 for (uint32_t n = 0; n < limit; ++n) {
625 Port* p = _monitor_out->output()->ports().port(*t, n);
626 string connect_to;
627 if (outputs[*t].size() > (n % mod)) {
628 connect_to = outputs[*t][n % mod];
631 if (!connect_to.empty()) {
632 if (_monitor_out->output()->connect (p, connect_to, this)) {
633 error << string_compose (
634 _("cannot connect control output %1 to %2"),
635 n, connect_to)
636 << endmsg;
637 break;
647 /* catch up on send+insert cnts */
649 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
651 /* hook us up to the engine */
653 BootMessage (_("Connect to engine"));
655 _engine.set_session (this);
656 _engine.update_total_latencies ();
659 void
660 Session::hookup_io ()
662 /* stop graph reordering notifications from
663 causing resorts, etc.
666 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
668 if (!auditioner) {
670 /* we delay creating the auditioner till now because
671 it makes its own connections to ports.
674 try {
675 boost::shared_ptr<Auditioner> a (new Auditioner (*this));
676 if (a->init()) {
677 throw failed_constructor ();
679 a->use_new_diskstream ();
680 auditioner = a;
683 catch (failed_constructor& err) {
684 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
688 /* load bundles, which we may have postponed earlier on */
689 if (_bundle_xml_node) {
690 load_bundles (*_bundle_xml_node);
691 delete _bundle_xml_node;
694 /* Tell all IO objects to connect themselves together */
696 IO::enable_connecting ();
697 MIDI::Port::MakeConnections ();
699 /* Now reset all panners */
701 Delivery::reset_panners ();
703 /* Connect tracks to monitor/listen bus if there is one.
704 Note that in an existing session, the internal sends will
705 already exist, but we want the routes to notice that
706 they connect to the control out specifically.
709 if (_monitor_out) {
710 boost::shared_ptr<RouteList> r = routes.reader ();
711 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
713 if ((*x)->is_monitor()) {
715 /* relax */
717 } else if ((*x)->is_master()) {
719 /* relax */
721 } else {
723 (*x)->listen_via_monitor ();
728 /* Anyone who cares about input state, wake up and do something */
730 IOConnectionsComplete (); /* EMIT SIGNAL */
732 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
734 /* now handle the whole enchilada as if it was one
735 graph reorder event.
738 graph_reordered ();
740 /* update the full solo state, which can't be
741 correctly determined on a per-route basis, but
742 needs the global overview that only the session
743 has.
746 update_route_solo_state ();
749 void
750 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
752 boost::shared_ptr<Track> track = wp.lock ();
753 if (!track) {
754 return;
757 boost::shared_ptr<Playlist> playlist;
759 if ((playlist = track->playlist()) != 0) {
760 playlist->RegionAdded.connect_same_thread (*this, boost::bind (&Session::playlist_region_added, this, _1));
761 playlist->RangesMoved.connect_same_thread (*this, boost::bind (&Session::playlist_ranges_moved, this, _1));
762 playlist->RegionsExtended.connect_same_thread (*this, boost::bind (&Session::playlist_regions_extended, this, _1));
766 bool
767 Session::record_enabling_legal () const
769 /* this used to be in here, but survey says.... we don't need to restrict it */
770 // if (record_status() == Recording) {
771 // return false;
772 // }
774 if (Config->get_all_safe()) {
775 return false;
777 return true;
780 void
781 Session::reset_input_monitor_state ()
783 if (transport_rolling()) {
785 boost::shared_ptr<RouteList> rl = routes.reader ();
786 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
787 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
788 if (tr && tr->record_enabled ()) {
789 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
790 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
794 } else {
796 boost::shared_ptr<RouteList> rl = routes.reader ();
797 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
798 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
799 if (tr && tr->record_enabled ()) {
800 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
801 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
807 void
808 Session::auto_punch_start_changed (Location* location)
810 replace_event (SessionEvent::PunchIn, location->start());
812 if (get_record_enabled() && config.get_punch_in()) {
813 /* capture start has been changed, so save new pending state */
814 save_state ("", true);
818 void
819 Session::auto_punch_end_changed (Location* location)
821 framepos_t when_to_stop = location->end();
822 // when_to_stop += _worst_output_latency + _worst_input_latency;
823 replace_event (SessionEvent::PunchOut, when_to_stop);
826 void
827 Session::auto_punch_changed (Location* location)
829 framepos_t when_to_stop = location->end();
831 replace_event (SessionEvent::PunchIn, location->start());
832 //when_to_stop += _worst_output_latency + _worst_input_latency;
833 replace_event (SessionEvent::PunchOut, when_to_stop);
836 void
837 Session::auto_loop_changed (Location* location)
839 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
841 if (transport_rolling() && play_loop) {
844 // if (_transport_frame > location->end()) {
846 if (_transport_frame < location->start() || _transport_frame > location->end()) {
847 // relocate to beginning of loop
848 clear_events (SessionEvent::LocateRoll);
850 request_locate (location->start(), true);
853 else if (Config->get_seamless_loop() && !loop_changing) {
855 // schedule a locate-roll to refill the diskstreams at the
856 // previous loop end
857 loop_changing = true;
859 if (location->end() > last_loopend) {
860 clear_events (SessionEvent::LocateRoll);
861 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
862 queue_event (ev);
868 last_loopend = location->end();
871 void
872 Session::set_auto_punch_location (Location* location)
874 Location* existing;
876 if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
877 punch_connections.drop_connections();
878 existing->set_auto_punch (false, this);
879 remove_event (existing->start(), SessionEvent::PunchIn);
880 clear_events (SessionEvent::PunchOut);
881 auto_punch_location_changed (0);
884 set_dirty();
886 if (location == 0) {
887 return;
890 if (location->end() <= location->start()) {
891 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
892 return;
895 punch_connections.drop_connections ();
897 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
898 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
899 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
901 location->set_auto_punch (true, this);
903 auto_punch_changed (location);
905 auto_punch_location_changed (location);
908 void
909 Session::set_auto_loop_location (Location* location)
911 Location* existing;
913 if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
914 loop_connections.drop_connections ();
915 existing->set_auto_loop (false, this);
916 remove_event (existing->end(), SessionEvent::AutoLoop);
917 auto_loop_location_changed (0);
920 set_dirty();
922 if (location == 0) {
923 return;
926 if (location->end() <= location->start()) {
927 error << _("Session: you can't use a mark for auto loop") << endmsg;
928 return;
931 last_loopend = location->end();
933 loop_connections.drop_connections ();
935 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
936 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
937 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
939 location->set_auto_loop (true, this);
941 /* take care of our stuff first */
943 auto_loop_changed (location);
945 /* now tell everyone else */
947 auto_loop_location_changed (location);
950 void
951 Session::locations_added (Location *)
953 set_dirty ();
956 void
957 Session::locations_changed ()
959 _locations->apply (*this, &Session::handle_locations_changed);
962 void
963 Session::handle_locations_changed (Locations::LocationList& locations)
965 Locations::LocationList::iterator i;
966 Location* location;
967 bool set_loop = false;
968 bool set_punch = false;
970 for (i = locations.begin(); i != locations.end(); ++i) {
972 location =* i;
974 if (location->is_auto_punch()) {
975 set_auto_punch_location (location);
976 set_punch = true;
978 if (location->is_auto_loop()) {
979 set_auto_loop_location (location);
980 set_loop = true;
983 if (location->is_session_range()) {
984 _session_range_location = location;
988 if (!set_loop) {
989 set_auto_loop_location (0);
991 if (!set_punch) {
992 set_auto_punch_location (0);
995 set_dirty();
998 void
999 Session::enable_record ()
1001 while (1) {
1002 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
1004 if (rs == Recording) {
1005 break;
1008 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
1010 _last_record_location = _transport_frame;
1011 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
1013 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1015 boost::shared_ptr<RouteList> rl = routes.reader ();
1016 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1017 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1018 if (tr && tr->record_enabled ()) {
1019 tr->monitor_input (true);
1024 RecordStateChanged ();
1025 break;
1030 void
1031 Session::disable_record (bool rt_context, bool force)
1033 RecordState rs;
1035 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1037 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1038 g_atomic_int_set (&_record_status, Disabled);
1039 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
1040 } else {
1041 if (rs == Recording) {
1042 g_atomic_int_set (&_record_status, Enabled);
1046 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1048 boost::shared_ptr<RouteList> rl = routes.reader ();
1049 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1050 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1051 if (tr && tr->record_enabled ()) {
1052 tr->monitor_input (false);
1057 RecordStateChanged (); /* emit signal */
1059 if (!rt_context) {
1060 remove_pending_capture_state ();
1065 void
1066 Session::step_back_from_record ()
1068 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1070 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1071 boost::shared_ptr<RouteList> rl = routes.reader ();
1072 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1073 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1074 if (tr && tr->record_enabled ()) {
1075 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1076 tr->monitor_input (false);
1083 void
1084 Session::maybe_enable_record ()
1086 if (_step_editors > 0) {
1087 return;
1090 g_atomic_int_set (&_record_status, Enabled);
1092 /* This function is currently called from somewhere other than an RT thread.
1093 This save_state() call therefore doesn't impact anything. Doing it here
1094 means that we save pending state of which sources the next record will use,
1095 which gives us some chance of recovering from a crash during the record.
1098 save_state ("", true);
1100 if (_transport_speed) {
1101 if (!config.get_punch_in()) {
1102 enable_record ();
1104 } else {
1105 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1106 RecordStateChanged (); /* EMIT SIGNAL */
1109 set_dirty();
1112 framepos_t
1113 Session::audible_frame () const
1115 framepos_t ret;
1116 framepos_t tf;
1117 framecnt_t offset;
1119 /* the first of these two possible settings for "offset"
1120 mean that the audible frame is stationary until
1121 audio emerges from the latency compensation
1122 "pseudo-pipeline".
1124 the second means that the audible frame is stationary
1125 until audio would emerge from a physical port
1126 in the absence of any plugin latency compensation
1129 offset = _worst_output_latency;
1131 if (offset > current_block_size) {
1132 offset -= current_block_size;
1133 } else {
1134 /* XXX is this correct? if we have no external
1135 physical connections and everything is internal
1136 then surely this is zero? still, how
1137 likely is that anyway?
1139 offset = current_block_size;
1142 if (synced_to_jack()) {
1143 tf = _engine.transport_frame();
1144 } else {
1145 tf = _transport_frame;
1148 ret = tf;
1150 if (!non_realtime_work_pending()) {
1152 /* MOVING */
1154 /* Check to see if we have passed the first guaranteed
1155 audible frame past our last start position. if not,
1156 return that last start point because in terms
1157 of audible frames, we have not moved yet.
1159 `Start position' in this context means the time we last
1160 either started or changed transport direction.
1163 if (_transport_speed > 0.0f) {
1165 if (!play_loop || !have_looped) {
1166 if (tf < _last_roll_or_reversal_location + offset) {
1167 return _last_roll_or_reversal_location;
1172 /* forwards */
1173 ret -= offset;
1175 } else if (_transport_speed < 0.0f) {
1177 /* XXX wot? no backward looping? */
1179 if (tf > _last_roll_or_reversal_location - offset) {
1180 return _last_roll_or_reversal_location;
1181 } else {
1182 /* backwards */
1183 ret += offset;
1188 return ret;
1191 void
1192 Session::set_frame_rate (framecnt_t frames_per_second)
1194 /** \fn void Session::set_frame_size(framecnt_t)
1195 the AudioEngine object that calls this guarantees
1196 that it will not be called while we are also in
1197 ::process(). Its fine to do things that block
1198 here.
1201 _base_frame_rate = frames_per_second;
1203 sync_time_vars();
1205 Automatable::set_automation_interval (ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1207 clear_clicks ();
1209 // XXX we need some equivalent to this, somehow
1210 // SndFileSource::setup_standard_crossfades (frames_per_second);
1212 set_dirty();
1214 /* XXX need to reset/reinstantiate all LADSPA plugins */
1217 void
1218 Session::set_block_size (pframes_t nframes)
1220 /* the AudioEngine guarantees
1221 that it will not be called while we are also in
1222 ::process(). It is therefore fine to do things that block
1223 here.
1227 current_block_size = nframes;
1229 ensure_buffers ();
1231 boost::shared_ptr<RouteList> r = routes.reader ();
1233 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1234 (*i)->set_block_size (nframes);
1237 boost::shared_ptr<RouteList> rl = routes.reader ();
1238 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1239 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1240 if (tr) {
1241 tr->set_block_size (nframes);
1245 set_worst_io_latencies ();
1249 struct RouteSorter {
1250 /** @return true to run r1 before r2, otherwise false */
1251 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1252 if (r2->feeds (r1)) {
1253 /* r1 fed by r2; run r2 early */
1254 return false;
1255 } else if (r1->feeds (r2)) {
1256 /* r2 fed by r1; run r1 early */
1257 return true;
1258 } else {
1259 if (r1->not_fed ()) {
1260 if (r2->not_fed ()) {
1261 /* no ardour-based connections inbound to either route. just use signal order */
1262 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1263 } else {
1264 /* r2 has connections, r1 does not; run r1 early */
1265 return true;
1267 } else {
1268 if (r2->not_fed()) {
1269 /* r1 has connections, r2 does not; run r2 early */
1270 return false;
1271 } else {
1272 /* both r1 and r2 have connections, but not to each other. just use signal order */
1273 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1280 static void
1281 trace_terminal (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> rbase)
1283 boost::shared_ptr<Route> r2;
1285 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1286 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1287 return;
1290 /* make a copy of the existing list of routes that feed r1 */
1292 Route::FedBy existing (r1->fed_by());
1294 /* for each route that feeds r1, recurse, marking it as feeding
1295 rbase as well.
1298 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1299 if (!(r2 = i->r.lock ())) {
1300 /* (*i) went away, ignore it */
1301 continue;
1304 /* r2 is a route that feeds r1 which somehow feeds base. mark
1305 base as being fed by r2
1308 rbase->add_fed_by (r2, i->sends_only);
1310 if (r2 != rbase) {
1312 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1313 stop here.
1316 if (r1->feeds (r2) && r2->feeds (r1)) {
1317 continue;
1320 /* now recurse, so that we can mark base as being fed by
1321 all routes that feed r2
1324 trace_terminal (r2, rbase);
1330 void
1331 Session::resort_routes ()
1333 /* don't do anything here with signals emitted
1334 by Routes while we are being destroyed.
1337 if (_state_of_the_state & Deletion) {
1338 return;
1342 RCUWriter<RouteList> writer (routes);
1343 boost::shared_ptr<RouteList> r = writer.get_copy ();
1344 resort_routes_using (r);
1345 /* writer goes out of scope and forces update */
1348 //route_graph->dump(1);
1350 #ifndef NDEBUG
1351 boost::shared_ptr<RouteList> rl = routes.reader ();
1352 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1353 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1355 const Route::FedBy& fb ((*i)->fed_by());
1357 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1358 boost::shared_ptr<Route> sf = f->r.lock();
1359 if (sf) {
1360 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1364 #endif
1367 void
1368 Session::resort_routes_using (boost::shared_ptr<RouteList> r)
1370 RouteList::iterator i, j;
1372 for (i = r->begin(); i != r->end(); ++i) {
1374 (*i)->clear_fed_by ();
1376 for (j = r->begin(); j != r->end(); ++j) {
1378 /* although routes can feed themselves, it will
1379 cause an endless recursive descent if we
1380 detect it. so don't bother checking for
1381 self-feeding.
1384 if (*j == *i) {
1385 continue;
1388 bool via_sends_only;
1390 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1391 (*i)->add_fed_by (*j, via_sends_only);
1396 for (i = r->begin(); i != r->end(); ++i) {
1397 trace_terminal (*i, *i);
1400 RouteSorter cmp;
1401 r->sort (cmp);
1403 route_graph->rechain (r);
1405 #ifndef NDEBUG
1406 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1407 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1408 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1409 (*i)->name(), (*i)->order_key ("signal")));
1411 #endif
1415 /** Find a route name starting with \a base, maybe followed by the
1416 * lowest \a id. \a id will always be added if \a definitely_add_number
1417 * is true on entry; otherwise it will only be added if required
1418 * to make the name unique.
1420 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1421 * The available route name with the lowest ID will be used, and \a id
1422 * will be set to the ID.
1424 * \return false if a route name could not be found, and \a track_name
1425 * and \a id do not reflect a free route name.
1427 bool
1428 Session::find_route_name (string const & base, uint32_t& id, char* name, size_t name_len, bool definitely_add_number)
1430 if (!definitely_add_number && route_by_name (base) == 0) {
1431 /* juse use the base */
1432 snprintf (name, name_len, "%s", base.c_str());
1433 return true;
1436 do {
1437 snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
1439 if (route_by_name (name) == 0) {
1440 return true;
1443 ++id;
1445 } while (id < (UINT_MAX-1));
1447 return false;
1450 /** Count the total ins and outs of all non-hidden routes in the session and return them in in and out */
1451 void
1452 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1454 in = ChanCount::ZERO;
1455 out = ChanCount::ZERO;
1456 boost::shared_ptr<RouteList> r = routes.reader ();
1457 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1458 if (!(*i)->is_hidden()) {
1459 in += (*i)->n_inputs();
1460 out += (*i)->n_outputs();
1465 /** Caller must not hold process lock
1466 * @param name_template string to use for the start of the name, or "" to use "Midi".
1468 list<boost::shared_ptr<MidiTrack> >
1469 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template)
1471 char track_name[32];
1472 uint32_t track_id = 0;
1473 ChanCount existing_inputs;
1474 ChanCount existing_outputs;
1475 string port;
1476 RouteList new_routes;
1477 list<boost::shared_ptr<MidiTrack> > ret;
1478 uint32_t control_id;
1480 count_existing_route_channels (existing_inputs, existing_outputs);
1482 control_id = ntracks() + nbusses();
1484 bool const use_number = (how_many != 1);
1486 while (how_many) {
1487 if (!find_route_name (name_template.empty() ? _("Midi") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1488 error << "cannot find name for new midi track" << endmsg;
1489 goto failed;
1492 boost::shared_ptr<MidiTrack> track;
1494 try {
1495 track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1497 if (track->init ()) {
1498 goto failed;
1501 track->use_new_diskstream();
1503 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1504 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1505 #endif
1507 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1508 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1509 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1510 goto failed;
1513 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1514 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1515 goto failed;
1519 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1521 track->non_realtime_input_change();
1523 if (route_group) {
1524 route_group->add (track);
1527 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1528 track->set_remote_control_id (control_id);
1530 new_routes.push_back (track);
1531 ret.push_back (track);
1534 catch (failed_constructor &err) {
1535 error << _("Session: could not create new midi track.") << endmsg;
1536 goto failed;
1539 catch (AudioEngine::PortRegistrationFailure& pfe) {
1541 error << string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME) << endmsg;
1542 goto failed;
1545 --how_many;
1548 failed:
1549 if (!new_routes.empty()) {
1550 add_routes (new_routes, false);
1551 save_state (_current_snapshot_name);
1554 return ret;
1557 /** Caller must hold process lock.
1558 * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs.
1559 * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0.
1560 * @param output_start As \a input_start, but for outputs.
1562 void
1563 Session::auto_connect_route (
1564 Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start
1567 /* If both inputs and outputs are auto-connected to physical ports,
1568 use the max of input and output offsets to ensure auto-connected
1569 port numbers always match up (e.g. the first audio input and the
1570 first audio output of the route will have the same physical
1571 port number). Otherwise just use the lowest input or output
1572 offset possible.
1575 const bool in_out_physical =
1576 (Config->get_input_auto_connect() & AutoConnectPhysical)
1577 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1578 && connect_inputs;
1580 const ChanCount in_offset = in_out_physical
1581 ? ChanCount::max(existing_inputs, existing_outputs)
1582 : existing_inputs;
1584 const ChanCount out_offset = in_out_physical
1585 ? ChanCount::max(existing_inputs, existing_outputs)
1586 : existing_outputs;
1588 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1589 vector<string> physinputs;
1590 vector<string> physoutputs;
1592 _engine.get_physical_outputs (*t, physoutputs);
1593 _engine.get_physical_inputs (*t, physinputs);
1595 if (!physinputs.empty() && connect_inputs) {
1596 uint32_t nphysical_in = physinputs.size();
1597 for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1598 string port;
1600 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1601 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1604 if (!port.empty() && route->input()->connect (
1605 route->input()->ports().port(*t, i), port, this)) {
1606 break;
1611 if (!physoutputs.empty()) {
1612 uint32_t nphysical_out = physoutputs.size();
1613 for (uint32_t i = output_start.get(*t); i < route->n_outputs().get(*t); ++i) {
1614 string port;
1616 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1617 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1618 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1619 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1620 port = _master_out->input()->ports().port(*t,
1621 i % _master_out->input()->n_ports().get(*t))->name();
1625 if (!port.empty() && route->output()->connect (
1626 route->output()->ports().port(*t, i), port, this)) {
1627 break;
1633 existing_inputs += route->n_inputs();
1634 existing_outputs += route->n_outputs();
1637 /** Caller must not hold process lock
1638 * @param name_template string to use for the start of the name, or "" to use "Audio".
1640 list< boost::shared_ptr<AudioTrack> >
1641 Session::new_audio_track (
1642 int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template
1645 char track_name[32];
1646 uint32_t track_id = 0;
1647 ChanCount existing_inputs;
1648 ChanCount existing_outputs;
1649 string port;
1650 RouteList new_routes;
1651 list<boost::shared_ptr<AudioTrack> > ret;
1652 uint32_t control_id;
1654 count_existing_route_channels (existing_inputs, existing_outputs);
1656 control_id = ntracks() + nbusses() + 1;
1658 bool const use_number = (how_many != 1);
1660 while (how_many) {
1661 if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
1662 error << "cannot find name for new audio track" << endmsg;
1663 goto failed;
1666 boost::shared_ptr<AudioTrack> track;
1668 try {
1669 track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1671 if (track->init ()) {
1672 goto failed;
1675 track->use_new_diskstream();
1677 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1678 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1679 #endif
1681 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1683 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1684 error << string_compose (
1685 _("cannot configure %1 in/%2 out configuration for new audio track"),
1686 input_channels, output_channels)
1687 << endmsg;
1688 goto failed;
1691 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1692 error << string_compose (
1693 _("cannot configure %1 in/%2 out configuration for new audio track"),
1694 input_channels, output_channels)
1695 << endmsg;
1696 goto failed;
1699 auto_connect_route (track.get(), existing_inputs, existing_outputs);
1702 if (route_group) {
1703 route_group->add (track);
1706 track->non_realtime_input_change();
1708 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1709 track->set_remote_control_id (control_id);
1710 ++control_id;
1712 new_routes.push_back (track);
1713 ret.push_back (track);
1716 catch (failed_constructor &err) {
1717 error << _("Session: could not create new audio track.") << endmsg;
1718 goto failed;
1721 catch (AudioEngine::PortRegistrationFailure& pfe) {
1723 error << pfe.what() << endmsg;
1724 goto failed;
1727 --how_many;
1730 failed:
1731 if (!new_routes.empty()) {
1732 add_routes (new_routes, true);
1735 return ret;
1738 void
1739 Session::set_remote_control_ids ()
1741 RemoteModel m = Config->get_remote_model();
1742 bool emit_signal = false;
1744 boost::shared_ptr<RouteList> r = routes.reader ();
1746 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1747 if (MixerOrdered == m) {
1748 int32_t order = (*i)->order_key(N_("signal"));
1749 (*i)->set_remote_control_id (order+1, false);
1750 emit_signal = true;
1751 } else if (EditorOrdered == m) {
1752 int32_t order = (*i)->order_key(N_("editor"));
1753 (*i)->set_remote_control_id (order+1, false);
1754 emit_signal = true;
1755 } else if (UserOrdered == m) {
1756 //do nothing ... only changes to remote id's are initiated by user
1760 if (emit_signal) {
1761 Route::RemoteControlIDChange();
1765 /** Caller must not hold process lock.
1766 * @param name_template string to use for the start of the name, or "" to use "Bus".
1768 RouteList
1769 Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
1771 char bus_name[32];
1772 uint32_t bus_id = 0;
1773 ChanCount existing_inputs;
1774 ChanCount existing_outputs;
1775 string port;
1776 RouteList ret;
1777 uint32_t control_id;
1779 count_existing_route_channels (existing_inputs, existing_outputs);
1781 control_id = ntracks() + nbusses() + 1;
1783 bool const use_number = (how_many != 1);
1784 while (how_many) {
1785 if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, sizeof(bus_name), use_number)) {
1786 error << "cannot find name for new audio bus" << endmsg;
1787 goto failure;
1790 try {
1791 boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1793 if (bus->init ()) {
1794 goto failure;
1797 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1798 boost_debug_shared_ptr_mark_interesting (bus.get(), "Route");
1799 #endif
1801 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1803 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1804 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1805 input_channels, output_channels)
1806 << endmsg;
1807 goto failure;
1811 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1812 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1813 input_channels, output_channels)
1814 << endmsg;
1815 goto failure;
1818 auto_connect_route (bus.get(), existing_inputs, existing_outputs, false);
1821 if (route_group) {
1822 route_group->add (bus);
1824 bus->set_remote_control_id (control_id);
1825 ++control_id;
1827 bus->add_internal_return ();
1829 ret.push_back (bus);
1833 catch (failed_constructor &err) {
1834 error << _("Session: could not create new audio route.") << endmsg;
1835 goto failure;
1838 catch (AudioEngine::PortRegistrationFailure& pfe) {
1839 error << pfe.what() << endmsg;
1840 goto failure;
1844 --how_many;
1847 failure:
1848 if (!ret.empty()) {
1849 add_routes (ret, true);
1852 return ret;
1856 RouteList
1857 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1859 char name[32];
1860 RouteList ret;
1861 uint32_t control_id;
1862 XMLTree tree;
1863 uint32_t number = 0;
1865 if (!tree.read (template_path.c_str())) {
1866 return ret;
1869 XMLNode* node = tree.root();
1871 control_id = ntracks() + nbusses() + 1;
1873 while (how_many) {
1875 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1877 std::string node_name = IO::name_from_state (*node_copy.children().front());
1879 /* generate a new name by adding a number to the end of the template name */
1880 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name), true)) {
1881 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1882 /*NOTREACHED*/
1885 /* set IO children to use the new name */
1886 XMLNodeList const & children = node_copy.children ();
1887 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1888 if ((*i)->name() == IO::state_node_name) {
1889 IO::set_name_in_state (**i, name);
1893 Track::zero_diskstream_id_in_xml (node_copy);
1895 try {
1896 boost::shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1898 if (route == 0) {
1899 error << _("Session: cannot create track/bus from template description") << endmsg;
1900 goto out;
1903 if (boost::dynamic_pointer_cast<Track>(route)) {
1904 /* force input/output change signals so that the new diskstream
1905 picks up the configuration of the route. During session
1906 loading this normally happens in a different way.
1909 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
1911 IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
1912 change.after = route->input()->n_ports();
1913 route->input()->changed (change, this);
1914 change.after = route->output()->n_ports();
1915 route->output()->changed (change, this);
1918 route->set_remote_control_id (control_id);
1919 ++control_id;
1921 ret.push_back (route);
1924 catch (failed_constructor &err) {
1925 error << _("Session: could not create new route from template") << endmsg;
1926 goto out;
1929 catch (AudioEngine::PortRegistrationFailure& pfe) {
1930 error << pfe.what() << endmsg;
1931 goto out;
1934 --how_many;
1937 out:
1938 if (!ret.empty()) {
1939 add_routes (ret, true);
1942 return ret;
1945 void
1946 Session::add_routes (RouteList& new_routes, bool save)
1949 RCUWriter<RouteList> writer (routes);
1950 boost::shared_ptr<RouteList> r = writer.get_copy ();
1951 r->insert (r->end(), new_routes.begin(), new_routes.end());
1954 /* if there is no control out and we're not in the middle of loading,
1955 resort the graph here. if there is a control out, we will resort
1956 toward the end of this method. if we are in the middle of loading,
1957 we will resort when done.
1960 if (!_monitor_out && IO::connecting_legal) {
1961 resort_routes_using (r);
1965 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1967 boost::weak_ptr<Route> wpr (*x);
1968 boost::shared_ptr<Route> r (*x);
1970 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1971 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1972 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1973 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1974 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1975 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1976 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1978 if (r->is_master()) {
1979 _master_out = r;
1982 if (r->is_monitor()) {
1983 _monitor_out = r;
1986 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1987 if (tr) {
1988 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1989 track_playlist_changed (boost::weak_ptr<Track> (tr));
1990 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1992 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (tr);
1993 if (mt) {
1994 mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1));
1999 if (_monitor_out && IO::connecting_legal) {
2001 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2002 if ((*x)->is_monitor()) {
2003 /* relax */
2004 } else if ((*x)->is_master()) {
2005 /* relax */
2006 } else {
2007 (*x)->listen_via_monitor ();
2011 resort_routes ();
2014 set_dirty();
2016 if (save) {
2017 save_state (_current_snapshot_name);
2020 RouteAdded (new_routes); /* EMIT SIGNAL */
2021 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2024 void
2025 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2027 boost::shared_ptr<RouteList> r = routes.reader ();
2028 boost::shared_ptr<Send> s;
2030 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2031 if ((s = (*i)->internal_send_for (dest)) != 0) {
2032 s->amp()->gain_control()->set_value (0.0);
2037 void
2038 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2040 boost::shared_ptr<RouteList> r = routes.reader ();
2041 boost::shared_ptr<Send> s;
2043 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2044 if ((s = (*i)->internal_send_for (dest)) != 0) {
2045 s->amp()->gain_control()->set_value (1.0);
2050 void
2051 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2053 boost::shared_ptr<RouteList> r = routes.reader ();
2054 boost::shared_ptr<Send> s;
2056 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2057 if ((s = (*i)->internal_send_for (dest)) != 0) {
2058 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2063 /** @param include_buses true to add sends to buses and tracks, false for just tracks */
2064 void
2065 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p, bool include_buses)
2067 boost::shared_ptr<RouteList> r = routes.reader ();
2068 boost::shared_ptr<RouteList> t (new RouteList);
2070 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2071 if (include_buses || boost::dynamic_pointer_cast<Track>(*i)) {
2072 t->push_back (*i);
2076 add_internal_sends (dest, p, t);
2079 void
2080 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2082 if (dest->is_monitor() || dest->is_master()) {
2083 return;
2086 if (!dest->internal_return()) {
2087 dest->add_internal_return();
2090 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2092 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2093 continue;
2096 (*i)->listen_via (dest, p);
2099 graph_reordered ();
2102 void
2103 Session::remove_route (boost::shared_ptr<Route> route)
2105 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2106 return;
2109 route->set_solo (false, this);
2112 RCUWriter<RouteList> writer (routes);
2113 boost::shared_ptr<RouteList> rs = writer.get_copy ();
2115 rs->remove (route);
2117 /* deleting the master out seems like a dumb
2118 idea, but its more of a UI policy issue
2119 than our concern.
2122 if (route == _master_out) {
2123 _master_out = boost::shared_ptr<Route> ();
2126 if (route == _monitor_out) {
2128 /* cancel control outs for all routes */
2130 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2131 (*r)->drop_listen (_monitor_out);
2134 _monitor_out.reset ();
2137 /* writer goes out of scope, forces route list update */
2140 update_route_solo_state ();
2142 // We need to disconnect the route's inputs and outputs
2144 route->input()->disconnect (0);
2145 route->output()->disconnect (0);
2147 /* if the route had internal sends sending to it, remove them */
2148 if (route->internal_return()) {
2150 boost::shared_ptr<RouteList> r = routes.reader ();
2151 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2152 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2153 if (s) {
2154 (*i)->remove_processor (s);
2159 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
2160 if (mt && mt->step_editing()) {
2161 if (_step_editors > 0) {
2162 _step_editors--;
2166 update_latency_compensation (false, false);
2167 set_dirty();
2169 /* Re-sort routes to remove the graph's current references to the one that is
2170 * going away, then flush old references out of the graph.
2173 resort_routes ();
2174 route_graph->clear_other_chain ();
2176 /* get rid of it from the dead wood collection in the route list manager */
2178 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2180 routes.flush ();
2182 /* try to cause everyone to drop their references */
2184 route->drop_references ();
2186 sync_order_keys (N_("session"));
2188 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2190 /* save the new state of the world */
2192 if (save_state (_current_snapshot_name)) {
2193 save_history (_current_snapshot_name);
2197 void
2198 Session::route_mute_changed (void* /*src*/)
2200 set_dirty ();
2203 void
2204 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2206 boost::shared_ptr<Route> route = wpr.lock();
2207 if (!route) {
2208 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2209 return;
2212 if (route->listening_via_monitor ()) {
2214 if (Config->get_exclusive_solo()) {
2215 /* new listen: disable all other listen */
2216 boost::shared_ptr<RouteList> r = routes.reader ();
2217 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2218 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2219 continue;
2221 (*i)->set_listen (false, this);
2225 _listen_cnt++;
2227 } else if (_listen_cnt > 0) {
2229 _listen_cnt--;
2232 update_route_solo_state ();
2234 void
2235 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2237 boost::shared_ptr<Route> route = wpr.lock ();
2239 if (!route) {
2240 /* should not happen */
2241 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2242 return;
2245 bool send_changed = false;
2247 if (route->solo_isolated()) {
2248 if (_solo_isolated_cnt == 0) {
2249 send_changed = true;
2251 _solo_isolated_cnt++;
2252 } else if (_solo_isolated_cnt > 0) {
2253 _solo_isolated_cnt--;
2254 if (_solo_isolated_cnt == 0) {
2255 send_changed = true;
2259 if (send_changed) {
2260 IsolatedChanged (); /* EMIT SIGNAL */
2264 void
2265 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2267 if (!self_solo_change) {
2268 // session doesn't care about changes to soloed-by-others
2269 return;
2272 if (solo_update_disabled) {
2273 // We know already
2274 return;
2277 boost::shared_ptr<Route> route = wpr.lock ();
2279 if (!route) {
2280 /* should not happen */
2281 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2282 return;
2285 boost::shared_ptr<RouteList> r = routes.reader ();
2286 int32_t delta;
2288 if (route->self_soloed()) {
2289 delta = 1;
2290 } else {
2291 delta = -1;
2294 if (delta == 1 && Config->get_exclusive_solo()) {
2295 /* new solo: disable all other solos */
2296 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2297 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2298 continue;
2300 (*i)->set_solo (false, this);
2304 solo_update_disabled = true;
2306 RouteList uninvolved;
2308 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2309 bool via_sends_only;
2310 bool in_signal_flow;
2312 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2313 continue;
2316 in_signal_flow = false;
2318 if ((*i)->feeds (route, &via_sends_only)) {
2319 if (!via_sends_only) {
2320 if (!route->soloed_by_others_upstream()) {
2321 (*i)->mod_solo_by_others_downstream (delta);
2323 in_signal_flow = true;
2327 if (route->feeds (*i, &via_sends_only)) {
2328 (*i)->mod_solo_by_others_upstream (delta);
2329 in_signal_flow = true;
2332 if (!in_signal_flow) {
2333 uninvolved.push_back (*i);
2337 solo_update_disabled = false;
2338 update_route_solo_state (r);
2340 /* now notify that the mute state of the routes not involved in the signal
2341 pathway of the just-solo-changed route may have altered.
2344 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2345 (*i)->mute_changed (this);
2348 SoloChanged (); /* EMIT SIGNAL */
2349 set_dirty();
2352 void
2353 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2355 /* now figure out if anything that matters is soloed (or is "listening")*/
2357 bool something_soloed = false;
2358 uint32_t listeners = 0;
2359 uint32_t isolated = 0;
2361 if (!r) {
2362 r = routes.reader();
2365 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2366 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2367 something_soloed = true;
2370 if (!(*i)->is_hidden() && (*i)->listening_via_monitor()) {
2371 if (Config->get_solo_control_is_listen_control()) {
2372 listeners++;
2373 } else {
2374 (*i)->set_listen (false, this);
2378 if ((*i)->solo_isolated()) {
2379 isolated++;
2383 if (something_soloed != _non_soloed_outs_muted) {
2384 _non_soloed_outs_muted = something_soloed;
2385 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2388 _listen_cnt = listeners;
2390 if (isolated != _solo_isolated_cnt) {
2391 _solo_isolated_cnt = isolated;
2392 IsolatedChanged (); /* EMIT SIGNAL */
2396 boost::shared_ptr<RouteList>
2397 Session::get_routes_with_internal_returns() const
2399 boost::shared_ptr<RouteList> r = routes.reader ();
2400 boost::shared_ptr<RouteList> rl (new RouteList);
2402 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2403 if ((*i)->internal_return ()) {
2404 rl->push_back (*i);
2407 return rl;
2410 bool
2411 Session::io_name_is_legal (const std::string& name)
2413 boost::shared_ptr<RouteList> r = routes.reader ();
2415 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2416 if ((*i)->name() == name) {
2417 return false;
2420 if ((*i)->has_io_processor_named (name)) {
2421 return false;
2425 return true;
2428 boost::shared_ptr<Route>
2429 Session::route_by_name (string name)
2431 boost::shared_ptr<RouteList> r = routes.reader ();
2433 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2434 if ((*i)->name() == name) {
2435 return *i;
2439 return boost::shared_ptr<Route> ((Route*) 0);
2442 boost::shared_ptr<Route>
2443 Session::route_by_id (PBD::ID id)
2445 boost::shared_ptr<RouteList> r = routes.reader ();
2447 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2448 if ((*i)->id() == id) {
2449 return *i;
2453 return boost::shared_ptr<Route> ((Route*) 0);
2456 boost::shared_ptr<Route>
2457 Session::route_by_remote_id (uint32_t id)
2459 boost::shared_ptr<RouteList> r = routes.reader ();
2461 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2462 if ((*i)->remote_control_id() == id) {
2463 return *i;
2467 return boost::shared_ptr<Route> ((Route*) 0);
2470 void
2471 Session::playlist_region_added (boost::weak_ptr<Region> w)
2473 boost::shared_ptr<Region> r = w.lock ();
2474 if (!r) {
2475 return;
2478 /* These are the operations that are currently in progress... */
2479 list<GQuark> curr = _current_trans_quarks;
2480 curr.sort ();
2482 /* ...and these are the operations during which we want to update
2483 the session range location markers.
2485 list<GQuark> ops;
2486 ops.push_back (Operations::capture);
2487 ops.push_back (Operations::paste);
2488 ops.push_back (Operations::duplicate_region);
2489 ops.push_back (Operations::insert_file);
2490 ops.push_back (Operations::insert_region);
2491 ops.push_back (Operations::drag_region_brush);
2492 ops.push_back (Operations::region_drag);
2493 ops.push_back (Operations::selection_grab);
2494 ops.push_back (Operations::region_fill);
2495 ops.push_back (Operations::fill_selection);
2496 ops.push_back (Operations::create_region);
2497 ops.sort ();
2499 /* See if any of the current operations match the ones that we want */
2500 list<GQuark> in;
2501 set_intersection (_current_trans_quarks.begin(), _current_trans_quarks.end(), ops.begin(), ops.end(), back_inserter (in));
2503 /* If so, update the session range markers */
2504 if (!in.empty ()) {
2505 maybe_update_session_range (r->position (), r->last_frame ());
2509 /** Update the session range markers if a is before the current start or
2510 * b is after the current end.
2512 void
2513 Session::maybe_update_session_range (framepos_t a, framepos_t b)
2515 if (_state_of_the_state & Loading) {
2516 return;
2519 if (_session_range_location == 0) {
2521 add_session_range_location (a, b);
2523 } else {
2525 if (a < _session_range_location->start()) {
2526 _session_range_location->set_start (a);
2529 if (b > _session_range_location->end()) {
2530 _session_range_location->set_end (b);
2535 void
2536 Session::playlist_ranges_moved (list<Evoral::RangeMove<framepos_t> > const & ranges)
2538 for (list<Evoral::RangeMove<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2539 maybe_update_session_range (i->to, i->to + i->length);
2543 void
2544 Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ranges)
2546 for (list<Evoral::Range<framepos_t> >::const_iterator i = ranges.begin(); i != ranges.end(); ++i) {
2547 maybe_update_session_range (i->from, i->to);
2551 /* Region management */
2553 boost::shared_ptr<Region>
2554 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2556 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2557 RegionFactory::RegionMap::const_iterator i;
2558 boost::shared_ptr<Region> region;
2560 Glib::Mutex::Lock lm (region_lock);
2562 for (i = regions.begin(); i != regions.end(); ++i) {
2564 region = i->second;
2566 if (region->whole_file()) {
2568 if (child->source_equivalent (region)) {
2569 return region;
2574 return boost::shared_ptr<Region> ();
2578 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2580 set<boost::shared_ptr<Region> > relevant_regions;
2582 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2583 RegionFactory::get_regions_using_source (*s, relevant_regions);
2586 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2588 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2589 set<boost::shared_ptr<Region> >::iterator tmp;
2591 tmp = r;
2592 ++tmp;
2594 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2596 playlists->destroy_region (*r);
2597 RegionFactory::map_remove (*r);
2599 (*r)->drop_sources ();
2600 (*r)->drop_references ();
2602 cerr << "\tdone UC = " << (*r).use_count() << endl;
2604 relevant_regions.erase (r);
2606 r = tmp;
2609 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2612 Glib::Mutex::Lock ls (source_lock);
2613 /* remove from the main source list */
2614 sources.erase ((*s)->id());
2617 (*s)->mark_for_remove ();
2618 (*s)->drop_references ();
2620 s = srcs.erase (s);
2623 return 0;
2627 Session::remove_last_capture ()
2629 list<boost::shared_ptr<Source> > srcs;
2631 boost::shared_ptr<RouteList> rl = routes.reader ();
2632 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2633 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2634 if (!tr) {
2635 continue;
2638 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2640 if (!l.empty()) {
2641 srcs.insert (srcs.end(), l.begin(), l.end());
2642 l.clear ();
2646 destroy_sources (srcs);
2648 save_state (_current_snapshot_name);
2650 return 0;
2653 /* Source Management */
2655 void
2656 Session::add_source (boost::shared_ptr<Source> source)
2658 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2659 pair<SourceMap::iterator,bool> result;
2661 entry.first = source->id();
2662 entry.second = source;
2665 Glib::Mutex::Lock lm (source_lock);
2666 result = sources.insert (entry);
2669 if (result.second) {
2671 /* yay, new source */
2673 set_dirty();
2675 boost::shared_ptr<AudioFileSource> afs;
2677 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2678 if (Config->get_auto_analyse_audio()) {
2679 Analyser::queue_source_for_analysis (source, false);
2683 source->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
2687 void
2688 Session::remove_source (boost::weak_ptr<Source> src)
2690 if (_state_of_the_state & Deletion) {
2691 return;
2694 SourceMap::iterator i;
2695 boost::shared_ptr<Source> source = src.lock();
2697 if (!source) {
2698 return;
2702 Glib::Mutex::Lock lm (source_lock);
2704 if ((i = sources.find (source->id())) != sources.end()) {
2705 sources.erase (i);
2709 if (!_state_of_the_state & InCleanup) {
2711 /* save state so we don't end up with a session file
2712 referring to non-existent sources.
2715 save_state (_current_snapshot_name);
2719 boost::shared_ptr<Source>
2720 Session::source_by_id (const PBD::ID& id)
2722 Glib::Mutex::Lock lm (source_lock);
2723 SourceMap::iterator i;
2724 boost::shared_ptr<Source> source;
2726 if ((i = sources.find (id)) != sources.end()) {
2727 source = i->second;
2730 return source;
2733 boost::shared_ptr<Source>
2734 Session::source_by_path_and_channel (const string& path, uint16_t chn)
2736 Glib::Mutex::Lock lm (source_lock);
2738 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2739 boost::shared_ptr<AudioFileSource> afs
2740 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2742 if (afs && afs->path() == path && chn == afs->channel()) {
2743 return afs;
2746 return boost::shared_ptr<Source>();
2749 uint32_t
2750 Session::count_sources_by_origin (const string& path)
2752 uint32_t cnt = 0;
2753 Glib::Mutex::Lock lm (source_lock);
2755 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2756 boost::shared_ptr<FileSource> fs
2757 = boost::dynamic_pointer_cast<FileSource>(i->second);
2759 if (fs && fs->origin() == path) {
2760 ++cnt;
2764 return cnt;
2768 string
2769 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2771 string look_for;
2772 string old_basename = PBD::basename_nosuffix (oldname);
2773 string new_legalized = legalize_for_path (newname);
2775 /* note: we know (or assume) the old path is already valid */
2777 if (destructive) {
2779 /* destructive file sources have a name of the form:
2781 /path/to/Tnnnn-NAME(%[LR])?.wav
2783 the task here is to replace NAME with the new name.
2786 string dir;
2787 string prefix;
2788 string::size_type dash;
2790 dir = Glib::path_get_dirname (path);
2791 path = Glib::path_get_basename (path);
2793 /* '-' is not a legal character for the NAME part of the path */
2795 if ((dash = path.find_last_of ('-')) == string::npos) {
2796 return "";
2799 prefix = path.substr (0, dash);
2801 path += prefix;
2802 path += '-';
2803 path += new_legalized;
2804 path += native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2805 path = Glib::build_filename (dir, path);
2807 } else {
2809 /* non-destructive file sources have a name of the form:
2811 /path/to/NAME-nnnnn(%[LR])?.ext
2813 the task here is to replace NAME with the new name.
2816 string dir;
2817 string suffix;
2818 string::size_type dash;
2819 string::size_type postfix;
2821 dir = Glib::path_get_dirname (path);
2822 path = Glib::path_get_basename (path);
2824 /* '-' is not a legal character for the NAME part of the path */
2826 if ((dash = path.find_last_of ('-')) == string::npos) {
2827 return "";
2830 suffix = path.substr (dash+1);
2832 // Suffix is now everything after the dash. Now we need to eliminate
2833 // the nnnnn part, which is done by either finding a '%' or a '.'
2835 postfix = suffix.find_last_of ("%");
2836 if (postfix == string::npos) {
2837 postfix = suffix.find_last_of ('.');
2840 if (postfix != string::npos) {
2841 suffix = suffix.substr (postfix);
2842 } else {
2843 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2844 return "";
2847 const uint32_t limit = 10000;
2848 char buf[PATH_MAX+1];
2850 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2852 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2854 if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
2855 path = Glib::build_filename (dir, buf);
2856 break;
2859 path = "";
2862 if (path.empty()) {
2863 fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
2864 newname) << endl;
2865 /*NOTREACHED*/
2869 return path;
2872 /** Return the full path (in some session directory) for a new within-session source.
2873 * \a name must be a session-unique name that does not contain slashes
2874 * (e.g. as returned by new_*_source_name)
2876 string
2877 Session::new_source_path_from_name (DataType type, const string& name)
2879 assert(name.find("/") == string::npos);
2881 SessionDirectory sdir(get_best_session_directory_for_new_source());
2883 sys::path p;
2884 if (type == DataType::AUDIO) {
2885 p = sdir.sound_path();
2886 } else if (type == DataType::MIDI) {
2887 p = sdir.midi_path();
2888 } else {
2889 error << "Unknown source type, unable to create file path" << endmsg;
2890 return "";
2893 p /= name;
2894 return p.to_string();
2897 string
2898 Session::peak_path (string base) const
2900 sys::path peakfile_path(_session_dir->peak_path());
2901 peakfile_path /= base + peakfile_suffix;
2902 return peakfile_path.to_string();
2905 /** Return a unique name based on \a base for a new internal audio source */
2906 string
2907 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2909 uint32_t cnt;
2910 char buf[PATH_MAX+1];
2911 const uint32_t limit = 10000;
2912 string legalized;
2913 string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
2915 buf[0] = '\0';
2916 legalized = legalize_for_path (base);
2918 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2919 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2921 vector<space_and_path>::iterator i;
2922 uint32_t existing = 0;
2924 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2926 if (destructive) {
2928 if (nchan < 2) {
2929 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2930 cnt, legalized.c_str(), ext.c_str());
2931 } else if (nchan == 2) {
2932 if (chan == 0) {
2933 snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
2934 cnt, legalized.c_str(), ext.c_str());
2935 } else {
2936 snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
2937 cnt, legalized.c_str(), ext.c_str());
2939 } else if (nchan < 26) {
2940 snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
2941 cnt, legalized.c_str(), 'a' + chan, ext.c_str());
2942 } else {
2943 snprintf (buf, sizeof(buf), "T%04d-%s%s",
2944 cnt, legalized.c_str(), ext.c_str());
2947 } else {
2949 if (nchan < 2) {
2950 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2951 } else if (nchan == 2) {
2952 if (chan == 0) {
2953 snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
2954 } else {
2955 snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
2957 } else if (nchan < 26) {
2958 snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
2959 } else {
2960 snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
2964 SessionDirectory sdir((*i).path);
2966 string spath = sdir.sound_path().to_string();
2968 /* note that we search *without* the extension so that
2969 we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
2970 in the event that this new name is required for
2971 a file format change.
2974 if (matching_unsuffixed_filename_exists_in (spath, buf)) {
2975 existing++;
2976 break;
2980 if (existing == 0) {
2981 break;
2984 if (cnt > limit) {
2985 error << string_compose(
2986 _("There are already %1 recordings for %2, which I consider too many."),
2987 limit, base) << endmsg;
2988 destroy ();
2989 throw failed_constructor();
2993 return Glib::path_get_basename (buf);
2996 /** Create a new within-session audio source */
2997 boost::shared_ptr<AudioFileSource>
2998 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
3000 const string name = new_audio_source_name (n, n_chans, chan, destructive);
3001 const string path = new_source_path_from_name(DataType::AUDIO, name);
3003 return boost::dynamic_pointer_cast<AudioFileSource> (
3004 SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
3007 /** Return a unique name based on \a base for a new internal MIDI source */
3008 string
3009 Session::new_midi_source_name (const string& base)
3011 uint32_t cnt;
3012 char buf[PATH_MAX+1];
3013 const uint32_t limit = 10000;
3014 string legalized;
3016 buf[0] = '\0';
3017 legalized = legalize_for_path (base);
3019 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3020 for (cnt = 1; cnt <= limit; ++cnt) {
3022 vector<space_and_path>::iterator i;
3023 uint32_t existing = 0;
3025 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3027 SessionDirectory sdir((*i).path);
3029 sys::path p = sdir.midi_path();
3030 p /= legalized;
3032 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3034 if (sys::exists (buf)) {
3035 existing++;
3039 if (existing == 0) {
3040 break;
3043 if (cnt > limit) {
3044 error << string_compose(
3045 _("There are already %1 recordings for %2, which I consider too many."),
3046 limit, base) << endmsg;
3047 destroy ();
3048 throw failed_constructor();
3052 return Glib::path_get_basename(buf);
3056 /** Create a new within-session MIDI source */
3057 boost::shared_ptr<MidiSource>
3058 Session::create_midi_source_for_session (Track* track, string const & n)
3060 /* try to use the existing write source for the track, to keep numbering sane
3063 if (track) {
3064 /*MidiTrack* mt = dynamic_cast<Track*> (track);
3065 assert (mt);
3068 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
3070 if (!l.empty()) {
3071 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
3072 return boost::dynamic_pointer_cast<MidiSource> (l.front());
3076 const string name = new_midi_source_name (n);
3077 const string path = new_source_path_from_name (DataType::MIDI, name);
3079 return boost::dynamic_pointer_cast<SMFSource> (
3080 SourceFactory::createWritable (
3081 DataType::MIDI, *this, path, string(), false, frame_rate()));
3085 void
3086 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3088 if (playlist->hidden()) {
3089 return;
3092 playlists->add (playlist);
3094 if (unused) {
3095 playlist->release();
3098 set_dirty();
3101 void
3102 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3104 if (_state_of_the_state & Deletion) {
3105 return;
3108 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3110 if (!playlist) {
3111 return;
3114 playlists->remove (playlist);
3116 set_dirty();
3119 void
3120 Session::set_audition (boost::shared_ptr<Region> r)
3122 pending_audition_region = r;
3123 add_post_transport_work (PostTransportAudition);
3124 _butler->schedule_transport_work ();
3127 void
3128 Session::audition_playlist ()
3130 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3131 ev->region.reset ();
3132 queue_event (ev);
3135 void
3136 Session::non_realtime_set_audition ()
3138 if (!pending_audition_region) {
3139 auditioner->audition_current_playlist ();
3140 } else {
3141 auditioner->audition_region (pending_audition_region);
3142 pending_audition_region.reset ();
3144 AuditionActive (true); /* EMIT SIGNAL */
3147 void
3148 Session::audition_region (boost::shared_ptr<Region> r)
3150 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3151 ev->region = r;
3152 queue_event (ev);
3155 void
3156 Session::cancel_audition ()
3158 if (auditioner->auditioning()) {
3159 auditioner->cancel_audition ();
3160 AuditionActive (false); /* EMIT SIGNAL */
3164 bool
3165 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3167 if (a->is_monitor()) {
3168 return true;
3170 if (b->is_monitor()) {
3171 return false;
3173 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3176 bool
3177 Session::is_auditioning () const
3179 /* can be called before we have an auditioner object */
3180 if (auditioner) {
3181 return auditioner->auditioning();
3182 } else {
3183 return false;
3187 void
3188 Session::graph_reordered ()
3190 /* don't do this stuff if we are setting up connections
3191 from a set_state() call or creating new tracks. Ditto for deletion.
3194 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3195 return;
3198 /* every track/bus asked for this to be handled but it was deferred because
3199 we were connecting. do it now.
3202 request_input_change_handling ();
3204 resort_routes ();
3206 /* force all diskstreams to update their capture offset values to
3207 reflect any changes in latencies within the graph.
3210 boost::shared_ptr<RouteList> rl = routes.reader ();
3211 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3212 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3213 if (tr) {
3214 tr->set_capture_offset ();
3219 framecnt_t
3220 Session::available_capture_duration ()
3222 float sample_bytes_on_disk = 4.0; // keep gcc happy
3224 switch (config.get_native_file_data_format()) {
3225 case FormatFloat:
3226 sample_bytes_on_disk = 4.0;
3227 break;
3229 case FormatInt24:
3230 sample_bytes_on_disk = 3.0;
3231 break;
3233 case FormatInt16:
3234 sample_bytes_on_disk = 2.0;
3235 break;
3237 default:
3238 /* impossible, but keep some gcc versions happy */
3239 fatal << string_compose (_("programming error: %1"),
3240 X_("illegal native file data format"))
3241 << endmsg;
3242 /*NOTREACHED*/
3245 double scale = 4096.0 / sample_bytes_on_disk;
3247 if (_total_free_4k_blocks * scale > (double) max_framecnt) {
3248 return max_framecnt;
3251 return (framecnt_t) floor (_total_free_4k_blocks * scale);
3254 void
3255 Session::add_bundle (boost::shared_ptr<Bundle> bundle)
3258 RCUWriter<BundleList> writer (_bundles);
3259 boost::shared_ptr<BundleList> b = writer.get_copy ();
3260 b->push_back (bundle);
3263 BundleAdded (bundle); /* EMIT SIGNAL */
3265 set_dirty();
3268 void
3269 Session::remove_bundle (boost::shared_ptr<Bundle> bundle)
3271 bool removed = false;
3274 RCUWriter<BundleList> writer (_bundles);
3275 boost::shared_ptr<BundleList> b = writer.get_copy ();
3276 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3278 if (i != b->end()) {
3279 b->erase (i);
3280 removed = true;
3284 if (removed) {
3285 BundleRemoved (bundle); /* EMIT SIGNAL */
3288 set_dirty();
3291 boost::shared_ptr<Bundle>
3292 Session::bundle_by_name (string name) const
3294 boost::shared_ptr<BundleList> b = _bundles.reader ();
3296 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3297 if ((*i)->name() == name) {
3298 return* i;
3302 return boost::shared_ptr<Bundle> ();
3305 void
3306 Session::tempo_map_changed (const PropertyChange&)
3308 clear_clicks ();
3310 playlists->update_after_tempo_map_change ();
3312 _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
3314 set_dirty ();
3317 void
3318 Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
3320 for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
3321 (*i)->recompute_frames_from_bbt ();
3325 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3326 * the given count with the current block size.
3328 void
3329 Session::ensure_buffers (ChanCount howmany)
3331 BufferManager::ensure_buffers (howmany);
3334 void
3335 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3337 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3338 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3342 uint32_t
3343 Session::next_insert_id ()
3345 /* this doesn't really loop forever. just think about it */
3347 while (true) {
3348 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3349 if (!insert_bitset[n]) {
3350 insert_bitset[n] = true;
3351 return n;
3356 /* none available, so resize and try again */
3358 insert_bitset.resize (insert_bitset.size() + 16, false);
3362 uint32_t
3363 Session::next_send_id ()
3365 /* this doesn't really loop forever. just think about it */
3367 while (true) {
3368 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3369 if (!send_bitset[n]) {
3370 send_bitset[n] = true;
3371 return n;
3376 /* none available, so resize and try again */
3378 send_bitset.resize (send_bitset.size() + 16, false);
3382 uint32_t
3383 Session::next_return_id ()
3385 /* this doesn't really loop forever. just think about it */
3387 while (true) {
3388 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3389 if (!return_bitset[n]) {
3390 return_bitset[n] = true;
3391 return n;
3396 /* none available, so resize and try again */
3398 return_bitset.resize (return_bitset.size() + 16, false);
3402 void
3403 Session::mark_send_id (uint32_t id)
3405 if (id >= send_bitset.size()) {
3406 send_bitset.resize (id+16, false);
3408 if (send_bitset[id]) {
3409 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3411 send_bitset[id] = true;
3414 void
3415 Session::mark_return_id (uint32_t id)
3417 if (id >= return_bitset.size()) {
3418 return_bitset.resize (id+16, false);
3420 if (return_bitset[id]) {
3421 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3423 return_bitset[id] = true;
3426 void
3427 Session::mark_insert_id (uint32_t id)
3429 if (id >= insert_bitset.size()) {
3430 insert_bitset.resize (id+16, false);
3432 if (insert_bitset[id]) {
3433 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3435 insert_bitset[id] = true;
3438 void
3439 Session::unmark_send_id (uint32_t id)
3441 if (id < send_bitset.size()) {
3442 send_bitset[id] = false;
3446 void
3447 Session::unmark_return_id (uint32_t id)
3449 if (id < return_bitset.size()) {
3450 return_bitset[id] = false;
3454 void
3455 Session::unmark_insert_id (uint32_t id)
3457 if (id < insert_bitset.size()) {
3458 insert_bitset[id] = false;
3463 /* Named Selection management */
3465 boost::shared_ptr<NamedSelection>
3466 Session::named_selection_by_name (string name)
3468 Glib::Mutex::Lock lm (named_selection_lock);
3469 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3470 if ((*i)->name == name) {
3471 return *i;
3474 return boost::shared_ptr<NamedSelection>();
3477 void
3478 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3481 Glib::Mutex::Lock lm (named_selection_lock);
3482 named_selections.insert (named_selections.begin(), named_selection);
3485 set_dirty();
3487 NamedSelectionAdded (); /* EMIT SIGNAL */
3490 void
3491 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3493 bool removed = false;
3496 Glib::Mutex::Lock lm (named_selection_lock);
3498 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3500 if (i != named_selections.end()) {
3501 named_selections.erase (i);
3502 set_dirty();
3503 removed = true;
3507 if (removed) {
3508 NamedSelectionRemoved (); /* EMIT SIGNAL */
3512 void
3513 Session::reset_native_file_format ()
3515 boost::shared_ptr<RouteList> rl = routes.reader ();
3516 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3517 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3518 if (tr) {
3519 /* don't save state as we do this, there's no point
3522 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
3523 tr->reset_write_sources (false);
3524 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
3529 bool
3530 Session::route_name_unique (string n) const
3532 boost::shared_ptr<RouteList> r = routes.reader ();
3534 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3535 if ((*i)->name() == n) {
3536 return false;
3540 return true;
3543 bool
3544 Session::route_name_internal (string n) const
3546 if (auditioner && auditioner->name() == n) {
3547 return true;
3550 if (_click_io && _click_io->name() == n) {
3551 return true;
3554 return false;
3558 Session::freeze_all (InterThreadInfo& itt)
3560 boost::shared_ptr<RouteList> r = routes.reader ();
3562 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3564 boost::shared_ptr<Track> t;
3566 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3567 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3568 of every track.
3570 t->freeze_me (itt);
3574 return 0;
3577 boost::shared_ptr<Region>
3578 Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
3579 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3580 InterThreadInfo& itt, bool enable_processing)
3582 boost::shared_ptr<Region> result;
3583 boost::shared_ptr<Playlist> playlist;
3584 boost::shared_ptr<AudioFileSource> fsource;
3585 uint32_t x;
3586 char buf[PATH_MAX+1];
3587 ChanCount diskstream_channels (track.n_channels());
3588 framepos_t position;
3589 framecnt_t this_chunk;
3590 framepos_t to_do;
3591 BufferSet buffers;
3592 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3593 const string sound_dir = sdir.sound_path().to_string();
3594 framepos_t len = end - start;
3595 bool need_block_size_reset = false;
3596 string ext;
3597 ChanCount const max_proc = track.max_processor_streams ();
3599 if (end <= start) {
3600 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3601 end, start) << endmsg;
3602 return result;
3605 const framecnt_t chunk_size = (256 * 1024)/4;
3607 // block all process callback handling
3609 block_processing ();
3611 /* call tree *MUST* hold route_lock */
3613 if ((playlist = track.playlist()) == 0) {
3614 goto out;
3617 /* external redirects will be a problem */
3619 if (track.has_external_redirects()) {
3620 goto out;
3623 ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
3625 for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
3627 for (x = 0; x < 99999; ++x) {
3628 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 "%s", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1, ext.c_str());
3629 if (access (buf, F_OK) != 0) {
3630 break;
3634 if (x == 99999) {
3635 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3636 goto out;
3639 try {
3640 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3641 SourceFactory::createWritable (DataType::AUDIO, *this, buf, string(), false, frame_rate()));
3644 catch (failed_constructor& err) {
3645 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3646 goto out;
3649 srcs.push_back (fsource);
3652 /* tell redirects that care that we are about to use a much larger blocksize */
3654 need_block_size_reset = true;
3655 track.set_block_size (chunk_size);
3657 /* XXX need to flush all redirects */
3659 position = start;
3660 to_do = len;
3662 /* create a set of reasonably-sized buffers */
3663 buffers.ensure_buffers (DataType::AUDIO, max_proc.n_audio(), chunk_size);
3664 buffers.set_count (max_proc);
3666 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3667 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3668 if (afs)
3669 afs->prepare_for_peakfile_writes ();
3672 while (to_do && !itt.cancel) {
3674 this_chunk = min (to_do, chunk_size);
3676 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3677 goto out;
3680 uint32_t n = 0;
3681 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3682 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3684 if (afs) {
3685 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3686 goto out;
3691 start += this_chunk;
3692 to_do -= this_chunk;
3694 itt.progress = (float) (1.0 - ((double) to_do / len));
3698 if (!itt.cancel) {
3700 time_t now;
3701 struct tm* xnow;
3702 time (&now);
3703 xnow = localtime (&now);
3705 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3706 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3708 if (afs) {
3709 afs->update_header (position, *xnow, now);
3710 afs->flush_header ();
3714 /* construct a region to represent the bounced material */
3716 PropertyList plist;
3718 plist.add (Properties::start, 0);
3719 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3720 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3722 result = RegionFactory::create (srcs, plist);
3726 out:
3727 if (!result) {
3728 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3729 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3731 if (afs) {
3732 afs->mark_for_remove ();
3735 (*src)->drop_references ();
3738 } else {
3739 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3740 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3742 if (afs)
3743 afs->done_with_peakfile_writes ();
3748 if (need_block_size_reset) {
3749 track.set_block_size (get_block_size());
3752 unblock_processing ();
3754 return result;
3757 gain_t*
3758 Session::gain_automation_buffer() const
3760 return ProcessThread::gain_automation_buffer ();
3763 pan_t**
3764 Session::pan_automation_buffer() const
3766 return ProcessThread::pan_automation_buffer ();
3769 BufferSet&
3770 Session::get_silent_buffers (ChanCount count)
3772 return ProcessThread::get_silent_buffers (count);
3773 #if 0
3774 assert(_silent_buffers->available() >= count);
3775 _silent_buffers->set_count(count);
3777 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3778 for (size_t i= 0; i < count.get(*t); ++i) {
3779 _silent_buffers->get(*t, i).clear();
3783 return *_silent_buffers;
3784 #endif
3787 BufferSet&
3788 Session::get_scratch_buffers (ChanCount count)
3790 return ProcessThread::get_scratch_buffers (count);
3791 #if 0
3792 if (count != ChanCount::ZERO) {
3793 assert(_scratch_buffers->available() >= count);
3794 _scratch_buffers->set_count(count);
3795 } else {
3796 _scratch_buffers->set_count (_scratch_buffers->available());
3799 return *_scratch_buffers;
3800 #endif
3803 BufferSet&
3804 Session::get_mix_buffers (ChanCount count)
3806 return ProcessThread::get_mix_buffers (count);
3807 #if 0
3808 assert(_mix_buffers->available() >= count);
3809 _mix_buffers->set_count(count);
3810 return *_mix_buffers;
3811 #endif
3814 uint32_t
3815 Session::ntracks () const
3817 uint32_t n = 0;
3818 boost::shared_ptr<RouteList> r = routes.reader ();
3820 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3821 if (boost::dynamic_pointer_cast<Track> (*i)) {
3822 ++n;
3826 return n;
3829 uint32_t
3830 Session::nbusses () const
3832 uint32_t n = 0;
3833 boost::shared_ptr<RouteList> r = routes.reader ();
3835 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3836 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3837 ++n;
3841 return n;
3844 void
3845 Session::add_automation_list(AutomationList *al)
3847 automation_lists[al->id()] = al;
3850 void
3851 Session::sync_order_keys (std::string const & base)
3853 if (deletion_in_progress()) {
3854 return;
3857 if (!Config->get_sync_all_route_ordering()) {
3858 /* leave order keys as they are */
3859 return;
3862 boost::shared_ptr<RouteList> r = routes.reader ();
3864 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3865 (*i)->sync_order_keys (base);
3868 Route::SyncOrderKeys (base); // EMIT SIGNAL
3870 /* this might not do anything */
3872 set_remote_control_ids ();
3875 /** @return true if there is at least one record-enabled track, otherwise false */
3876 bool
3877 Session::have_rec_enabled_track () const
3879 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3882 /** Update the state of our rec-enabled tracks flag */
3883 void
3884 Session::update_have_rec_enabled_track ()
3886 boost::shared_ptr<RouteList> rl = routes.reader ();
3887 RouteList::iterator i = rl->begin();
3888 while (i != rl->end ()) {
3890 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3891 if (tr && tr->record_enabled ()) {
3892 break;
3895 ++i;
3898 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3900 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3902 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3903 RecordStateChanged (); /* EMIT SIGNAL */
3907 void
3908 Session::listen_position_changed ()
3910 boost::shared_ptr<RouteList> r = routes.reader ();
3912 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3913 (*i)->listen_position_changed ();
3917 void
3918 Session::solo_control_mode_changed ()
3920 /* cancel all solo or all listen when solo control mode changes */
3922 if (soloing()) {
3923 set_solo (get_routes(), false);
3924 } else if (listening()) {
3925 set_listen (get_routes(), false);
3929 /** Called when anything about any of our route groups changes (membership, state etc.) */
3930 void
3931 Session::route_group_changed ()
3933 RouteGroupChanged (); /* EMIT SIGNAL */
3936 vector<SyncSource>
3937 Session::get_available_sync_options () const
3939 vector<SyncSource> ret;
3941 ret.push_back (JACK);
3942 ret.push_back (MTC);
3943 ret.push_back (MIDIClock);
3945 return ret;
3948 boost::shared_ptr<RouteList>
3949 Session::get_routes_with_regions_at (framepos_t const p) const
3951 boost::shared_ptr<RouteList> r = routes.reader ();
3952 boost::shared_ptr<RouteList> rl (new RouteList);
3954 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3955 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3956 if (!tr) {
3957 continue;
3960 boost::shared_ptr<Playlist> pl = tr->playlist ();
3961 if (!pl) {
3962 continue;
3965 if (pl->has_region_at (p)) {
3966 rl->push_back (*i);
3970 return rl;
3973 void
3974 Session::goto_end ()
3976 if (_session_range_location) {
3977 request_locate (_session_range_location->end(), false);
3978 } else {
3979 request_locate (0, false);
3983 void
3984 Session::goto_start ()
3986 if (_session_range_location) {
3987 request_locate (_session_range_location->start(), false);
3988 } else {
3989 request_locate (0, false);
3993 framepos_t
3994 Session::current_start_frame () const
3996 return _session_range_location ? _session_range_location->start() : 0;
3999 framepos_t
4000 Session::current_end_frame () const
4002 return _session_range_location ? _session_range_location->end() : 0;
4005 void
4006 Session::add_session_range_location (framepos_t start, framepos_t end)
4008 _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
4009 _locations->add (_session_range_location);
4012 /** Called when one of our routes' order keys has changed */
4013 void
4014 Session::route_order_key_changed ()
4016 RouteOrderKeyChanged (); /* EMIT SIGNAL */
4019 void
4020 Session::step_edit_status_change (bool yn)
4022 bool send = false;
4024 bool val = false;
4025 if (yn) {
4026 send = (_step_editors == 0);
4027 val = true;
4029 _step_editors++;
4030 } else {
4031 send = (_step_editors == 1);
4032 val = false;
4034 if (_step_editors > 0) {
4035 _step_editors--;
4039 if (send) {
4040 StepEditStatusChange (val);
4045 void
4046 Session::start_time_changed (framepos_t old)
4048 /* Update the auto loop range to match the session range
4049 (unless the auto loop range has been changed by the user)
4052 Location* s = _locations->session_range_location ();
4053 if (s == 0) {
4054 return;
4057 Location* l = _locations->auto_loop_location ();
4059 if (l->start() == old) {
4060 l->set_start (s->start(), true);
4064 void
4065 Session::end_time_changed (framepos_t old)
4067 /* Update the auto loop range to match the session range
4068 (unless the auto loop range has been changed by the user)
4071 Location* s = _locations->session_range_location ();
4072 if (s == 0) {
4073 return;
4076 Location* l = _locations->auto_loop_location ();
4078 if (l->end() == old) {
4079 l->set_end (s->end(), true);
4083 string
4084 Session::source_search_path (DataType type) const
4086 string search_path;
4088 if (session_dirs.size() == 1) {
4089 switch (type) {
4090 case DataType::AUDIO:
4091 search_path = _session_dir->sound_path().to_string();
4092 break;
4093 case DataType::MIDI:
4094 search_path = _session_dir->midi_path().to_string();
4095 break;
4097 } else {
4098 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4099 SessionDirectory sdir (i->path);
4100 if (!search_path.empty()) {
4101 search_path += ':';
4103 switch (type) {
4104 case DataType::AUDIO:
4105 search_path += sdir.sound_path().to_string();
4106 break;
4107 case DataType::MIDI:
4108 search_path += sdir.midi_path().to_string();
4109 break;
4114 /* now add user-specified locations
4117 vector<string> dirs;
4119 switch (type) {
4120 case DataType::AUDIO:
4121 split (config.get_audio_search_path (), dirs, ':');
4122 break;
4123 case DataType::MIDI:
4124 split (config.get_midi_search_path (), dirs, ':');
4125 break;
4128 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4129 search_path += ':';
4130 search_path += *i;
4134 return search_path;
4137 void
4138 Session::ensure_search_path_includes (const string& path, DataType type)
4140 string search_path;
4141 vector<string> dirs;
4143 if (path == ".") {
4144 return;
4147 switch (type) {
4148 case DataType::AUDIO:
4149 search_path = config.get_audio_search_path ();
4150 break;
4151 case DataType::MIDI:
4152 search_path = config.get_midi_search_path ();
4153 break;
4156 split (search_path, dirs, ':');
4158 for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
4159 if (*i == path) {
4160 return;
4164 if (!search_path.empty()) {
4165 search_path += ':';
4168 search_path += path;
4170 switch (type) {
4171 case DataType::AUDIO:
4172 config.set_audio_search_path (search_path);
4173 break;
4174 case DataType::MIDI:
4175 config.set_midi_search_path (search_path);
4176 break;
4180 boost::shared_ptr<Speakers>
4181 Session::get_speakers()
4183 return _speakers;
4186 list<string>
4187 Session::unknown_processors () const
4189 list<string> p;
4191 boost::shared_ptr<RouteList> r = routes.reader ();
4192 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4193 list<string> t = (*i)->unknown_processors ();
4194 copy (t.begin(), t.end(), back_inserter (p));
4197 p.sort ();
4198 p.unique ();
4200 return p;
4203 #ifdef HAVE_JACK_NEW_LATENCY
4204 void
4205 Session::update_latency (bool playback)
4207 DEBUG_TRACE (DEBUG::Latency, "JACK latency callback\n");
4209 boost::shared_ptr<RouteList> r = routes.reader ();
4211 if (playback) {
4212 /* reverse the list so that we work backwards from the last route to run to the first */
4213 reverse (r->begin(), r->end());
4216 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4217 DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Working on latency for %1\n", (*i)->name()));
4218 (*i)->set_latency_ranges (playback);
4219 DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Done working on latency for %1\n\n", (*i)->name()));
4222 #endif