clear activation_sets component of Graph, thus restoring full Route deletion
[ardour2.git] / libs / ardour / session.cc
blob7a4a4c4e9ff556d4b9fab81544b3c3a6a76c13be
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 #define __STDC_LIMIT_MACROS
21 #include <stdint.h>
23 #include <algorithm>
24 #include <string>
25 #include <vector>
26 #include <sstream>
27 #include <fstream>
28 #include <cstdio> /* sprintf(3) ... grrr */
29 #include <cmath>
30 #include <cerrno>
31 #include <unistd.h>
32 #include <limits.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
36 #include <glibmm/fileutils.h>
38 #include "pbd/error.h"
39 #include "pbd/boost_debug.h"
40 #include "pbd/pathscanner.h"
41 #include "pbd/stl_delete.h"
42 #include "pbd/basename.h"
43 #include "pbd/stacktrace.h"
44 #include "pbd/file_utils.h"
45 #include "pbd/convert.h"
47 #include "ardour/amp.h"
48 #include "ardour/analyser.h"
49 #include "ardour/audio_buffer.h"
50 #include "ardour/audio_diskstream.h"
51 #include "ardour/audio_port.h"
52 #include "ardour/audio_track.h"
53 #include "ardour/audioengine.h"
54 #include "ardour/audiofilesource.h"
55 #include "ardour/audioplaylist.h"
56 #include "ardour/audioregion.h"
57 #include "ardour/auditioner.h"
58 #include "ardour/buffer_manager.h"
59 #include "ardour/buffer_set.h"
60 #include "ardour/bundle.h"
61 #include "ardour/butler.h"
62 #include "ardour/click.h"
63 #include "ardour/configuration.h"
64 #include "ardour/crossfade.h"
65 #include "ardour/cycle_timer.h"
66 #include "ardour/data_type.h"
67 #include "ardour/debug.h"
68 #include "ardour/filename_extensions.h"
69 #include "ardour/internal_send.h"
70 #include "ardour/io_processor.h"
71 #include "ardour/midi_diskstream.h"
72 #include "ardour/midi_playlist.h"
73 #include "ardour/midi_region.h"
74 #include "ardour/midi_track.h"
75 #include "ardour/midi_ui.h"
76 #include "ardour/named_selection.h"
77 #include "ardour/process_thread.h"
78 #include "ardour/playlist.h"
79 #include "ardour/plugin_insert.h"
80 #include "ardour/port_insert.h"
81 #include "ardour/processor.h"
82 #include "ardour/rc_configuration.h"
83 #include "ardour/recent_sessions.h"
84 #include "ardour/region_factory.h"
85 #include "ardour/return.h"
86 #include "ardour/route_group.h"
87 #include "ardour/send.h"
88 #include "ardour/session.h"
89 #include "ardour/session_directory.h"
90 #include "ardour/session_directory.h"
91 #include "ardour/session_metadata.h"
92 #include "ardour/session_playlists.h"
93 #include "ardour/slave.h"
94 #include "ardour/smf_source.h"
95 #include "ardour/source_factory.h"
96 #include "ardour/tape_file_matcher.h"
97 #include "ardour/tempo.h"
98 #include "ardour/utils.h"
99 #include "ardour/graph.h"
101 #include "midi++/jack.h"
103 #include "i18n.h"
105 using namespace std;
106 using namespace ARDOUR;
107 using namespace PBD;
108 using boost::shared_ptr;
109 using boost::weak_ptr;
111 bool Session::_disable_all_loaded_plugins = false;
113 PBD::Signal1<void,std::string> Session::Dialog;
114 PBD::Signal0<int> Session::AskAboutPendingState;
115 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
116 PBD::Signal0<void> Session::SendFeedback;
118 PBD::Signal0<void> Session::TimecodeOffsetChanged;
119 PBD::Signal0<void> Session::StartTimeChanged;
120 PBD::Signal0<void> Session::EndTimeChanged;
121 PBD::Signal0<void> Session::AutoBindingOn;
122 PBD::Signal0<void> Session::AutoBindingOff;
123 PBD::Signal2<void,std::string, std::string> Session::Exported;
124 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
126 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
127 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
129 Session::Session (AudioEngine &eng,
130 const string& fullpath,
131 const string& snapshot_name,
132 BusProfile* bus_profile,
133 string mix_template)
135 : _engine (eng),
136 _target_transport_speed (0.0),
137 _requested_return_frame (-1),
138 mmc (0),
139 _mmc_port (default_mmc_port),
140 _mtc_port (default_mtc_port),
141 _midi_port (default_midi_port),
142 _midi_clock_port (default_midi_clock_port),
143 _session_dir (new SessionDirectory(fullpath)),
144 state_tree (0),
145 _butler (new Butler (*this)),
146 _post_transport_work (0),
147 _send_timecode_update (false),
148 route_graph (new Graph(*this)),
149 routes (new RouteList),
150 _total_free_4k_blocks (0),
151 _bundles (new BundleList),
152 _bundle_xml_node (0),
153 _click_io ((IO*) 0),
154 click_data (0),
155 click_emphasis_data (0),
156 main_outs (0),
157 _metadata (new SessionMetadata()),
158 _have_rec_enabled_track (false)
161 playlists.reset (new SessionPlaylists);
163 interpolation.add_channel_to (0, 0);
165 if (!eng.connected()) {
166 throw failed_constructor();
169 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
170 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
172 first_stage_init (fullpath, snapshot_name);
174 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
176 if (_is_new) {
177 if (create (mix_template, bus_profile)) {
178 destroy ();
179 throw failed_constructor ();
183 if (second_stage_init ()) {
184 destroy ();
185 throw failed_constructor ();
188 store_recent_sessions(_name, _path);
190 bool was_dirty = dirty();
192 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
194 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
195 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
197 if (was_dirty) {
198 DirtyChanged (); /* EMIT SIGNAL */
201 _is_new = false;
204 Session::~Session ()
206 destroy ();
209 void
210 Session::destroy ()
212 vector<void*> debug_pointers;
214 /* if we got to here, leaving pending capture state around
215 is a mistake.
218 remove_pending_capture_state ();
220 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
222 _engine.remove_session ();
224 /* clear history so that no references to objects are held any more */
226 _history.clear ();
228 /* clear state tree so that no references to objects are held any more */
230 delete state_tree;
232 /* reset dynamic state version back to default */
234 Stateful::loading_state_version = 0;
236 _butler->drop_references ();
237 delete _butler;
238 delete midi_control_ui;
240 if (click_data != default_click) {
241 delete [] click_data;
244 if (click_emphasis_data != default_click_emphasis) {
245 delete [] click_emphasis_data;
248 clear_clicks ();
250 /* clear out any pending dead wood from RCU managed objects */
252 routes.flush ();
253 _bundles.flush ();
255 AudioDiskstream::free_working_buffers();
257 /* tell everyone who is still standing that we're about to die */
258 drop_references ();
260 /* tell everyone to drop references and delete objects as we go */
262 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
263 named_selections.clear ();
265 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
266 RegionFactory::delete_all_regions ();
268 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
270 /* reset these three references to special routes before we do the usual route delete thing */
272 auditioner.reset ();
273 _master_out.reset ();
274 _monitor_out.reset ();
277 RCUWriter<RouteList> writer (routes);
278 boost::shared_ptr<RouteList> r = writer.get_copy ();
280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
281 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
282 (*i)->drop_references ();
285 r->clear ();
286 /* writer goes out of scope and updates master */
288 routes.flush ();
290 boost::shared_ptr<RouteList> r = routes.reader ();
292 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
293 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
294 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
295 i->second->drop_references ();
298 sources.clear ();
300 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
301 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
303 delete *i;
306 Crossfade::set_buffer_size (0);
308 delete mmc;
310 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
311 playlists.reset ();
313 boost_debug_list_ptrs ();
315 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
318 void
319 Session::set_worst_io_latencies ()
321 _worst_output_latency = 0;
322 _worst_input_latency = 0;
324 if (!_engine.connected()) {
325 return;
328 boost::shared_ptr<RouteList> r = routes.reader ();
330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
331 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
332 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
336 void
337 Session::when_engine_running ()
339 string first_physical_output;
341 BootMessage (_("Set block size and sample rate"));
343 set_block_size (_engine.frames_per_cycle());
344 set_frame_rate (_engine.frame_rate());
346 BootMessage (_("Using configuration"));
348 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
349 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
351 Config->map_parameters (ff);
352 config.map_parameters (ft);
354 /* every time we reconnect, recompute worst case output latencies */
356 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
358 if (synced_to_jack()) {
359 _engine.transport_stop ();
362 if (config.get_jack_time_master()) {
363 _engine.transport_locate (_transport_frame);
366 _clicking = false;
368 try {
369 XMLNode* child = 0;
371 _click_io.reset (new ClickIO (*this, "click"));
373 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
375 /* existing state for Click */
376 int c;
378 if (Stateful::loading_state_version < 3000) {
379 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
380 } else {
381 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
385 if (c == 0) {
386 _clicking = Config->get_clicking ();
388 } else {
390 error << _("could not setup Click I/O") << endmsg;
391 _clicking = false;
395 } else {
397 /* default state for Click: dual-mono to first 2 physical outputs */
399 for (int physport = 0; physport < 2; ++physport) {
400 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
402 if (physical_output.length()) {
403 if (_click_io->add_port (physical_output, this)) {
404 // relax, even though its an error
409 if (_click_io->n_ports () > ChanCount::ZERO) {
410 _clicking = Config->get_clicking ();
415 catch (failed_constructor& err) {
416 error << _("cannot setup Click I/O") << endmsg;
419 BootMessage (_("Compute I/O Latencies"));
421 set_worst_io_latencies ();
423 if (_clicking) {
424 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
427 BootMessage (_("Set up standard connections"));
429 /* Create a set of Bundle objects that map
430 to the physical I/O currently available. We create both
431 mono and stereo bundles, so that the common cases of mono
432 and stereo tracks get bundles to put in their mixer strip
433 in / out menus. There may be a nicer way of achieving that;
434 it doesn't really scale that well to higher channel counts
437 /* mono output bundles */
439 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
440 char buf[32];
441 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
443 shared_ptr<Bundle> c (new Bundle (buf, true));
444 c->add_channel (_("mono"));
445 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
447 add_bundle (c);
450 /* stereo output bundles */
452 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
453 if (np + 1 < n_physical_outputs) {
454 char buf[32];
455 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
456 shared_ptr<Bundle> c (new Bundle (buf, true));
457 c->add_channel (_("L"));
458 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
459 c->add_channel (_("R"));
460 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
462 add_bundle (c);
466 /* mono input bundles */
468 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
469 char buf[32];
470 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
472 shared_ptr<Bundle> c (new Bundle (buf, false));
473 c->add_channel (_("mono"));
474 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
476 add_bundle (c);
479 /* stereo input bundles */
481 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
482 if (np + 1 < n_physical_inputs) {
483 char buf[32];
484 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
486 shared_ptr<Bundle> c (new Bundle (buf, false));
487 c->add_channel (_("L"));
488 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
489 c->add_channel (_("R"));
490 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
492 add_bundle (c);
496 BootMessage (_("Setup signal flow and plugins"));
498 hookup_io ();
500 if (_is_new && !no_auto_connect()) {
502 /* don't connect the master bus outputs if there is a monitor bus */
504 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
506 /* if requested auto-connect the outputs to the first N physical ports.
509 uint32_t limit = _master_out->n_outputs().n_total();
511 for (uint32_t n = 0; n < limit; ++n) {
512 Port* p = _master_out->output()->nth (n);
513 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
515 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
516 if (_master_out->output()->connect (p, connect_to, this)) {
517 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
518 << endmsg;
519 break;
525 if (_monitor_out) {
527 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
528 are undefined, at best.
531 /* control out listens to master bus (but ignores it
532 under some conditions)
535 uint32_t limit = _monitor_out->n_inputs().n_audio();
537 if (_master_out) {
538 for (uint32_t n = 0; n < limit; ++n) {
539 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
540 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
542 if (o) {
543 string connect_to = o->name();
544 if (_monitor_out->input()->connect (p, connect_to, this)) {
545 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
546 << endmsg;
547 break;
553 /* if control out is not connected, connect control out to physical outs
556 if (!_monitor_out->output()->connected ()) {
558 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
560 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
562 if (b) {
563 _monitor_out->output()->connect_ports_to_bundle (b, this);
564 } else {
565 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
566 Config->get_monitor_bus_preferred_bundle())
567 << endmsg;
570 } else {
572 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
573 uint32_t mod = _engine.n_physical_outputs (*t);
574 uint32_t limit = _monitor_out->n_outputs().get(*t);
576 for (uint32_t n = 0; n < limit; ++n) {
578 Port* p = _monitor_out->output()->ports().port(*t, n);
579 string connect_to = _engine.get_nth_physical_output (*t, (n % mod));
581 if (!connect_to.empty()) {
582 if (_monitor_out->output()->connect (p, connect_to, this)) {
583 error << string_compose (
584 _("cannot connect control output %1 to %2"),
585 n, connect_to)
586 << endmsg;
587 break;
597 /* catch up on send+insert cnts */
599 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
601 /* hook us up to the engine */
603 BootMessage (_("Connect to engine"));
605 _engine.set_session (this);
608 void
609 Session::hookup_io ()
611 /* stop graph reordering notifications from
612 causing resorts, etc.
615 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
618 if (!auditioner) {
620 /* we delay creating the auditioner till now because
621 it makes its own connections to ports.
624 try {
625 Auditioner* a = new Auditioner (*this);
626 if (a->init()) {
627 delete a;
628 throw failed_constructor();
630 a->use_new_diskstream ();
631 auditioner.reset (a);
634 catch (failed_constructor& err) {
635 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
639 /* load bundles, which we may have postponed earlier on */
640 if (_bundle_xml_node) {
641 load_bundles (*_bundle_xml_node);
642 delete _bundle_xml_node;
645 /* Tell all IO objects to connect themselves together */
647 IO::enable_connecting ();
648 MIDI::JACK_MidiPort::MakeConnections ();
650 /* Now reset all panners */
652 Delivery::reset_panners ();
654 /* Connect tracks to monitor/listen bus if there is one.
655 Note that in an existing session, the internal sends will
656 already exist, but we want the routes to notice that
657 they connect to the control out specifically.
660 if (_monitor_out) {
661 boost::shared_ptr<RouteList> r = routes.reader ();
662 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
664 if ((*x)->is_monitor()) {
666 /* relax */
668 } else if ((*x)->is_master()) {
670 /* relax */
672 } else {
674 (*x)->listen_via (_monitor_out,
675 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
676 false, false);
681 /* Anyone who cares about input state, wake up and do something */
683 IOConnectionsComplete (); /* EMIT SIGNAL */
685 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
687 /* now handle the whole enchilada as if it was one
688 graph reorder event.
691 graph_reordered ();
693 /* update the full solo state, which can't be
694 correctly determined on a per-route basis, but
695 needs the global overview that only the session
696 has.
699 update_route_solo_state ();
702 void
703 Session::playlist_length_changed ()
705 update_session_range_location_marker ();
708 void
709 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
711 boost::shared_ptr<Track> track = wp.lock ();
712 if (!track) {
713 return;
716 boost::shared_ptr<Playlist> playlist;
718 if ((playlist = track->playlist()) != 0) {
719 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
722 update_session_range_location_marker ();
725 bool
726 Session::record_enabling_legal () const
728 /* this used to be in here, but survey says.... we don't need to restrict it */
729 // if (record_status() == Recording) {
730 // return false;
731 // }
733 if (Config->get_all_safe()) {
734 return false;
736 return true;
739 void
740 Session::reset_input_monitor_state ()
742 if (transport_rolling()) {
744 boost::shared_ptr<RouteList> rl = routes.reader ();
745 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
746 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
747 if (tr && tr->record_enabled ()) {
748 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
749 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
753 } else {
755 boost::shared_ptr<RouteList> rl = routes.reader ();
756 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
757 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
758 if (tr && tr->record_enabled ()) {
759 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
760 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
766 void
767 Session::auto_punch_start_changed (Location* location)
769 replace_event (SessionEvent::PunchIn, location->start());
771 if (get_record_enabled() && config.get_punch_in()) {
772 /* capture start has been changed, so save new pending state */
773 save_state ("", true);
777 void
778 Session::auto_punch_end_changed (Location* location)
780 nframes_t when_to_stop = location->end();
781 // when_to_stop += _worst_output_latency + _worst_input_latency;
782 replace_event (SessionEvent::PunchOut, when_to_stop);
785 void
786 Session::auto_punch_changed (Location* location)
788 nframes_t when_to_stop = location->end();
790 replace_event (SessionEvent::PunchIn, location->start());
791 //when_to_stop += _worst_output_latency + _worst_input_latency;
792 replace_event (SessionEvent::PunchOut, when_to_stop);
795 void
796 Session::auto_loop_changed (Location* location)
798 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
800 if (transport_rolling() && play_loop) {
803 // if (_transport_frame > location->end()) {
805 if (_transport_frame < location->start() || _transport_frame > location->end()) {
806 // relocate to beginning of loop
807 clear_events (SessionEvent::LocateRoll);
809 request_locate (location->start(), true);
812 else if (Config->get_seamless_loop() && !loop_changing) {
814 // schedule a locate-roll to refill the diskstreams at the
815 // previous loop end
816 loop_changing = true;
818 if (location->end() > last_loopend) {
819 clear_events (SessionEvent::LocateRoll);
820 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
821 queue_event (ev);
827 last_loopend = location->end();
830 void
831 Session::set_auto_punch_location (Location* location)
833 Location* existing;
835 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
836 punch_connections.drop_connections();
837 existing->set_auto_punch (false, this);
838 remove_event (existing->start(), SessionEvent::PunchIn);
839 clear_events (SessionEvent::PunchOut);
840 auto_punch_location_changed (0);
843 set_dirty();
845 if (location == 0) {
846 return;
849 if (location->end() <= location->start()) {
850 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
851 return;
854 punch_connections.drop_connections ();
856 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
857 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
858 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
860 location->set_auto_punch (true, this);
862 auto_punch_changed (location);
864 auto_punch_location_changed (location);
867 void
868 Session::set_auto_loop_location (Location* location)
870 Location* existing;
872 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
873 loop_connections.drop_connections ();
874 existing->set_auto_loop (false, this);
875 remove_event (existing->end(), SessionEvent::AutoLoop);
876 auto_loop_location_changed (0);
879 set_dirty();
881 if (location == 0) {
882 return;
885 if (location->end() <= location->start()) {
886 error << _("Session: you can't use a mark for auto loop") << endmsg;
887 return;
890 last_loopend = location->end();
892 loop_connections.drop_connections ();
894 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
895 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
896 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
898 location->set_auto_loop (true, this);
900 /* take care of our stuff first */
902 auto_loop_changed (location);
904 /* now tell everyone else */
906 auto_loop_location_changed (location);
909 void
910 Session::locations_added (Location *)
912 set_dirty ();
915 void
916 Session::locations_changed ()
918 _locations.apply (*this, &Session::handle_locations_changed);
921 void
922 Session::handle_locations_changed (Locations::LocationList& locations)
924 Locations::LocationList::iterator i;
925 Location* location;
926 bool set_loop = false;
927 bool set_punch = false;
929 for (i = locations.begin(); i != locations.end(); ++i) {
931 location =* i;
933 if (location->is_auto_punch()) {
934 set_auto_punch_location (location);
935 set_punch = true;
937 if (location->is_auto_loop()) {
938 set_auto_loop_location (location);
939 set_loop = true;
942 if (location->is_session_range()) {
943 _session_range_location = location;
947 if (!set_loop) {
948 set_auto_loop_location (0);
950 if (!set_punch) {
951 set_auto_punch_location (0);
954 set_dirty();
957 void
958 Session::enable_record ()
960 /* XXX really atomic compare+swap here */
961 if (g_atomic_int_get (&_record_status) != Recording) {
962 g_atomic_int_set (&_record_status, Recording);
963 _last_record_location = _transport_frame;
964 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
966 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
968 boost::shared_ptr<RouteList> rl = routes.reader ();
969 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
970 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
971 if (tr && tr->record_enabled ()) {
972 tr->monitor_input (true);
977 RecordStateChanged ();
981 void
982 Session::disable_record (bool rt_context, bool force)
984 RecordState rs;
986 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
988 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
989 g_atomic_int_set (&_record_status, Disabled);
990 } else {
991 if (rs == Recording) {
992 g_atomic_int_set (&_record_status, Enabled);
996 // FIXME: timestamp correct? [DR]
997 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
998 // does this /need/ to be sent in all cases?
999 if (rt_context) {
1000 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1003 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1005 boost::shared_ptr<RouteList> rl = routes.reader ();
1006 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1007 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1008 if (tr && tr->record_enabled ()) {
1009 tr->monitor_input (false);
1014 RecordStateChanged (); /* emit signal */
1016 if (!rt_context) {
1017 remove_pending_capture_state ();
1022 void
1023 Session::step_back_from_record ()
1025 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1027 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1028 boost::shared_ptr<RouteList> rl = routes.reader ();
1029 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1030 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1031 if (tr && tr->record_enabled ()) {
1032 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1033 tr->monitor_input (false);
1040 void
1041 Session::maybe_enable_record ()
1043 g_atomic_int_set (&_record_status, Enabled);
1045 /* this function is currently called from somewhere other than an RT thread.
1046 this save_state() call therefore doesn't impact anything.
1049 save_state ("", true);
1051 if (_transport_speed) {
1052 if (!config.get_punch_in()) {
1053 enable_record ();
1055 } else {
1056 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1057 RecordStateChanged (); /* EMIT SIGNAL */
1060 set_dirty();
1063 nframes64_t
1064 Session::audible_frame () const
1066 nframes64_t ret;
1067 nframes64_t tf;
1068 nframes_t offset;
1070 /* the first of these two possible settings for "offset"
1071 mean that the audible frame is stationary until
1072 audio emerges from the latency compensation
1073 "pseudo-pipeline".
1075 the second means that the audible frame is stationary
1076 until audio would emerge from a physical port
1077 in the absence of any plugin latency compensation
1080 offset = _worst_output_latency;
1082 if (offset > current_block_size) {
1083 offset -= current_block_size;
1084 } else {
1085 /* XXX is this correct? if we have no external
1086 physical connections and everything is internal
1087 then surely this is zero? still, how
1088 likely is that anyway?
1090 offset = current_block_size;
1093 if (synced_to_jack()) {
1094 tf = _engine.transport_frame();
1095 } else {
1096 tf = _transport_frame;
1099 ret = tf;
1101 if (!non_realtime_work_pending()) {
1103 /* MOVING */
1105 /* Check to see if we have passed the first guaranteed
1106 audible frame past our last start position. if not,
1107 return that last start point because in terms
1108 of audible frames, we have not moved yet.
1110 `Start position' in this context means the time we last
1111 either started or changed transport direction.
1114 if (_transport_speed > 0.0f) {
1116 if (!play_loop || !have_looped) {
1117 if (tf < _last_roll_or_reversal_location + offset) {
1118 return _last_roll_or_reversal_location;
1123 /* forwards */
1124 ret -= offset;
1126 } else if (_transport_speed < 0.0f) {
1128 /* XXX wot? no backward looping? */
1130 if (tf > _last_roll_or_reversal_location - offset) {
1131 return _last_roll_or_reversal_location;
1132 } else {
1133 /* backwards */
1134 ret += offset;
1139 return ret;
1142 void
1143 Session::set_frame_rate (nframes_t frames_per_second)
1145 /** \fn void Session::set_frame_size(nframes_t)
1146 the AudioEngine object that calls this guarantees
1147 that it will not be called while we are also in
1148 ::process(). Its fine to do things that block
1149 here.
1152 _base_frame_rate = frames_per_second;
1154 sync_time_vars();
1156 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1158 clear_clicks ();
1160 // XXX we need some equivalent to this, somehow
1161 // SndFileSource::setup_standard_crossfades (frames_per_second);
1163 set_dirty();
1165 /* XXX need to reset/reinstantiate all LADSPA plugins */
1168 void
1169 Session::set_block_size (nframes_t nframes)
1171 /* the AudioEngine guarantees
1172 that it will not be called while we are also in
1173 ::process(). It is therefore fine to do things that block
1174 here.
1178 current_block_size = nframes;
1180 ensure_buffers ();
1182 boost::shared_ptr<RouteList> r = routes.reader ();
1184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1185 (*i)->set_block_size (nframes);
1188 boost::shared_ptr<RouteList> rl = routes.reader ();
1189 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1190 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1191 if (tr) {
1192 tr->set_block_size (nframes);
1196 set_worst_io_latencies ();
1200 void
1201 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1203 #if 0
1204 nframes_t fade_frames;
1206 /* Don't allow fade of less 1 frame */
1208 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1210 fade_msecs = 0;
1211 fade_frames = 0;
1213 } else {
1215 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1219 default_fade_msecs = fade_msecs;
1220 default_fade_steepness = steepness;
1223 // jlc, WTF is this!
1224 Glib::RWLock::ReaderLock lm (route_lock);
1225 AudioRegion::set_default_fade (steepness, fade_frames);
1228 set_dirty();
1230 /* XXX have to do this at some point */
1231 /* foreach region using default fade, reset, then
1232 refill_all_diskstream_buffers ();
1234 #endif
1237 struct RouteSorter {
1238 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1239 if (r2->feeds (r1)) {
1240 return false;
1241 } else if (r1->feeds (r2)) {
1242 return true;
1243 } else {
1244 if (r1->not_fed ()) {
1245 if (r2->not_fed ()) {
1246 /* no ardour-based connections inbound to either route. just use signal order */
1247 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1248 } else {
1249 /* r2 has connections, r1 does not; run r1 early */
1250 return true;
1252 } else {
1253 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1259 static void
1260 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1262 shared_ptr<Route> r2;
1264 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1265 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1266 return;
1269 /* make a copy of the existing list of routes that feed r1 */
1271 Route::FedBy existing (r1->fed_by());
1273 /* for each route that feeds r1, recurse, marking it as feeding
1274 rbase as well.
1277 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1278 if (!(r2 = i->r.lock ())) {
1279 /* (*i) went away, ignore it */
1280 continue;
1283 /* r2 is a route that feeds r1 which somehow feeds base. mark
1284 base as being fed by r2
1287 rbase->add_fed_by (r2, i->sends_only);
1289 if (r2 != rbase) {
1291 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1292 stop here.
1295 if (r1->feeds (r2) && r2->feeds (r1)) {
1296 continue;
1299 /* now recurse, so that we can mark base as being fed by
1300 all routes that feed r2
1303 trace_terminal (r2, rbase);
1309 void
1310 Session::resort_routes ()
1312 /* don't do anything here with signals emitted
1313 by Routes while we are being destroyed.
1316 if (_state_of_the_state & Deletion) {
1317 return;
1321 RCUWriter<RouteList> writer (routes);
1322 shared_ptr<RouteList> r = writer.get_copy ();
1323 resort_routes_using (r);
1324 /* writer goes out of scope and forces update */
1327 //route_graph->dump(1);
1329 #ifndef NDEBUG
1330 boost::shared_ptr<RouteList> rl = routes.reader ();
1331 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1332 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1334 const Route::FedBy& fb ((*i)->fed_by());
1336 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1337 boost::shared_ptr<Route> sf = f->r.lock();
1338 if (sf) {
1339 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1343 #endif
1346 void
1347 Session::resort_routes_using (shared_ptr<RouteList> r)
1349 RouteList::iterator i, j;
1351 for (i = r->begin(); i != r->end(); ++i) {
1353 (*i)->clear_fed_by ();
1355 for (j = r->begin(); j != r->end(); ++j) {
1357 /* although routes can feed themselves, it will
1358 cause an endless recursive descent if we
1359 detect it. so don't bother checking for
1360 self-feeding.
1363 if (*j == *i) {
1364 continue;
1367 bool via_sends_only;
1369 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1370 (*i)->add_fed_by (*j, via_sends_only);
1375 for (i = r->begin(); i != r->end(); ++i) {
1376 trace_terminal (*i, *i);
1379 RouteSorter cmp;
1380 r->sort (cmp);
1382 route_graph->rechain (r);
1384 #ifndef NDEBUG
1385 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1386 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1387 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1388 (*i)->name(), (*i)->order_key ("signal")));
1390 #endif
1394 /** Find the route name starting with \a base with the lowest \a id.
1396 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1397 * The available route name with the lowest ID will be used, and \a id
1398 * will be set to the ID.
1400 * \return false if a route name could not be found, and \a track_name
1401 * and \a id do not reflect a free route name.
1403 bool
1404 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1406 do {
1407 snprintf (name, name_len, "%s %" PRIu32, base, id);
1409 if (route_by_name (name) == 0) {
1410 return true;
1413 ++id;
1415 } while (id < (UINT_MAX-1));
1417 return false;
1420 void
1421 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1423 in = ChanCount::ZERO;
1424 out = ChanCount::ZERO;
1425 shared_ptr<RouteList> r = routes.reader ();
1426 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1427 if (!(*i)->is_hidden()) {
1428 in += (*i)->n_inputs();
1429 out += (*i)->n_outputs();
1434 list<boost::shared_ptr<MidiTrack> >
1435 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1437 char track_name[32];
1438 uint32_t track_id = 0;
1439 ChanCount existing_inputs;
1440 ChanCount existing_outputs;
1441 string port;
1442 RouteList new_routes;
1443 list<boost::shared_ptr<MidiTrack> > ret;
1444 uint32_t control_id;
1446 count_existing_route_channels (existing_inputs, existing_outputs);
1448 control_id = ntracks() + nbusses();
1450 while (how_many) {
1451 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1452 error << "cannot find name for new midi track" << endmsg;
1453 goto failed;
1456 shared_ptr<MidiTrack> track;
1458 try {
1459 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1461 if (mt->init ()) {
1462 delete mt;
1463 goto failed;
1466 mt->use_new_diskstream();
1468 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1469 track = boost::shared_ptr<MidiTrack>(mt);
1471 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1472 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1473 goto failed;
1477 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1478 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1479 goto failed;
1482 auto_connect_route (track, existing_inputs, existing_outputs);
1484 track->non_realtime_input_change();
1486 if (route_group) {
1487 route_group->add (track);
1490 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1491 track->set_remote_control_id (control_id);
1493 new_routes.push_back (track);
1494 ret.push_back (track);
1497 catch (failed_constructor &err) {
1498 error << _("Session: could not create new midi track.") << endmsg;
1499 goto failed;
1502 catch (AudioEngine::PortRegistrationFailure& pfe) {
1504 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;
1505 goto failed;
1508 --how_many;
1511 failed:
1512 if (!new_routes.empty()) {
1513 add_routes (new_routes, false);
1514 save_state (_current_snapshot_name);
1517 return ret;
1520 void
1521 Session::auto_connect_route (boost::shared_ptr<Route> route,
1522 ChanCount& existing_inputs, ChanCount& existing_outputs)
1524 /* If both inputs and outputs are auto-connected to physical ports,
1525 use the max of input and output offsets to ensure auto-connected
1526 port numbers always match up (e.g. the first audio input and the
1527 first audio output of the route will have the same physical
1528 port number). Otherwise just use the lowest input or output
1529 offset possible.
1531 const bool in_out_physical =
1532 (Config->get_input_auto_connect() & AutoConnectPhysical)
1533 && (Config->get_output_auto_connect() & AutoConnectPhysical);
1535 const ChanCount in_offset = in_out_physical
1536 ? ChanCount::max(existing_inputs, existing_outputs)
1537 : existing_inputs;
1539 const ChanCount out_offset = in_out_physical
1540 ? ChanCount::max(existing_inputs, existing_outputs)
1541 : existing_outputs;
1543 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1544 vector<string> physinputs;
1545 vector<string> physoutputs;
1547 _engine.get_physical_outputs (*t, physoutputs);
1548 _engine.get_physical_inputs (*t, physinputs);
1550 if (!physinputs.empty()) {
1551 uint32_t nphysical_in = physinputs.size();
1552 for (uint32_t i = 0; i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1553 string port;
1555 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1556 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1559 if (!port.empty() && route->input()->connect (
1560 route->input()->ports().port(*t, i), port, this)) {
1561 break;
1566 if (!physoutputs.empty()) {
1567 uint32_t nphysical_out = physoutputs.size();
1568 for (uint32_t i = 0; i < route->n_outputs().get(*t); ++i) {
1569 string port;
1571 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1572 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1573 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1574 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1575 port = _master_out->input()->ports().port(*t,
1576 i % _master_out->input()->n_ports().get(*t))->name();
1580 if (!port.empty() && route->output()->connect (
1581 route->output()->ports().port(*t, i), port, this)) {
1582 break;
1588 existing_inputs += route->n_inputs();
1589 existing_outputs += route->n_outputs();
1592 list< boost::shared_ptr<AudioTrack> >
1593 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1595 char track_name[32];
1596 uint32_t track_id = 0;
1597 ChanCount existing_inputs;
1598 ChanCount existing_outputs;
1599 string port;
1600 RouteList new_routes;
1601 list<boost::shared_ptr<AudioTrack> > ret;
1602 uint32_t control_id;
1604 count_existing_route_channels (existing_inputs, existing_outputs);
1606 control_id = ntracks() + nbusses() + 1;
1608 while (how_many) {
1609 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1610 error << "cannot find name for new audio track" << endmsg;
1611 goto failed;
1614 shared_ptr<AudioTrack> track;
1616 try {
1617 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1619 if (at->init ()) {
1620 delete at;
1621 goto failed;
1624 at->use_new_diskstream();
1626 boost_debug_shared_ptr_mark_interesting (at, "Track");
1627 track = boost::shared_ptr<AudioTrack>(at);
1629 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1630 error << string_compose (
1631 _("cannot configure %1 in/%2 out configuration for new audio track"),
1632 input_channels, output_channels)
1633 << endmsg;
1634 goto failed;
1637 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1638 error << string_compose (
1639 _("cannot configure %1 in/%2 out configuration for new audio track"),
1640 input_channels, output_channels)
1641 << endmsg;
1642 goto failed;
1645 auto_connect_route (track, existing_inputs, existing_outputs);
1647 if (route_group) {
1648 route_group->add (track);
1651 track->non_realtime_input_change();
1653 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1654 track->set_remote_control_id (control_id);
1655 ++control_id;
1657 new_routes.push_back (track);
1658 ret.push_back (track);
1661 catch (failed_constructor &err) {
1662 error << _("Session: could not create new audio track.") << endmsg;
1663 goto failed;
1666 catch (AudioEngine::PortRegistrationFailure& pfe) {
1668 error << pfe.what() << endmsg;
1669 goto failed;
1672 --how_many;
1675 failed:
1676 if (!new_routes.empty()) {
1677 add_routes (new_routes, true);
1680 return ret;
1683 void
1684 Session::set_remote_control_ids ()
1686 RemoteModel m = Config->get_remote_model();
1687 bool emit_signal = false;
1689 shared_ptr<RouteList> r = routes.reader ();
1691 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1692 if (MixerOrdered == m) {
1693 long order = (*i)->order_key(N_("signal"));
1694 (*i)->set_remote_control_id (order+1, false);
1695 emit_signal = true;
1696 } else if (EditorOrdered == m) {
1697 long order = (*i)->order_key(N_("editor"));
1698 (*i)->set_remote_control_id (order+1, false);
1699 emit_signal = true;
1700 } else if (UserOrdered == m) {
1701 //do nothing ... only changes to remote id's are initiated by user
1705 if (emit_signal) {
1706 Route::RemoteControlIDChange();
1711 RouteList
1712 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1714 char bus_name[32];
1715 uint32_t bus_id = 0;
1716 ChanCount existing_inputs;
1717 ChanCount existing_outputs;
1718 string port;
1719 RouteList ret;
1720 uint32_t control_id;
1722 count_existing_route_channels (existing_inputs, existing_outputs);
1724 control_id = ntracks() + nbusses() + 1;
1726 while (how_many) {
1727 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1728 error << "cannot find name for new audio bus" << endmsg;
1729 goto failure;
1732 try {
1733 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1735 if (rt->init ()) {
1736 delete rt;
1737 goto failure;
1740 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1741 shared_ptr<Route> bus (rt);
1743 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1744 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1745 input_channels, output_channels)
1746 << endmsg;
1747 goto failure;
1751 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1752 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1753 input_channels, output_channels)
1754 << endmsg;
1755 goto failure;
1758 auto_connect_route (bus, existing_inputs, existing_outputs);
1760 if (route_group) {
1761 route_group->add (bus);
1763 bus->set_remote_control_id (control_id);
1764 ++control_id;
1766 if (aux) {
1767 bus->add_internal_return ();
1770 ret.push_back (bus);
1774 catch (failed_constructor &err) {
1775 error << _("Session: could not create new audio route.") << endmsg;
1776 goto failure;
1779 catch (AudioEngine::PortRegistrationFailure& pfe) {
1780 error << pfe.what() << endmsg;
1781 goto failure;
1785 --how_many;
1788 failure:
1789 if (!ret.empty()) {
1790 add_routes (ret, true);
1793 return ret;
1797 RouteList
1798 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1800 char name[32];
1801 RouteList ret;
1802 uint32_t control_id;
1803 XMLTree tree;
1804 uint32_t number = 0;
1806 if (!tree.read (template_path.c_str())) {
1807 return ret;
1810 XMLNode* node = tree.root();
1812 control_id = ntracks() + nbusses() + 1;
1814 while (how_many) {
1816 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1818 std::string node_name = IO::name_from_state (*node_copy.children().front());
1820 /* generate a new name by adding a number to the end of the template name */
1821 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1822 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1823 /*NOTREACHED*/
1826 /* set IO children to use the new name */
1827 XMLNodeList const & children = node_copy.children ();
1828 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1829 if ((*i)->name() == IO::state_node_name) {
1830 IO::set_name_in_state (**i, name);
1834 Track::zero_diskstream_id_in_xml (node_copy);
1836 try {
1837 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1839 if (route == 0) {
1840 error << _("Session: cannot create track/bus from template description") << endmsg;
1841 goto out;
1844 if (boost::dynamic_pointer_cast<Track>(route)) {
1845 /* force input/output change signals so that the new diskstream
1846 picks up the configuration of the route. During session
1847 loading this normally happens in a different way.
1849 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
1850 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
1853 route->set_remote_control_id (control_id);
1854 ++control_id;
1856 ret.push_back (route);
1859 catch (failed_constructor &err) {
1860 error << _("Session: could not create new route from template") << endmsg;
1861 goto out;
1864 catch (AudioEngine::PortRegistrationFailure& pfe) {
1865 error << pfe.what() << endmsg;
1866 goto out;
1869 --how_many;
1872 out:
1873 if (!ret.empty()) {
1874 add_routes (ret, true);
1877 return ret;
1880 void
1881 Session::add_routes (RouteList& new_routes, bool save)
1884 RCUWriter<RouteList> writer (routes);
1885 shared_ptr<RouteList> r = writer.get_copy ();
1886 r->insert (r->end(), new_routes.begin(), new_routes.end());
1889 /* if there is no control out and we're not in the middle of loading,
1890 resort the graph here. if there is a control out, we will resort
1891 toward the end of this method. if we are in the middle of loading,
1892 we will resort when done.
1895 if (!_monitor_out && IO::connecting_legal) {
1896 resort_routes_using (r);
1900 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1902 boost::weak_ptr<Route> wpr (*x);
1903 boost::shared_ptr<Route> r (*x);
1905 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1906 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1907 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1908 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1909 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1910 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1911 r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
1913 if (r->is_master()) {
1914 _master_out = r;
1917 if (r->is_monitor()) {
1918 _monitor_out = r;
1921 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1922 if (tr) {
1923 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1924 track_playlist_changed (boost::weak_ptr<Track> (tr));
1925 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1929 if (_monitor_out && IO::connecting_legal) {
1931 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1932 if ((*x)->is_monitor()) {
1933 /* relax */
1934 } else if ((*x)->is_master()) {
1935 /* relax */
1936 } else {
1937 (*x)->listen_via (_monitor_out,
1938 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
1939 false, false);
1943 resort_routes ();
1946 set_dirty();
1948 if (save) {
1949 save_state (_current_snapshot_name);
1952 RouteAdded (new_routes); /* EMIT SIGNAL */
1953 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
1956 void
1957 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
1959 boost::shared_ptr<RouteList> r = routes.reader ();
1960 boost::shared_ptr<Send> s;
1962 /* only tracks */
1964 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1965 if (boost::dynamic_pointer_cast<Track>(*i)) {
1966 if ((s = (*i)->internal_send_for (dest)) != 0) {
1967 s->amp()->gain_control()->set_value (0.0);
1973 void
1974 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
1976 boost::shared_ptr<RouteList> r = routes.reader ();
1977 boost::shared_ptr<Send> s;
1979 /* only tracks */
1981 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1982 if (boost::dynamic_pointer_cast<Track>(*i)) {
1983 if ((s = (*i)->internal_send_for (dest)) != 0) {
1984 s->amp()->gain_control()->set_value (1.0);
1990 void
1991 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
1993 boost::shared_ptr<RouteList> r = routes.reader ();
1994 boost::shared_ptr<Send> s;
1996 /* only tracks */
1998 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1999 if (boost::dynamic_pointer_cast<Track>(*i)) {
2000 if ((s = (*i)->internal_send_for (dest)) != 0) {
2001 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2007 void
2008 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2010 boost::shared_ptr<RouteList> r = routes.reader ();
2011 boost::shared_ptr<RouteList> t (new RouteList);
2013 /* only send tracks */
2015 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2016 if (boost::dynamic_pointer_cast<Track>(*i)) {
2017 t->push_back (*i);
2021 add_internal_sends (dest, p, t);
2024 void
2025 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2027 if (dest->is_monitor() || dest->is_master()) {
2028 return;
2031 if (!dest->internal_return()) {
2032 dest->add_internal_return();
2035 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2037 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2038 continue;
2041 (*i)->listen_via (dest, p, true, true);
2044 graph_reordered ();
2047 void
2048 Session::remove_route (shared_ptr<Route> route)
2050 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2051 return;
2055 RCUWriter<RouteList> writer (routes);
2056 shared_ptr<RouteList> rs = writer.get_copy ();
2058 rs->remove (route);
2060 /* deleting the master out seems like a dumb
2061 idea, but its more of a UI policy issue
2062 than our concern.
2065 if (route == _master_out) {
2066 _master_out = shared_ptr<Route> ();
2069 if (route == _monitor_out) {
2071 /* cancel control outs for all routes */
2073 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2074 (*r)->drop_listen (_monitor_out);
2077 _monitor_out.reset ();
2080 /* writer goes out of scope, forces route list update */
2083 update_route_solo_state ();
2084 update_session_range_location_marker ();
2086 // We need to disconnect the route's inputs and outputs
2088 route->input()->disconnect (0);
2089 route->output()->disconnect (0);
2091 /* if the route had internal sends sending to it, remove them */
2092 if (route->internal_return()) {
2094 boost::shared_ptr<RouteList> r = routes.reader ();
2095 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2096 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2097 if (s) {
2098 (*i)->remove_processor (s);
2103 update_latency_compensation (false, false);
2104 set_dirty();
2106 /* flush references out of the graph
2109 route_graph->clear_other_chain ();
2111 /* get rid of it from the dead wood collection in the route list manager */
2113 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2115 routes.flush ();
2117 /* try to cause everyone to drop their references */
2119 route->drop_references ();
2121 sync_order_keys (N_("session"));
2123 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2125 /* save the new state of the world */
2127 if (save_state (_current_snapshot_name)) {
2128 save_history (_current_snapshot_name);
2132 void
2133 Session::route_mute_changed (void* /*src*/)
2135 set_dirty ();
2138 void
2139 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2141 boost::shared_ptr<Route> route = wpr.lock();
2142 if (!route) {
2143 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2144 return;
2147 if (route->listening()) {
2149 if (Config->get_exclusive_solo()) {
2150 /* new listen: disable all other listen */
2151 shared_ptr<RouteList> r = routes.reader ();
2152 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2153 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2154 continue;
2156 (*i)->set_listen (false, this);
2160 _listen_cnt++;
2162 } else if (_listen_cnt > 0) {
2164 _listen_cnt--;
2167 void
2168 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2170 boost::shared_ptr<Route> route = wpr.lock ();
2172 if (!route) {
2173 /* should not happen */
2174 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2175 return;
2178 bool send_changed = false;
2180 if (route->solo_isolated()) {
2181 if (_solo_isolated_cnt == 0) {
2182 send_changed = true;
2184 _solo_isolated_cnt++;
2185 } else if (_solo_isolated_cnt > 0) {
2186 _solo_isolated_cnt--;
2187 if (_solo_isolated_cnt == 0) {
2188 send_changed = true;
2192 if (send_changed) {
2193 IsolatedChanged (); /* EMIT SIGNAL */
2197 void
2198 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2200 if (!self_solo_change) {
2201 // session doesn't care about changes to soloed-by-others
2202 return;
2205 if (solo_update_disabled) {
2206 // We know already
2207 return;
2210 boost::shared_ptr<Route> route = wpr.lock ();
2212 if (!route) {
2213 /* should not happen */
2214 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2215 return;
2218 shared_ptr<RouteList> r = routes.reader ();
2219 int32_t delta;
2221 if (route->self_soloed()) {
2222 delta = 1;
2223 } else {
2224 delta = -1;
2227 if (delta == 1 && Config->get_exclusive_solo()) {
2228 /* new solo: disable all other solos */
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2231 continue;
2233 (*i)->set_solo (false, this);
2237 solo_update_disabled = true;
2239 RouteList uninvolved;
2241 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2242 bool via_sends_only;
2243 bool in_signal_flow;
2245 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2246 continue;
2249 in_signal_flow = false;
2251 if ((*i)->feeds (route, &via_sends_only)) {
2252 if (!via_sends_only) {
2253 if (!route->soloed_by_others_upstream()) {
2254 (*i)->mod_solo_by_others_downstream (delta);
2256 in_signal_flow = true;
2260 if (route->feeds (*i, &via_sends_only)) {
2261 (*i)->mod_solo_by_others_upstream (delta);
2262 in_signal_flow = true;
2265 if (!in_signal_flow) {
2266 uninvolved.push_back (*i);
2270 solo_update_disabled = false;
2271 update_route_solo_state (r);
2273 /* now notify that the mute state of the routes not involved in the signal
2274 pathway of the just-solo-changed route may have altered.
2277 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2278 (*i)->mute_changed (this);
2281 SoloChanged (); /* EMIT SIGNAL */
2282 set_dirty();
2285 void
2286 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2288 /* now figure out if anything that matters is soloed (or is "listening")*/
2290 bool something_soloed = false;
2291 uint32_t listeners = 0;
2292 uint32_t isolated = 0;
2294 if (!r) {
2295 r = routes.reader();
2298 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2299 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2300 something_soloed = true;
2303 if (!(*i)->is_hidden() && (*i)->listening()) {
2304 if (Config->get_solo_control_is_listen_control()) {
2305 listeners++;
2306 } else {
2307 (*i)->set_listen (false, this);
2311 if ((*i)->solo_isolated()) {
2312 isolated++;
2316 if (something_soloed != _non_soloed_outs_muted) {
2317 _non_soloed_outs_muted = something_soloed;
2318 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2321 _listen_cnt = listeners;
2323 if (isolated != _solo_isolated_cnt) {
2324 _solo_isolated_cnt = isolated;
2325 IsolatedChanged (); /* EMIT SIGNAL */
2329 boost::shared_ptr<RouteList>
2330 Session::get_routes_with_internal_returns() const
2332 shared_ptr<RouteList> r = routes.reader ();
2333 boost::shared_ptr<RouteList> rl (new RouteList);
2335 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2336 if ((*i)->internal_return ()) {
2337 rl->push_back (*i);
2340 return rl;
2343 bool
2344 Session::io_name_is_legal (const std::string& name)
2346 shared_ptr<RouteList> r = routes.reader ();
2348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2349 if ((*i)->name() == name) {
2350 return false;
2353 if ((*i)->has_io_processor_named (name)) {
2354 return false;
2358 return true;
2361 shared_ptr<Route>
2362 Session::route_by_name (string name)
2364 shared_ptr<RouteList> r = routes.reader ();
2366 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2367 if ((*i)->name() == name) {
2368 return *i;
2372 return shared_ptr<Route> ((Route*) 0);
2375 shared_ptr<Route>
2376 Session::route_by_id (PBD::ID id)
2378 shared_ptr<RouteList> r = routes.reader ();
2380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2381 if ((*i)->id() == id) {
2382 return *i;
2386 return shared_ptr<Route> ((Route*) 0);
2389 shared_ptr<Route>
2390 Session::route_by_remote_id (uint32_t id)
2392 shared_ptr<RouteList> r = routes.reader ();
2394 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2395 if ((*i)->remote_control_id() == id) {
2396 return *i;
2400 return shared_ptr<Route> ((Route*) 0);
2403 /** If either end of the session range location marker lies inside the current
2404 * session extent, move it to the corresponding session extent.
2406 void
2407 Session::update_session_range_location_marker ()
2409 if (_state_of_the_state & Loading) {
2410 return;
2413 pair<nframes_t, nframes_t> const ext = get_extent ();
2415 if (_session_range_location == 0) {
2416 /* we don't have a session range yet; use this one (provided it is valid) */
2417 if (ext.first != max_frames) {
2418 add_session_range_location (ext.first, ext.second);
2420 } else {
2421 /* update the existing session range */
2422 if (ext.first < _session_range_location->start()) {
2423 _session_range_location->set_start (ext.first);
2424 set_dirty ();
2427 if (ext.second > _session_range_location->end()) {
2428 _session_range_location->set_end (ext.second);
2429 set_dirty ();
2435 /** @return Extent of the session's contents; if the session is empty, the first value of
2436 * the pair will equal max_frames.
2438 pair<nframes_t, nframes_t>
2439 Session::get_extent () const
2441 pair<nframes_t, nframes_t> ext (max_frames, 0);
2443 boost::shared_ptr<RouteList> rl = routes.reader ();
2444 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2445 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2446 if (!tr || tr->destructive()) {
2447 // ignore tape tracks when getting extents
2448 continue;
2451 pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
2452 if (e.first < ext.first) {
2453 ext.first = e.first;
2455 if (e.second > ext.second) {
2456 ext.second = e.second;
2460 return ext;
2463 /* Region management */
2465 boost::shared_ptr<Region>
2466 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2468 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2469 RegionFactory::RegionMap::const_iterator i;
2470 boost::shared_ptr<Region> region;
2472 Glib::Mutex::Lock lm (region_lock);
2474 for (i = regions.begin(); i != regions.end(); ++i) {
2476 region = i->second;
2478 if (region->whole_file()) {
2480 if (child->source_equivalent (region)) {
2481 return region;
2486 return boost::shared_ptr<Region> ();
2490 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2492 set<boost::shared_ptr<Region> > relevant_regions;
2494 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2495 RegionFactory::get_regions_using_source (*s, relevant_regions);
2498 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2500 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2501 set<boost::shared_ptr<Region> >::iterator tmp;
2503 tmp = r;
2504 ++tmp;
2506 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2508 playlists->destroy_region (*r);
2509 RegionFactory::map_remove (*r);
2511 (*r)->drop_sources ();
2512 (*r)->drop_references ();
2514 cerr << "\tdone UC = " << (*r).use_count() << endl;
2516 relevant_regions.erase (r);
2518 r = tmp;
2521 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2524 Glib::Mutex::Lock ls (source_lock);
2525 /* remove from the main source list */
2526 sources.erase ((*s)->id());
2529 (*s)->mark_for_remove ();
2530 (*s)->drop_references ();
2532 s = srcs.erase (s);
2535 return 0;
2539 Session::remove_last_capture ()
2541 list<boost::shared_ptr<Source> > srcs;
2543 boost::shared_ptr<RouteList> rl = routes.reader ();
2544 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2545 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2546 if (!tr) {
2547 continue;
2550 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2552 if (!l.empty()) {
2553 srcs.insert (srcs.end(), l.begin(), l.end());
2554 l.clear ();
2558 destroy_sources (srcs);
2560 save_state (_current_snapshot_name);
2562 return 0;
2565 /* Source Management */
2567 void
2568 Session::add_source (boost::shared_ptr<Source> source)
2570 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2571 pair<SourceMap::iterator,bool> result;
2573 entry.first = source->id();
2574 entry.second = source;
2577 Glib::Mutex::Lock lm (source_lock);
2578 result = sources.insert (entry);
2581 if (result.second) {
2583 /* yay, new source */
2585 set_dirty();
2587 boost::shared_ptr<AudioFileSource> afs;
2589 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2590 if (Config->get_auto_analyse_audio()) {
2591 Analyser::queue_source_for_analysis (source, false);
2597 void
2598 Session::remove_source (boost::weak_ptr<Source> src)
2600 SourceMap::iterator i;
2601 boost::shared_ptr<Source> source = src.lock();
2603 if (!source) {
2604 return;
2608 Glib::Mutex::Lock lm (source_lock);
2610 if ((i = sources.find (source->id())) != sources.end()) {
2611 sources.erase (i);
2615 if (!_state_of_the_state & InCleanup) {
2617 /* save state so we don't end up with a session file
2618 referring to non-existent sources.
2621 save_state (_current_snapshot_name);
2625 boost::shared_ptr<Source>
2626 Session::source_by_id (const PBD::ID& id)
2628 Glib::Mutex::Lock lm (source_lock);
2629 SourceMap::iterator i;
2630 boost::shared_ptr<Source> source;
2632 if ((i = sources.find (id)) != sources.end()) {
2633 source = i->second;
2636 return source;
2639 boost::shared_ptr<Source>
2640 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2642 Glib::Mutex::Lock lm (source_lock);
2644 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2645 cerr << "comparing " << path << " with " << i->second->name() << endl;
2646 boost::shared_ptr<AudioFileSource> afs
2647 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2649 if (afs && afs->path() == path && chn == afs->channel()) {
2650 return afs;
2653 return boost::shared_ptr<Source>();
2657 string
2658 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2660 string look_for;
2661 string old_basename = PBD::basename_nosuffix (oldname);
2662 string new_legalized = legalize_for_path (newname);
2664 /* note: we know (or assume) the old path is already valid */
2666 if (destructive) {
2668 /* destructive file sources have a name of the form:
2670 /path/to/Tnnnn-NAME(%[LR])?.wav
2672 the task here is to replace NAME with the new name.
2675 /* find last slash */
2677 string dir;
2678 string prefix;
2679 string::size_type slash;
2680 string::size_type dash;
2682 if ((slash = path.find_last_of ('/')) == string::npos) {
2683 return "";
2686 dir = path.substr (0, slash+1);
2688 /* '-' is not a legal character for the NAME part of the path */
2690 if ((dash = path.find_last_of ('-')) == string::npos) {
2691 return "";
2694 prefix = path.substr (slash+1, dash-(slash+1));
2696 path = dir;
2697 path += prefix;
2698 path += '-';
2699 path += new_legalized;
2700 path += ".wav"; /* XXX gag me with a spoon */
2702 } else {
2704 /* non-destructive file sources have a name of the form:
2706 /path/to/NAME-nnnnn(%[LR])?.ext
2708 the task here is to replace NAME with the new name.
2711 string dir;
2712 string suffix;
2713 string::size_type slash;
2714 string::size_type dash;
2715 string::size_type postfix;
2717 /* find last slash */
2719 if ((slash = path.find_last_of ('/')) == string::npos) {
2720 return "";
2723 dir = path.substr (0, slash+1);
2725 /* '-' is not a legal character for the NAME part of the path */
2727 if ((dash = path.find_last_of ('-')) == string::npos) {
2728 return "";
2731 suffix = path.substr (dash+1);
2733 // Suffix is now everything after the dash. Now we need to eliminate
2734 // the nnnnn part, which is done by either finding a '%' or a '.'
2736 postfix = suffix.find_last_of ("%");
2737 if (postfix == string::npos) {
2738 postfix = suffix.find_last_of ('.');
2741 if (postfix != string::npos) {
2742 suffix = suffix.substr (postfix);
2743 } else {
2744 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2745 return "";
2748 const uint32_t limit = 10000;
2749 char buf[PATH_MAX+1];
2751 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2753 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2755 if (access (buf, F_OK) != 0) {
2756 path = buf;
2757 break;
2759 path = "";
2762 if (path == "") {
2763 error << "FATAL ERROR! Could not find a " << endl;
2768 return path;
2771 /** Return the full path (in some session directory) for a new within-session source.
2772 * \a name must be a session-unique name that does not contain slashes
2773 * (e.g. as returned by new_*_source_name)
2775 string
2776 Session::new_source_path_from_name (DataType type, const string& name)
2778 assert(name.find("/") == string::npos);
2780 SessionDirectory sdir(get_best_session_directory_for_new_source());
2782 sys::path p;
2783 if (type == DataType::AUDIO) {
2784 p = sdir.sound_path();
2785 } else if (type == DataType::MIDI) {
2786 p = sdir.midi_path();
2787 } else {
2788 error << "Unknown source type, unable to create file path" << endmsg;
2789 return "";
2792 p /= name;
2793 return p.to_string();
2796 Glib::ustring
2797 Session::peak_path (Glib::ustring base) const
2799 sys::path peakfile_path(_session_dir->peak_path());
2800 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2801 return peakfile_path.to_string();
2804 /** Return a unique name based on \a base for a new internal audio source */
2805 string
2806 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2808 string spath;
2809 uint32_t cnt;
2810 char buf[PATH_MAX+1];
2811 const uint32_t limit = 10000;
2812 string legalized;
2814 buf[0] = '\0';
2815 legalized = legalize_for_path (base);
2817 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2818 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2820 vector<space_and_path>::iterator i;
2821 uint32_t existing = 0;
2823 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2825 SessionDirectory sdir((*i).path);
2827 spath = sdir.sound_path().to_string();
2829 if (destructive) {
2831 if (nchan < 2) {
2832 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
2833 spath.c_str(), cnt, legalized.c_str());
2834 } else if (nchan == 2) {
2835 if (chan == 0) {
2836 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
2837 spath.c_str(), cnt, legalized.c_str());
2838 } else {
2839 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
2840 spath.c_str(), cnt, legalized.c_str());
2842 } else if (nchan < 26) {
2843 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
2844 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2845 } else {
2846 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
2847 spath.c_str(), cnt, legalized.c_str());
2850 } else {
2852 spath += '/';
2853 spath += legalized;
2855 if (nchan < 2) {
2856 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2857 } else if (nchan == 2) {
2858 if (chan == 0) {
2859 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2860 } else {
2861 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2863 } else if (nchan < 26) {
2864 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2865 } else {
2866 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2870 if (sys::exists(buf)) {
2871 existing++;
2876 if (existing == 0) {
2877 break;
2880 if (cnt > limit) {
2881 error << string_compose(
2882 _("There are already %1 recordings for %2, which I consider too many."),
2883 limit, base) << endmsg;
2884 destroy ();
2885 throw failed_constructor();
2889 return Glib::path_get_basename(buf);
2892 /** Create a new within-session audio source */
2893 boost::shared_ptr<AudioFileSource>
2894 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
2896 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2897 const string path = new_source_path_from_name(DataType::AUDIO, name);
2899 return boost::dynamic_pointer_cast<AudioFileSource> (
2900 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
2903 /** Return a unique name based on \a base for a new internal MIDI source */
2904 string
2905 Session::new_midi_source_name (const string& base)
2907 uint32_t cnt;
2908 char buf[PATH_MAX+1];
2909 const uint32_t limit = 10000;
2910 string legalized;
2912 buf[0] = '\0';
2913 legalized = legalize_for_path (base);
2915 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2916 for (cnt = 1; cnt <= limit; ++cnt) {
2918 vector<space_and_path>::iterator i;
2919 uint32_t existing = 0;
2921 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2923 SessionDirectory sdir((*i).path);
2925 sys::path p = sdir.midi_path();
2926 p /= legalized;
2928 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
2930 if (sys::exists (buf)) {
2931 existing++;
2935 if (existing == 0) {
2936 break;
2939 if (cnt > limit) {
2940 error << string_compose(
2941 _("There are already %1 recordings for %2, which I consider too many."),
2942 limit, base) << endmsg;
2943 destroy ();
2944 throw failed_constructor();
2948 return Glib::path_get_basename(buf);
2952 /** Create a new within-session MIDI source */
2953 boost::shared_ptr<MidiSource>
2954 Session::create_midi_source_for_session (Track* track, string const & n)
2956 /* try to use the existing write source for the track, to keep numbering sane
2959 if (track) {
2960 /*MidiTrack* mt = dynamic_cast<Track*> (track);
2961 assert (mt);
2964 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
2966 if (!l.empty()) {
2967 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
2968 return boost::dynamic_pointer_cast<MidiSource> (l.front());
2972 const string name = new_midi_source_name (n);
2973 const string path = new_source_path_from_name (DataType::MIDI, name);
2975 return boost::dynamic_pointer_cast<SMFSource> (
2976 SourceFactory::createWritable (
2977 DataType::MIDI, *this, path, false, frame_rate()));
2981 void
2982 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
2984 if (playlist->hidden()) {
2985 return;
2988 playlists->add (playlist);
2990 if (unused) {
2991 playlist->release();
2994 set_dirty();
2997 void
2998 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3000 if (_state_of_the_state & Deletion) {
3001 return;
3004 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3006 if (!playlist) {
3007 return;
3010 playlists->remove (playlist);
3012 set_dirty();
3015 void
3016 Session::set_audition (boost::shared_ptr<Region> r)
3018 pending_audition_region = r;
3019 add_post_transport_work (PostTransportAudition);
3020 _butler->schedule_transport_work ();
3023 void
3024 Session::audition_playlist ()
3026 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3027 ev->region.reset ();
3028 queue_event (ev);
3031 void
3032 Session::non_realtime_set_audition ()
3034 if (!pending_audition_region) {
3035 auditioner->audition_current_playlist ();
3036 } else {
3037 auditioner->audition_region (pending_audition_region);
3038 pending_audition_region.reset ();
3040 AuditionActive (true); /* EMIT SIGNAL */
3043 void
3044 Session::audition_region (boost::shared_ptr<Region> r)
3046 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3047 ev->region = r;
3048 queue_event (ev);
3051 void
3052 Session::cancel_audition ()
3054 if (auditioner->auditioning()) {
3055 auditioner->cancel_audition ();
3056 AuditionActive (false); /* EMIT SIGNAL */
3060 bool
3061 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3063 if (a->is_monitor()) {
3064 return true;
3066 if (b->is_monitor()) {
3067 return false;
3069 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3072 void
3073 Session::remove_empty_sounds ()
3075 vector<string> audio_filenames;
3077 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3079 Glib::Mutex::Lock lm (source_lock);
3081 TapeFileMatcher tape_file_matcher;
3083 remove_if (audio_filenames.begin(), audio_filenames.end(),
3084 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3086 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3088 sys::path audio_file_path (_session_dir->sound_path());
3090 audio_file_path /= *i;
3092 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3096 sys::remove (audio_file_path);
3097 const string peakfile = peak_path (audio_file_path.to_string());
3098 sys::remove (peakfile);
3100 catch (const sys::filesystem_error& err)
3102 error << err.what() << endmsg;
3108 bool
3109 Session::is_auditioning () const
3111 /* can be called before we have an auditioner object */
3112 if (auditioner) {
3113 return auditioner->auditioning();
3114 } else {
3115 return false;
3119 void
3120 Session::graph_reordered ()
3122 /* don't do this stuff if we are setting up connections
3123 from a set_state() call or creating new tracks. Ditto for deletion.
3126 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3127 return;
3130 /* every track/bus asked for this to be handled but it was deferred because
3131 we were connecting. do it now.
3134 request_input_change_handling ();
3136 resort_routes ();
3138 /* force all diskstreams to update their capture offset values to
3139 reflect any changes in latencies within the graph.
3142 boost::shared_ptr<RouteList> rl = routes.reader ();
3143 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3144 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3145 if (tr) {
3146 tr->set_capture_offset ();
3151 nframes_t
3152 Session::available_capture_duration ()
3154 float sample_bytes_on_disk = 4.0; // keep gcc happy
3156 switch (config.get_native_file_data_format()) {
3157 case FormatFloat:
3158 sample_bytes_on_disk = 4.0;
3159 break;
3161 case FormatInt24:
3162 sample_bytes_on_disk = 3.0;
3163 break;
3165 case FormatInt16:
3166 sample_bytes_on_disk = 2.0;
3167 break;
3169 default:
3170 /* impossible, but keep some gcc versions happy */
3171 fatal << string_compose (_("programming error: %1"),
3172 X_("illegal native file data format"))
3173 << endmsg;
3174 /*NOTREACHED*/
3177 double scale = 4096.0 / sample_bytes_on_disk;
3179 if (_total_free_4k_blocks * scale > (double) max_frames) {
3180 return max_frames;
3183 return (nframes_t) floor (_total_free_4k_blocks * scale);
3186 void
3187 Session::add_bundle (shared_ptr<Bundle> bundle)
3190 RCUWriter<BundleList> writer (_bundles);
3191 boost::shared_ptr<BundleList> b = writer.get_copy ();
3192 b->push_back (bundle);
3195 BundleAdded (bundle); /* EMIT SIGNAL */
3197 set_dirty();
3200 void
3201 Session::remove_bundle (shared_ptr<Bundle> bundle)
3203 bool removed = false;
3206 RCUWriter<BundleList> writer (_bundles);
3207 boost::shared_ptr<BundleList> b = writer.get_copy ();
3208 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3210 if (i != b->end()) {
3211 b->erase (i);
3212 removed = true;
3216 if (removed) {
3217 BundleRemoved (bundle); /* EMIT SIGNAL */
3220 set_dirty();
3223 shared_ptr<Bundle>
3224 Session::bundle_by_name (string name) const
3226 boost::shared_ptr<BundleList> b = _bundles.reader ();
3228 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3229 if ((*i)->name() == name) {
3230 return* i;
3234 return boost::shared_ptr<Bundle> ();
3237 void
3238 Session::tempo_map_changed (const PropertyChange&)
3240 clear_clicks ();
3242 playlists->update_after_tempo_map_change ();
3244 set_dirty ();
3247 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3248 * the given count with the current block size.
3250 void
3251 Session::ensure_buffers (ChanCount howmany)
3253 BufferManager::ensure_buffers (howmany);
3256 void
3257 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3259 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3260 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3264 uint32_t
3265 Session::next_insert_id ()
3267 /* this doesn't really loop forever. just think about it */
3269 while (true) {
3270 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3271 if (!insert_bitset[n]) {
3272 insert_bitset[n] = true;
3273 return n;
3278 /* none available, so resize and try again */
3280 insert_bitset.resize (insert_bitset.size() + 16, false);
3284 uint32_t
3285 Session::next_send_id ()
3287 /* this doesn't really loop forever. just think about it */
3289 while (true) {
3290 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3291 if (!send_bitset[n]) {
3292 send_bitset[n] = true;
3293 return n;
3298 /* none available, so resize and try again */
3300 send_bitset.resize (send_bitset.size() + 16, false);
3304 uint32_t
3305 Session::next_return_id ()
3307 /* this doesn't really loop forever. just think about it */
3309 while (true) {
3310 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3311 if (!return_bitset[n]) {
3312 return_bitset[n] = true;
3313 return n;
3318 /* none available, so resize and try again */
3320 return_bitset.resize (return_bitset.size() + 16, false);
3324 void
3325 Session::mark_send_id (uint32_t id)
3327 if (id >= send_bitset.size()) {
3328 send_bitset.resize (id+16, false);
3330 if (send_bitset[id]) {
3331 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3333 send_bitset[id] = true;
3336 void
3337 Session::mark_return_id (uint32_t id)
3339 if (id >= return_bitset.size()) {
3340 return_bitset.resize (id+16, false);
3342 if (return_bitset[id]) {
3343 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3345 return_bitset[id] = true;
3348 void
3349 Session::mark_insert_id (uint32_t id)
3351 if (id >= insert_bitset.size()) {
3352 insert_bitset.resize (id+16, false);
3354 if (insert_bitset[id]) {
3355 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3357 insert_bitset[id] = true;
3360 void
3361 Session::unmark_send_id (uint32_t id)
3363 if (id < send_bitset.size()) {
3364 send_bitset[id] = false;
3368 void
3369 Session::unmark_return_id (uint32_t id)
3371 if (id < return_bitset.size()) {
3372 return_bitset[id] = false;
3376 void
3377 Session::unmark_insert_id (uint32_t id)
3379 if (id < insert_bitset.size()) {
3380 insert_bitset[id] = false;
3385 /* Named Selection management */
3387 boost::shared_ptr<NamedSelection>
3388 Session::named_selection_by_name (string name)
3390 Glib::Mutex::Lock lm (named_selection_lock);
3391 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3392 if ((*i)->name == name) {
3393 return *i;
3396 return boost::shared_ptr<NamedSelection>();
3399 void
3400 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3403 Glib::Mutex::Lock lm (named_selection_lock);
3404 named_selections.insert (named_selections.begin(), named_selection);
3407 set_dirty();
3409 NamedSelectionAdded (); /* EMIT SIGNAL */
3412 void
3413 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3415 bool removed = false;
3418 Glib::Mutex::Lock lm (named_selection_lock);
3420 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3422 if (i != named_selections.end()) {
3423 named_selections.erase (i);
3424 set_dirty();
3425 removed = true;
3429 if (removed) {
3430 NamedSelectionRemoved (); /* EMIT SIGNAL */
3434 void
3435 Session::reset_native_file_format ()
3437 boost::shared_ptr<RouteList> rl = routes.reader ();
3438 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3439 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3440 if (tr) {
3441 tr->reset_write_sources (false);
3446 bool
3447 Session::route_name_unique (string n) const
3449 shared_ptr<RouteList> r = routes.reader ();
3451 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3452 if ((*i)->name() == n) {
3453 return false;
3457 return true;
3460 bool
3461 Session::route_name_internal (string n) const
3463 if (auditioner && auditioner->name() == n) {
3464 return true;
3467 if (_click_io && _click_io->name() == n) {
3468 return true;
3471 return false;
3475 Session::freeze_all (InterThreadInfo& itt)
3477 shared_ptr<RouteList> r = routes.reader ();
3479 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3481 boost::shared_ptr<Track> t;
3483 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3484 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3485 of every track.
3487 t->freeze_me (itt);
3491 return 0;
3494 boost::shared_ptr<Region>
3495 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3496 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3497 InterThreadInfo& itt, bool enable_processing)
3499 boost::shared_ptr<Region> result;
3500 boost::shared_ptr<Playlist> playlist;
3501 boost::shared_ptr<AudioFileSource> fsource;
3502 uint32_t x;
3503 char buf[PATH_MAX+1];
3504 ChanCount nchans(track.n_channels());
3505 nframes_t position;
3506 nframes_t this_chunk;
3507 nframes_t to_do;
3508 BufferSet buffers;
3509 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3510 const string sound_dir = sdir.sound_path().to_string();
3511 nframes_t len = end - start;
3513 if (end <= start) {
3514 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3515 end, start) << endmsg;
3516 return result;
3519 const nframes_t chunk_size = (256 * 1024)/4;
3521 // block all process callback handling
3523 block_processing ();
3525 /* call tree *MUST* hold route_lock */
3527 if ((playlist = track.playlist()) == 0) {
3528 goto out;
3531 /* external redirects will be a problem */
3533 if (track.has_external_redirects()) {
3534 goto out;
3537 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3539 for (x = 0; x < 99999; ++x) {
3540 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3541 if (access (buf, F_OK) != 0) {
3542 break;
3546 if (x == 99999) {
3547 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3548 goto out;
3551 try {
3552 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3553 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3556 catch (failed_constructor& err) {
3557 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3558 goto out;
3561 srcs.push_back (fsource);
3564 /* XXX need to flush all redirects */
3566 position = start;
3567 to_do = len;
3569 /* create a set of reasonably-sized buffers */
3570 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3571 buffers.set_count(nchans);
3573 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3574 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3575 if (afs)
3576 afs->prepare_for_peakfile_writes ();
3579 while (to_do && !itt.cancel) {
3581 this_chunk = min (to_do, chunk_size);
3583 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3584 goto out;
3587 uint32_t n = 0;
3588 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3589 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3591 if (afs) {
3592 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3593 goto out;
3598 start += this_chunk;
3599 to_do -= this_chunk;
3601 itt.progress = (float) (1.0 - ((double) to_do / len));
3605 if (!itt.cancel) {
3607 time_t now;
3608 struct tm* xnow;
3609 time (&now);
3610 xnow = localtime (&now);
3612 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3613 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3615 if (afs) {
3616 afs->update_header (position, *xnow, now);
3617 afs->flush_header ();
3621 /* construct a region to represent the bounced material */
3623 PropertyList plist;
3625 plist.add (Properties::start, 0);
3626 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3627 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3629 result = RegionFactory::create (srcs, plist);
3633 out:
3634 if (!result) {
3635 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3636 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3638 if (afs) {
3639 afs->mark_for_remove ();
3642 (*src)->drop_references ();
3645 } else {
3646 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3647 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3649 if (afs)
3650 afs->done_with_peakfile_writes ();
3654 unblock_processing ();
3656 return result;
3659 gain_t*
3660 Session::gain_automation_buffer() const
3662 return ProcessThread::gain_automation_buffer ();
3665 pan_t**
3666 Session::pan_automation_buffer() const
3668 return ProcessThread::pan_automation_buffer ();
3671 BufferSet&
3672 Session::get_silent_buffers (ChanCount count)
3674 return ProcessThread::get_silent_buffers (count);
3675 #if 0
3676 assert(_silent_buffers->available() >= count);
3677 _silent_buffers->set_count(count);
3679 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3680 for (size_t i= 0; i < count.get(*t); ++i) {
3681 _silent_buffers->get(*t, i).clear();
3685 return *_silent_buffers;
3686 #endif
3689 BufferSet&
3690 Session::get_scratch_buffers (ChanCount count)
3692 return ProcessThread::get_scratch_buffers (count);
3693 #if 0
3694 if (count != ChanCount::ZERO) {
3695 assert(_scratch_buffers->available() >= count);
3696 _scratch_buffers->set_count(count);
3697 } else {
3698 _scratch_buffers->set_count (_scratch_buffers->available());
3701 return *_scratch_buffers;
3702 #endif
3705 BufferSet&
3706 Session::get_mix_buffers (ChanCount count)
3708 return ProcessThread::get_mix_buffers (count);
3709 #if 0
3710 assert(_mix_buffers->available() >= count);
3711 _mix_buffers->set_count(count);
3712 return *_mix_buffers;
3713 #endif
3716 uint32_t
3717 Session::ntracks () const
3719 uint32_t n = 0;
3720 shared_ptr<RouteList> r = routes.reader ();
3722 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3723 if (boost::dynamic_pointer_cast<Track> (*i)) {
3724 ++n;
3728 return n;
3731 uint32_t
3732 Session::nbusses () const
3734 uint32_t n = 0;
3735 shared_ptr<RouteList> r = routes.reader ();
3737 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3738 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3739 ++n;
3743 return n;
3746 void
3747 Session::add_automation_list(AutomationList *al)
3749 automation_lists[al->id()] = al;
3752 void
3753 Session::sync_order_keys (std::string const & base)
3755 if (deletion_in_progress()) {
3756 return;
3759 if (!Config->get_sync_all_route_ordering()) {
3760 /* leave order keys as they are */
3761 return;
3764 boost::shared_ptr<RouteList> r = routes.reader ();
3766 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3767 (*i)->sync_order_keys (base);
3770 Route::SyncOrderKeys (base); // EMIT SIGNAL
3772 /* this might not do anything */
3774 set_remote_control_ids ();
3777 /** @return true if there is at least one record-enabled track, otherwise false */
3778 bool
3779 Session::have_rec_enabled_track () const
3781 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3784 /** Update the state of our rec-enabled tracks flag */
3785 void
3786 Session::update_have_rec_enabled_track ()
3788 boost::shared_ptr<RouteList> rl = routes.reader ();
3789 RouteList::iterator i = rl->begin();
3790 while (i != rl->end ()) {
3792 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3793 if (tr && tr->record_enabled ()) {
3794 break;
3797 ++i;
3800 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3802 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3804 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3805 RecordStateChanged (); /* EMIT SIGNAL */
3809 void
3810 Session::listen_position_changed ()
3812 Placement p;
3814 switch (Config->get_listen_position()) {
3815 case AfterFaderListen:
3816 p = PostFader;
3817 break;
3819 case PreFaderListen:
3820 p = PreFader;
3821 break;
3824 boost::shared_ptr<RouteList> r = routes.reader ();
3826 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3827 (*i)->put_monitor_send_at (p);
3831 void
3832 Session::solo_control_mode_changed ()
3834 /* cancel all solo or all listen when solo control mode changes */
3836 if (soloing()) {
3837 set_solo (get_routes(), false);
3838 } else if (listening()) {
3839 set_listen (get_routes(), false);
3843 void
3844 Session::route_group_changed ()
3846 RouteGroupChanged (); /* EMIT SIGNAL */
3849 vector<SyncSource>
3850 Session::get_available_sync_options () const
3852 vector<SyncSource> ret;
3854 ret.push_back (JACK);
3856 if (mtc_port()) {
3857 ret.push_back (MTC);
3860 if (midi_clock_port()) {
3861 ret.push_back (MIDIClock);
3864 return ret;
3867 boost::shared_ptr<RouteList>
3868 Session::get_routes_with_regions_at (nframes64_t const p) const
3870 shared_ptr<RouteList> r = routes.reader ();
3871 shared_ptr<RouteList> rl (new RouteList);
3873 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3874 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3875 if (!tr) {
3876 continue;
3879 boost::shared_ptr<Playlist> pl = tr->playlist ();
3880 if (!pl) {
3881 continue;
3884 if (pl->has_region_at (p)) {
3885 rl->push_back (*i);
3889 return rl;
3892 void
3893 Session::goto_end ()
3895 if (_session_range_location) {
3896 request_locate (_session_range_location->end(), false);
3897 } else {
3898 request_locate (0, false);
3902 void
3903 Session::goto_start ()
3905 if (_session_range_location) {
3906 request_locate (_session_range_location->start(), false);
3907 } else {
3908 request_locate (0, false);
3912 void
3913 Session::set_session_start (nframes_t start)
3915 if (_session_range_location) {
3916 _session_range_location->set_start (start);
3917 } else {
3918 add_session_range_location (start, start);
3922 void
3923 Session::set_session_end (nframes_t end)
3925 if (_session_range_location) {
3926 _session_range_location->set_end (end);
3927 } else {
3928 add_session_range_location (end, end);
3932 nframes_t
3933 Session::current_start_frame () const
3935 return _session_range_location ? _session_range_location->start() : 0;
3938 nframes_t
3939 Session::current_end_frame () const
3941 return _session_range_location ? _session_range_location->end() : 0;
3944 void
3945 Session::add_session_range_location (nframes_t start, nframes_t end)
3947 _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange);
3948 _locations.add (_session_range_location);