fix up file renaming code a little bit
[ArdourMidi.git] / libs / ardour / session.cc
blob344a20f86046dba5c00718f3bdb7f69d37469591
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++/port.h"
102 #include "midi++/mmc.h"
103 #include "midi++/manager.h"
105 #include "i18n.h"
107 using namespace std;
108 using namespace ARDOUR;
109 using namespace PBD;
110 using boost::shared_ptr;
111 using boost::weak_ptr;
113 bool Session::_disable_all_loaded_plugins = false;
115 PBD::Signal1<void,std::string> Session::Dialog;
116 PBD::Signal0<int> Session::AskAboutPendingState;
117 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
118 PBD::Signal0<void> Session::SendFeedback;
120 PBD::Signal0<void> Session::TimecodeOffsetChanged;
121 PBD::Signal0<void> Session::StartTimeChanged;
122 PBD::Signal0<void> Session::EndTimeChanged;
123 PBD::Signal0<void> Session::AutoBindingOn;
124 PBD::Signal0<void> Session::AutoBindingOff;
125 PBD::Signal2<void,std::string, std::string> Session::Exported;
126 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
128 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
129 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
131 Session::Session (AudioEngine &eng,
132 const string& fullpath,
133 const string& snapshot_name,
134 BusProfile* bus_profile,
135 string mix_template)
137 : _engine (eng),
138 _target_transport_speed (0.0),
139 _requested_return_frame (-1),
140 _session_dir (new SessionDirectory(fullpath)),
141 state_tree (0),
142 _butler (new Butler (*this)),
143 _post_transport_work (0),
144 _send_timecode_update (false),
145 route_graph (new Graph(*this)),
146 routes (new RouteList),
147 _total_free_4k_blocks (0),
148 _bundles (new BundleList),
149 _bundle_xml_node (0),
150 _click_io ((IO*) 0),
151 click_data (0),
152 click_emphasis_data (0),
153 main_outs (0),
154 _metadata (new SessionMetadata()),
155 _have_rec_enabled_track (false)
158 playlists.reset (new SessionPlaylists);
160 interpolation.add_channel_to (0, 0);
162 if (!eng.connected()) {
163 throw failed_constructor();
166 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
167 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
169 first_stage_init (fullpath, snapshot_name);
171 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
173 if (_is_new) {
174 if (create (mix_template, bus_profile)) {
175 destroy ();
176 throw failed_constructor ();
180 if (second_stage_init ()) {
181 destroy ();
182 throw failed_constructor ();
185 store_recent_sessions(_name, _path);
187 bool was_dirty = dirty();
189 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
191 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
192 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
194 if (was_dirty) {
195 DirtyChanged (); /* EMIT SIGNAL */
198 _is_new = false;
201 Session::~Session ()
203 destroy ();
206 void
207 Session::destroy ()
209 vector<void*> debug_pointers;
211 /* if we got to here, leaving pending capture state around
212 is a mistake.
215 remove_pending_capture_state ();
217 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
219 _engine.remove_session ();
221 /* clear history so that no references to objects are held any more */
223 _history.clear ();
225 /* clear state tree so that no references to objects are held any more */
227 delete state_tree;
229 /* remove all stubfiles that might still be lurking */
231 cleanup_stubfiles ();
233 /* reset dynamic state version back to default */
235 Stateful::loading_state_version = 0;
237 _butler->drop_references ();
238 delete _butler;
239 delete midi_control_ui;
241 if (click_data != default_click) {
242 delete [] click_data;
245 if (click_emphasis_data != default_click_emphasis) {
246 delete [] click_emphasis_data;
249 clear_clicks ();
251 /* clear out any pending dead wood from RCU managed objects */
253 routes.flush ();
254 _bundles.flush ();
256 AudioDiskstream::free_working_buffers();
258 /* tell everyone who is still standing that we're about to die */
259 drop_references ();
261 /* tell everyone to drop references and delete objects as we go */
263 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
264 named_selections.clear ();
266 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
267 RegionFactory::delete_all_regions ();
269 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
271 /* reset these three references to special routes before we do the usual route delete thing */
273 auditioner.reset ();
274 _master_out.reset ();
275 _monitor_out.reset ();
278 RCUWriter<RouteList> writer (routes);
279 boost::shared_ptr<RouteList> r = writer.get_copy ();
281 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
282 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
283 (*i)->drop_references ();
286 r->clear ();
287 /* writer goes out of scope and updates master */
289 routes.flush ();
291 boost::shared_ptr<RouteList> r = routes.reader ();
293 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
294 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
295 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
296 i->second->drop_references ();
299 sources.clear ();
301 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
302 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
304 delete *i;
307 Crossfade::set_buffer_size (0);
309 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
310 playlists.reset ();
312 boost_debug_list_ptrs ();
314 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
317 void
318 Session::set_worst_io_latencies ()
320 _worst_output_latency = 0;
321 _worst_input_latency = 0;
323 if (!_engine.connected()) {
324 return;
327 boost::shared_ptr<RouteList> r = routes.reader ();
329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
330 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
331 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
335 void
336 Session::when_engine_running ()
338 string first_physical_output;
340 BootMessage (_("Set block size and sample rate"));
342 set_block_size (_engine.frames_per_cycle());
343 set_frame_rate (_engine.frame_rate());
345 BootMessage (_("Using configuration"));
347 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
348 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
350 Config->map_parameters (ff);
351 config.map_parameters (ft);
353 /* every time we reconnect, recompute worst case output latencies */
355 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
357 if (synced_to_jack()) {
358 _engine.transport_stop ();
361 if (config.get_jack_time_master()) {
362 _engine.transport_locate (_transport_frame);
365 _clicking = false;
367 try {
368 XMLNode* child = 0;
370 _click_io.reset (new ClickIO (*this, "click"));
372 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
374 /* existing state for Click */
375 int c;
377 if (Stateful::loading_state_version < 3000) {
378 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
379 } else {
380 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
384 if (c == 0) {
385 _clicking = Config->get_clicking ();
387 } else {
389 error << _("could not setup Click I/O") << endmsg;
390 _clicking = false;
394 } else {
396 /* default state for Click: dual-mono to first 2 physical outputs */
398 for (int physport = 0; physport < 2; ++physport) {
399 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
401 if (physical_output.length()) {
402 if (_click_io->add_port (physical_output, this)) {
403 // relax, even though its an error
408 if (_click_io->n_ports () > ChanCount::ZERO) {
409 _clicking = Config->get_clicking ();
414 catch (failed_constructor& err) {
415 error << _("cannot setup Click I/O") << endmsg;
418 BootMessage (_("Compute I/O Latencies"));
420 set_worst_io_latencies ();
422 if (_clicking) {
423 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
426 BootMessage (_("Set up standard connections"));
428 /* Create a set of Bundle objects that map
429 to the physical I/O currently available. We create both
430 mono and stereo bundles, so that the common cases of mono
431 and stereo tracks get bundles to put in their mixer strip
432 in / out menus. There may be a nicer way of achieving that;
433 it doesn't really scale that well to higher channel counts
436 /* mono output bundles */
438 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
439 char buf[32];
440 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
442 shared_ptr<Bundle> c (new Bundle (buf, true));
443 c->add_channel (_("mono"), DataType::AUDIO);
444 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
446 add_bundle (c);
449 /* stereo output bundles */
451 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
452 if (np + 1 < n_physical_outputs) {
453 char buf[32];
454 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
455 shared_ptr<Bundle> c (new Bundle (buf, true));
456 c->add_channel (_("L"), DataType::AUDIO);
457 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
458 c->add_channel (_("R"), DataType::AUDIO);
459 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
461 add_bundle (c);
465 /* mono input bundles */
467 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
468 char buf[32];
469 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
471 shared_ptr<Bundle> c (new Bundle (buf, false));
472 c->add_channel (_("mono"), DataType::AUDIO);
473 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
475 add_bundle (c);
478 /* stereo input bundles */
480 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
481 if (np + 1 < n_physical_inputs) {
482 char buf[32];
483 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
485 shared_ptr<Bundle> c (new Bundle (buf, false));
486 c->add_channel (_("L"), DataType::AUDIO);
487 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
488 c->add_channel (_("R"), DataType::AUDIO);
489 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
491 add_bundle (c);
495 BootMessage (_("Setup signal flow and plugins"));
497 hookup_io ();
499 if (_is_new && !no_auto_connect()) {
501 /* don't connect the master bus outputs if there is a monitor bus */
503 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
505 /* if requested auto-connect the outputs to the first N physical ports.
508 uint32_t limit = _master_out->n_outputs().n_total();
510 for (uint32_t n = 0; n < limit; ++n) {
511 Port* p = _master_out->output()->nth (n);
512 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
514 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
515 if (_master_out->output()->connect (p, connect_to, this)) {
516 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
517 << endmsg;
518 break;
524 if (_monitor_out) {
526 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
527 are undefined, at best.
530 /* control out listens to master bus (but ignores it
531 under some conditions)
534 uint32_t limit = _monitor_out->n_inputs().n_audio();
536 if (_master_out) {
537 for (uint32_t n = 0; n < limit; ++n) {
538 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
539 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
541 if (o) {
542 string connect_to = o->name();
543 if (_monitor_out->input()->connect (p, connect_to, this)) {
544 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
545 << endmsg;
546 break;
552 /* if control out is not connected, connect control out to physical outs
555 if (!_monitor_out->output()->connected ()) {
557 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
559 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
561 if (b) {
562 _monitor_out->output()->connect_ports_to_bundle (b, this);
563 } else {
564 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
565 Config->get_monitor_bus_preferred_bundle())
566 << endmsg;
569 } else {
571 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
572 uint32_t mod = _engine.n_physical_outputs (*t);
573 uint32_t limit = _monitor_out->n_outputs().get(*t);
575 for (uint32_t n = 0; n < limit; ++n) {
577 Port* p = _monitor_out->output()->ports().port(*t, n);
578 string connect_to = _engine.get_nth_physical_output (*t, (n % mod));
580 if (!connect_to.empty()) {
581 if (_monitor_out->output()->connect (p, connect_to, this)) {
582 error << string_compose (
583 _("cannot connect control output %1 to %2"),
584 n, connect_to)
585 << endmsg;
586 break;
596 /* catch up on send+insert cnts */
598 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
600 /* hook us up to the engine */
602 BootMessage (_("Connect to engine"));
604 _engine.set_session (this);
607 void
608 Session::hookup_io ()
610 /* stop graph reordering notifications from
611 causing resorts, etc.
614 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
617 if (!auditioner) {
619 /* we delay creating the auditioner till now because
620 it makes its own connections to ports.
623 try {
624 Auditioner* a = new Auditioner (*this);
625 if (a->init()) {
626 delete a;
627 throw failed_constructor();
629 a->use_new_diskstream ();
630 auditioner.reset (a);
633 catch (failed_constructor& err) {
634 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
638 /* load bundles, which we may have postponed earlier on */
639 if (_bundle_xml_node) {
640 load_bundles (*_bundle_xml_node);
641 delete _bundle_xml_node;
644 /* Tell all IO objects to connect themselves together */
646 IO::enable_connecting ();
647 MIDI::Port::MakeConnections ();
649 /* Now reset all panners */
651 Delivery::reset_panners ();
653 /* Connect tracks to monitor/listen bus if there is one.
654 Note that in an existing session, the internal sends will
655 already exist, but we want the routes to notice that
656 they connect to the control out specifically.
659 if (_monitor_out) {
660 boost::shared_ptr<RouteList> r = routes.reader ();
661 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
663 if ((*x)->is_monitor()) {
665 /* relax */
667 } else if ((*x)->is_master()) {
669 /* relax */
671 } else {
673 (*x)->listen_via (_monitor_out,
674 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
675 false, false);
680 /* Anyone who cares about input state, wake up and do something */
682 IOConnectionsComplete (); /* EMIT SIGNAL */
684 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
686 /* now handle the whole enchilada as if it was one
687 graph reorder event.
690 graph_reordered ();
692 /* update the full solo state, which can't be
693 correctly determined on a per-route basis, but
694 needs the global overview that only the session
695 has.
698 update_route_solo_state ();
701 void
702 Session::playlist_length_changed ()
704 update_session_range_location_marker ();
707 void
708 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
710 boost::shared_ptr<Track> track = wp.lock ();
711 if (!track) {
712 return;
715 boost::shared_ptr<Playlist> playlist;
717 if ((playlist = track->playlist()) != 0) {
718 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
721 update_session_range_location_marker ();
724 bool
725 Session::record_enabling_legal () const
727 /* this used to be in here, but survey says.... we don't need to restrict it */
728 // if (record_status() == Recording) {
729 // return false;
730 // }
732 if (Config->get_all_safe()) {
733 return false;
735 return true;
738 void
739 Session::reset_input_monitor_state ()
741 if (transport_rolling()) {
743 boost::shared_ptr<RouteList> rl = routes.reader ();
744 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
745 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
746 if (tr && tr->record_enabled ()) {
747 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
748 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
752 } else {
754 boost::shared_ptr<RouteList> rl = routes.reader ();
755 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
756 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
757 if (tr && tr->record_enabled ()) {
758 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
759 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
765 void
766 Session::auto_punch_start_changed (Location* location)
768 replace_event (SessionEvent::PunchIn, location->start());
770 if (get_record_enabled() && config.get_punch_in()) {
771 /* capture start has been changed, so save new pending state */
772 save_state ("", true);
776 void
777 Session::auto_punch_end_changed (Location* location)
779 nframes_t when_to_stop = location->end();
780 // when_to_stop += _worst_output_latency + _worst_input_latency;
781 replace_event (SessionEvent::PunchOut, when_to_stop);
784 void
785 Session::auto_punch_changed (Location* location)
787 nframes_t when_to_stop = location->end();
789 replace_event (SessionEvent::PunchIn, location->start());
790 //when_to_stop += _worst_output_latency + _worst_input_latency;
791 replace_event (SessionEvent::PunchOut, when_to_stop);
794 void
795 Session::auto_loop_changed (Location* location)
797 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
799 if (transport_rolling() && play_loop) {
802 // if (_transport_frame > location->end()) {
804 if (_transport_frame < location->start() || _transport_frame > location->end()) {
805 // relocate to beginning of loop
806 clear_events (SessionEvent::LocateRoll);
808 request_locate (location->start(), true);
811 else if (Config->get_seamless_loop() && !loop_changing) {
813 // schedule a locate-roll to refill the diskstreams at the
814 // previous loop end
815 loop_changing = true;
817 if (location->end() > last_loopend) {
818 clear_events (SessionEvent::LocateRoll);
819 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
820 queue_event (ev);
826 last_loopend = location->end();
829 void
830 Session::set_auto_punch_location (Location* location)
832 Location* existing;
834 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
835 punch_connections.drop_connections();
836 existing->set_auto_punch (false, this);
837 remove_event (existing->start(), SessionEvent::PunchIn);
838 clear_events (SessionEvent::PunchOut);
839 auto_punch_location_changed (0);
842 set_dirty();
844 if (location == 0) {
845 return;
848 if (location->end() <= location->start()) {
849 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
850 return;
853 punch_connections.drop_connections ();
855 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
856 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
857 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
859 location->set_auto_punch (true, this);
861 auto_punch_changed (location);
863 auto_punch_location_changed (location);
866 void
867 Session::set_auto_loop_location (Location* location)
869 Location* existing;
871 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
872 loop_connections.drop_connections ();
873 existing->set_auto_loop (false, this);
874 remove_event (existing->end(), SessionEvent::AutoLoop);
875 auto_loop_location_changed (0);
878 set_dirty();
880 if (location == 0) {
881 return;
884 if (location->end() <= location->start()) {
885 error << _("Session: you can't use a mark for auto loop") << endmsg;
886 return;
889 last_loopend = location->end();
891 loop_connections.drop_connections ();
893 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
894 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
895 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
897 location->set_auto_loop (true, this);
899 /* take care of our stuff first */
901 auto_loop_changed (location);
903 /* now tell everyone else */
905 auto_loop_location_changed (location);
908 void
909 Session::locations_added (Location *)
911 set_dirty ();
914 void
915 Session::locations_changed ()
917 _locations.apply (*this, &Session::handle_locations_changed);
920 void
921 Session::handle_locations_changed (Locations::LocationList& locations)
923 Locations::LocationList::iterator i;
924 Location* location;
925 bool set_loop = false;
926 bool set_punch = false;
928 for (i = locations.begin(); i != locations.end(); ++i) {
930 location =* i;
932 if (location->is_auto_punch()) {
933 set_auto_punch_location (location);
934 set_punch = true;
936 if (location->is_auto_loop()) {
937 set_auto_loop_location (location);
938 set_loop = true;
941 if (location->is_session_range()) {
942 _session_range_location = location;
946 if (!set_loop) {
947 set_auto_loop_location (0);
949 if (!set_punch) {
950 set_auto_punch_location (0);
953 set_dirty();
956 void
957 Session::enable_record ()
959 while (1) {
960 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
962 if (rs == Recording) {
963 break;
966 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
968 _last_record_location = _transport_frame;
969 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
971 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
973 boost::shared_ptr<RouteList> rl = routes.reader ();
974 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
975 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
976 if (tr && tr->record_enabled ()) {
977 tr->monitor_input (true);
982 RecordStateChanged ();
983 break;
988 void
989 Session::disable_record (bool rt_context, bool force)
991 RecordState rs;
993 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
995 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
996 g_atomic_int_set (&_record_status, Disabled);
997 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
998 } else {
999 if (rs == Recording) {
1000 g_atomic_int_set (&_record_status, Enabled);
1004 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1006 boost::shared_ptr<RouteList> rl = routes.reader ();
1007 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1008 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1009 if (tr && tr->record_enabled ()) {
1010 tr->monitor_input (false);
1015 RecordStateChanged (); /* emit signal */
1017 if (!rt_context) {
1018 remove_pending_capture_state ();
1023 void
1024 Session::step_back_from_record ()
1026 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1028 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1029 boost::shared_ptr<RouteList> rl = routes.reader ();
1030 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1031 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1032 if (tr && tr->record_enabled ()) {
1033 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1034 tr->monitor_input (false);
1041 void
1042 Session::maybe_enable_record ()
1044 g_atomic_int_set (&_record_status, Enabled);
1046 /* this function is currently called from somewhere other than an RT thread.
1047 this save_state() call therefore doesn't impact anything.
1050 save_state ("", true);
1052 if (_transport_speed) {
1053 if (!config.get_punch_in()) {
1054 enable_record ();
1056 } else {
1057 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1058 RecordStateChanged (); /* EMIT SIGNAL */
1061 set_dirty();
1064 nframes64_t
1065 Session::audible_frame () const
1067 nframes64_t ret;
1068 nframes64_t tf;
1069 nframes_t offset;
1071 /* the first of these two possible settings for "offset"
1072 mean that the audible frame is stationary until
1073 audio emerges from the latency compensation
1074 "pseudo-pipeline".
1076 the second means that the audible frame is stationary
1077 until audio would emerge from a physical port
1078 in the absence of any plugin latency compensation
1081 offset = _worst_output_latency;
1083 if (offset > current_block_size) {
1084 offset -= current_block_size;
1085 } else {
1086 /* XXX is this correct? if we have no external
1087 physical connections and everything is internal
1088 then surely this is zero? still, how
1089 likely is that anyway?
1091 offset = current_block_size;
1094 if (synced_to_jack()) {
1095 tf = _engine.transport_frame();
1096 } else {
1097 tf = _transport_frame;
1100 ret = tf;
1102 if (!non_realtime_work_pending()) {
1104 /* MOVING */
1106 /* Check to see if we have passed the first guaranteed
1107 audible frame past our last start position. if not,
1108 return that last start point because in terms
1109 of audible frames, we have not moved yet.
1111 `Start position' in this context means the time we last
1112 either started or changed transport direction.
1115 if (_transport_speed > 0.0f) {
1117 if (!play_loop || !have_looped) {
1118 if (tf < _last_roll_or_reversal_location + offset) {
1119 return _last_roll_or_reversal_location;
1124 /* forwards */
1125 ret -= offset;
1127 } else if (_transport_speed < 0.0f) {
1129 /* XXX wot? no backward looping? */
1131 if (tf > _last_roll_or_reversal_location - offset) {
1132 return _last_roll_or_reversal_location;
1133 } else {
1134 /* backwards */
1135 ret += offset;
1140 return ret;
1143 void
1144 Session::set_frame_rate (nframes_t frames_per_second)
1146 /** \fn void Session::set_frame_size(nframes_t)
1147 the AudioEngine object that calls this guarantees
1148 that it will not be called while we are also in
1149 ::process(). Its fine to do things that block
1150 here.
1153 _base_frame_rate = frames_per_second;
1155 sync_time_vars();
1157 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1159 clear_clicks ();
1161 // XXX we need some equivalent to this, somehow
1162 // SndFileSource::setup_standard_crossfades (frames_per_second);
1164 set_dirty();
1166 /* XXX need to reset/reinstantiate all LADSPA plugins */
1169 void
1170 Session::set_block_size (nframes_t nframes)
1172 /* the AudioEngine guarantees
1173 that it will not be called while we are also in
1174 ::process(). It is therefore fine to do things that block
1175 here.
1179 current_block_size = nframes;
1181 ensure_buffers ();
1183 boost::shared_ptr<RouteList> r = routes.reader ();
1185 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1186 (*i)->set_block_size (nframes);
1189 boost::shared_ptr<RouteList> rl = routes.reader ();
1190 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1191 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1192 if (tr) {
1193 tr->set_block_size (nframes);
1197 set_worst_io_latencies ();
1201 void
1202 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1204 #if 0
1205 nframes_t fade_frames;
1207 /* Don't allow fade of less 1 frame */
1209 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1211 fade_msecs = 0;
1212 fade_frames = 0;
1214 } else {
1216 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1220 default_fade_msecs = fade_msecs;
1221 default_fade_steepness = steepness;
1224 // jlc, WTF is this!
1225 Glib::RWLock::ReaderLock lm (route_lock);
1226 AudioRegion::set_default_fade (steepness, fade_frames);
1229 set_dirty();
1231 /* XXX have to do this at some point */
1232 /* foreach region using default fade, reset, then
1233 refill_all_diskstream_buffers ();
1235 #endif
1238 struct RouteSorter {
1239 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1240 if (r2->feeds (r1)) {
1241 return false;
1242 } else if (r1->feeds (r2)) {
1243 return true;
1244 } else {
1245 if (r1->not_fed ()) {
1246 if (r2->not_fed ()) {
1247 /* no ardour-based connections inbound to either route. just use signal order */
1248 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1249 } else {
1250 /* r2 has connections, r1 does not; run r1 early */
1251 return true;
1253 } else {
1254 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1260 static void
1261 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1263 shared_ptr<Route> r2;
1265 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1266 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1267 return;
1270 /* make a copy of the existing list of routes that feed r1 */
1272 Route::FedBy existing (r1->fed_by());
1274 /* for each route that feeds r1, recurse, marking it as feeding
1275 rbase as well.
1278 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1279 if (!(r2 = i->r.lock ())) {
1280 /* (*i) went away, ignore it */
1281 continue;
1284 /* r2 is a route that feeds r1 which somehow feeds base. mark
1285 base as being fed by r2
1288 rbase->add_fed_by (r2, i->sends_only);
1290 if (r2 != rbase) {
1292 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1293 stop here.
1296 if (r1->feeds (r2) && r2->feeds (r1)) {
1297 continue;
1300 /* now recurse, so that we can mark base as being fed by
1301 all routes that feed r2
1304 trace_terminal (r2, rbase);
1310 void
1311 Session::resort_routes ()
1313 /* don't do anything here with signals emitted
1314 by Routes while we are being destroyed.
1317 if (_state_of_the_state & Deletion) {
1318 return;
1322 RCUWriter<RouteList> writer (routes);
1323 shared_ptr<RouteList> r = writer.get_copy ();
1324 resort_routes_using (r);
1325 /* writer goes out of scope and forces update */
1328 //route_graph->dump(1);
1330 #ifndef NDEBUG
1331 boost::shared_ptr<RouteList> rl = routes.reader ();
1332 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1333 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1335 const Route::FedBy& fb ((*i)->fed_by());
1337 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1338 boost::shared_ptr<Route> sf = f->r.lock();
1339 if (sf) {
1340 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1344 #endif
1347 void
1348 Session::resort_routes_using (shared_ptr<RouteList> r)
1350 RouteList::iterator i, j;
1352 for (i = r->begin(); i != r->end(); ++i) {
1354 (*i)->clear_fed_by ();
1356 for (j = r->begin(); j != r->end(); ++j) {
1358 /* although routes can feed themselves, it will
1359 cause an endless recursive descent if we
1360 detect it. so don't bother checking for
1361 self-feeding.
1364 if (*j == *i) {
1365 continue;
1368 bool via_sends_only;
1370 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1371 (*i)->add_fed_by (*j, via_sends_only);
1376 for (i = r->begin(); i != r->end(); ++i) {
1377 trace_terminal (*i, *i);
1380 RouteSorter cmp;
1381 r->sort (cmp);
1383 route_graph->rechain (r);
1385 #ifndef NDEBUG
1386 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1387 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1388 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1389 (*i)->name(), (*i)->order_key ("signal")));
1391 #endif
1395 /** Find the route name starting with \a base with the lowest \a id.
1397 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1398 * The available route name with the lowest ID will be used, and \a id
1399 * will be set to the ID.
1401 * \return false if a route name could not be found, and \a track_name
1402 * and \a id do not reflect a free route name.
1404 bool
1405 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1407 do {
1408 snprintf (name, name_len, "%s %" PRIu32, base, id);
1410 if (route_by_name (name) == 0) {
1411 return true;
1414 ++id;
1416 } while (id < (UINT_MAX-1));
1418 return false;
1421 void
1422 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1424 in = ChanCount::ZERO;
1425 out = ChanCount::ZERO;
1426 shared_ptr<RouteList> r = routes.reader ();
1427 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1428 if (!(*i)->is_hidden()) {
1429 in += (*i)->n_inputs();
1430 out += (*i)->n_outputs();
1435 list<boost::shared_ptr<MidiTrack> >
1436 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1438 char track_name[32];
1439 uint32_t track_id = 0;
1440 ChanCount existing_inputs;
1441 ChanCount existing_outputs;
1442 string port;
1443 RouteList new_routes;
1444 list<boost::shared_ptr<MidiTrack> > ret;
1445 uint32_t control_id;
1447 count_existing_route_channels (existing_inputs, existing_outputs);
1449 control_id = ntracks() + nbusses();
1451 while (how_many) {
1452 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1453 error << "cannot find name for new midi track" << endmsg;
1454 goto failed;
1457 shared_ptr<MidiTrack> track;
1459 try {
1460 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1462 if (mt->init ()) {
1463 delete mt;
1464 goto failed;
1467 mt->use_new_diskstream();
1469 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1470 track = boost::shared_ptr<MidiTrack>(mt);
1472 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1473 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1474 goto failed;
1478 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1479 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1480 goto failed;
1483 auto_connect_route (track, existing_inputs, existing_outputs);
1485 track->non_realtime_input_change();
1487 if (route_group) {
1488 route_group->add (track);
1491 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1492 track->set_remote_control_id (control_id);
1494 new_routes.push_back (track);
1495 ret.push_back (track);
1498 catch (failed_constructor &err) {
1499 error << _("Session: could not create new midi track.") << endmsg;
1500 goto failed;
1503 catch (AudioEngine::PortRegistrationFailure& pfe) {
1505 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;
1506 goto failed;
1509 --how_many;
1512 failed:
1513 if (!new_routes.empty()) {
1514 add_routes (new_routes, false);
1515 save_state (_current_snapshot_name);
1518 return ret;
1521 /** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs */
1522 void
1523 Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs)
1525 /* If both inputs and outputs are auto-connected to physical ports,
1526 use the max of input and output offsets to ensure auto-connected
1527 port numbers always match up (e.g. the first audio input and the
1528 first audio output of the route will have the same physical
1529 port number). Otherwise just use the lowest input or output
1530 offset possible.
1533 const bool in_out_physical =
1534 (Config->get_input_auto_connect() & AutoConnectPhysical)
1535 && (Config->get_output_auto_connect() & AutoConnectPhysical)
1536 && connect_inputs;
1538 const ChanCount in_offset = in_out_physical
1539 ? ChanCount::max(existing_inputs, existing_outputs)
1540 : existing_inputs;
1542 const ChanCount out_offset = in_out_physical
1543 ? ChanCount::max(existing_inputs, existing_outputs)
1544 : existing_outputs;
1546 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1547 vector<string> physinputs;
1548 vector<string> physoutputs;
1550 _engine.get_physical_outputs (*t, physoutputs);
1551 _engine.get_physical_inputs (*t, physinputs);
1553 if (!physinputs.empty() && connect_inputs) {
1554 uint32_t nphysical_in = physinputs.size();
1555 for (uint32_t i = 0; i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1556 string port;
1558 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1559 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1562 if (!port.empty() && route->input()->connect (
1563 route->input()->ports().port(*t, i), port, this)) {
1564 break;
1569 if (!physoutputs.empty()) {
1570 uint32_t nphysical_out = physoutputs.size();
1571 for (uint32_t i = 0; i < route->n_outputs().get(*t); ++i) {
1572 string port;
1574 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1575 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1576 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1577 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1578 port = _master_out->input()->ports().port(*t,
1579 i % _master_out->input()->n_ports().get(*t))->name();
1583 if (!port.empty() && route->output()->connect (
1584 route->output()->ports().port(*t, i), port, this)) {
1585 break;
1591 existing_inputs += route->n_inputs();
1592 existing_outputs += route->n_outputs();
1595 list< boost::shared_ptr<AudioTrack> >
1596 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1598 char track_name[32];
1599 uint32_t track_id = 0;
1600 ChanCount existing_inputs;
1601 ChanCount existing_outputs;
1602 string port;
1603 RouteList new_routes;
1604 list<boost::shared_ptr<AudioTrack> > ret;
1605 uint32_t control_id;
1607 count_existing_route_channels (existing_inputs, existing_outputs);
1609 control_id = ntracks() + nbusses() + 1;
1611 while (how_many) {
1612 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1613 error << "cannot find name for new audio track" << endmsg;
1614 goto failed;
1617 shared_ptr<AudioTrack> track;
1619 try {
1620 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1622 if (at->init ()) {
1623 delete at;
1624 goto failed;
1627 at->use_new_diskstream();
1629 boost_debug_shared_ptr_mark_interesting (at, "Track");
1630 track = boost::shared_ptr<AudioTrack>(at);
1632 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1633 error << string_compose (
1634 _("cannot configure %1 in/%2 out configuration for new audio track"),
1635 input_channels, output_channels)
1636 << endmsg;
1637 goto failed;
1640 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1641 error << string_compose (
1642 _("cannot configure %1 in/%2 out configuration for new audio track"),
1643 input_channels, output_channels)
1644 << endmsg;
1645 goto failed;
1648 auto_connect_route (track, existing_inputs, existing_outputs);
1650 if (route_group) {
1651 route_group->add (track);
1654 track->non_realtime_input_change();
1656 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1657 track->set_remote_control_id (control_id);
1658 ++control_id;
1660 new_routes.push_back (track);
1661 ret.push_back (track);
1664 catch (failed_constructor &err) {
1665 error << _("Session: could not create new audio track.") << endmsg;
1666 goto failed;
1669 catch (AudioEngine::PortRegistrationFailure& pfe) {
1671 error << pfe.what() << endmsg;
1672 goto failed;
1675 --how_many;
1678 failed:
1679 if (!new_routes.empty()) {
1680 add_routes (new_routes, true);
1683 return ret;
1686 void
1687 Session::set_remote_control_ids ()
1689 RemoteModel m = Config->get_remote_model();
1690 bool emit_signal = false;
1692 shared_ptr<RouteList> r = routes.reader ();
1694 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1695 if (MixerOrdered == m) {
1696 long order = (*i)->order_key(N_("signal"));
1697 (*i)->set_remote_control_id (order+1, false);
1698 emit_signal = true;
1699 } else if (EditorOrdered == m) {
1700 long order = (*i)->order_key(N_("editor"));
1701 (*i)->set_remote_control_id (order+1, false);
1702 emit_signal = true;
1703 } else if (UserOrdered == m) {
1704 //do nothing ... only changes to remote id's are initiated by user
1708 if (emit_signal) {
1709 Route::RemoteControlIDChange();
1714 RouteList
1715 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1717 char bus_name[32];
1718 uint32_t bus_id = 0;
1719 ChanCount existing_inputs;
1720 ChanCount existing_outputs;
1721 string port;
1722 RouteList ret;
1723 uint32_t control_id;
1725 count_existing_route_channels (existing_inputs, existing_outputs);
1727 control_id = ntracks() + nbusses() + 1;
1729 while (how_many) {
1730 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1731 error << "cannot find name for new audio bus" << endmsg;
1732 goto failure;
1735 try {
1736 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1738 if (rt->init ()) {
1739 delete rt;
1740 goto failure;
1743 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1744 shared_ptr<Route> bus (rt);
1746 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1747 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1748 input_channels, output_channels)
1749 << endmsg;
1750 goto failure;
1754 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1755 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1756 input_channels, output_channels)
1757 << endmsg;
1758 goto failure;
1761 auto_connect_route (bus, existing_inputs, existing_outputs, false);
1763 if (route_group) {
1764 route_group->add (bus);
1766 bus->set_remote_control_id (control_id);
1767 ++control_id;
1769 if (aux) {
1770 bus->add_internal_return ();
1773 ret.push_back (bus);
1777 catch (failed_constructor &err) {
1778 error << _("Session: could not create new audio route.") << endmsg;
1779 goto failure;
1782 catch (AudioEngine::PortRegistrationFailure& pfe) {
1783 error << pfe.what() << endmsg;
1784 goto failure;
1788 --how_many;
1791 failure:
1792 if (!ret.empty()) {
1793 add_routes (ret, true);
1796 return ret;
1800 RouteList
1801 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1803 char name[32];
1804 RouteList ret;
1805 uint32_t control_id;
1806 XMLTree tree;
1807 uint32_t number = 0;
1809 if (!tree.read (template_path.c_str())) {
1810 return ret;
1813 XMLNode* node = tree.root();
1815 control_id = ntracks() + nbusses() + 1;
1817 while (how_many) {
1819 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1821 std::string node_name = IO::name_from_state (*node_copy.children().front());
1823 /* generate a new name by adding a number to the end of the template name */
1824 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1825 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1826 /*NOTREACHED*/
1829 /* set IO children to use the new name */
1830 XMLNodeList const & children = node_copy.children ();
1831 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1832 if ((*i)->name() == IO::state_node_name) {
1833 IO::set_name_in_state (**i, name);
1837 Track::zero_diskstream_id_in_xml (node_copy);
1839 try {
1840 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1842 if (route == 0) {
1843 error << _("Session: cannot create track/bus from template description") << endmsg;
1844 goto out;
1847 if (boost::dynamic_pointer_cast<Track>(route)) {
1848 /* force input/output change signals so that the new diskstream
1849 picks up the configuration of the route. During session
1850 loading this normally happens in a different way.
1852 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
1853 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
1856 route->set_remote_control_id (control_id);
1857 ++control_id;
1859 ret.push_back (route);
1862 catch (failed_constructor &err) {
1863 error << _("Session: could not create new route from template") << endmsg;
1864 goto out;
1867 catch (AudioEngine::PortRegistrationFailure& pfe) {
1868 error << pfe.what() << endmsg;
1869 goto out;
1872 --how_many;
1875 out:
1876 if (!ret.empty()) {
1877 add_routes (ret, true);
1880 return ret;
1883 void
1884 Session::add_routes (RouteList& new_routes, bool save)
1887 RCUWriter<RouteList> writer (routes);
1888 shared_ptr<RouteList> r = writer.get_copy ();
1889 r->insert (r->end(), new_routes.begin(), new_routes.end());
1892 /* if there is no control out and we're not in the middle of loading,
1893 resort the graph here. if there is a control out, we will resort
1894 toward the end of this method. if we are in the middle of loading,
1895 we will resort when done.
1898 if (!_monitor_out && IO::connecting_legal) {
1899 resort_routes_using (r);
1903 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1905 boost::weak_ptr<Route> wpr (*x);
1906 boost::shared_ptr<Route> r (*x);
1908 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1909 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1910 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1911 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1912 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1913 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1914 r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
1916 if (r->is_master()) {
1917 _master_out = r;
1920 if (r->is_monitor()) {
1921 _monitor_out = r;
1924 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1925 if (tr) {
1926 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1927 track_playlist_changed (boost::weak_ptr<Track> (tr));
1928 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1932 if (_monitor_out && IO::connecting_legal) {
1934 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1935 if ((*x)->is_monitor()) {
1936 /* relax */
1937 } else if ((*x)->is_master()) {
1938 /* relax */
1939 } else {
1940 (*x)->listen_via (_monitor_out,
1941 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
1942 false, false);
1946 resort_routes ();
1949 set_dirty();
1951 if (save) {
1952 save_state (_current_snapshot_name);
1955 RouteAdded (new_routes); /* EMIT SIGNAL */
1956 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
1959 void
1960 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
1962 boost::shared_ptr<RouteList> r = routes.reader ();
1963 boost::shared_ptr<Send> s;
1965 /* only tracks */
1967 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1968 if (boost::dynamic_pointer_cast<Track>(*i)) {
1969 if ((s = (*i)->internal_send_for (dest)) != 0) {
1970 s->amp()->gain_control()->set_value (0.0);
1976 void
1977 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
1979 boost::shared_ptr<RouteList> r = routes.reader ();
1980 boost::shared_ptr<Send> s;
1982 /* only tracks */
1984 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1985 if (boost::dynamic_pointer_cast<Track>(*i)) {
1986 if ((s = (*i)->internal_send_for (dest)) != 0) {
1987 s->amp()->gain_control()->set_value (1.0);
1993 void
1994 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
1996 boost::shared_ptr<RouteList> r = routes.reader ();
1997 boost::shared_ptr<Send> s;
1999 /* only tracks */
2001 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2002 if (boost::dynamic_pointer_cast<Track>(*i)) {
2003 if ((s = (*i)->internal_send_for (dest)) != 0) {
2004 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2010 void
2011 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2013 boost::shared_ptr<RouteList> r = routes.reader ();
2014 boost::shared_ptr<RouteList> t (new RouteList);
2016 /* only send tracks */
2018 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2019 if (boost::dynamic_pointer_cast<Track>(*i)) {
2020 t->push_back (*i);
2024 add_internal_sends (dest, p, t);
2027 void
2028 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2030 if (dest->is_monitor() || dest->is_master()) {
2031 return;
2034 if (!dest->internal_return()) {
2035 dest->add_internal_return();
2038 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2040 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2041 continue;
2044 (*i)->listen_via (dest, p, true, true);
2047 graph_reordered ();
2050 void
2051 Session::remove_route (shared_ptr<Route> route)
2053 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2054 return;
2058 RCUWriter<RouteList> writer (routes);
2059 shared_ptr<RouteList> rs = writer.get_copy ();
2061 rs->remove (route);
2063 /* deleting the master out seems like a dumb
2064 idea, but its more of a UI policy issue
2065 than our concern.
2068 if (route == _master_out) {
2069 _master_out = shared_ptr<Route> ();
2072 if (route == _monitor_out) {
2074 /* cancel control outs for all routes */
2076 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2077 (*r)->drop_listen (_monitor_out);
2080 _monitor_out.reset ();
2083 /* writer goes out of scope, forces route list update */
2086 update_route_solo_state ();
2087 update_session_range_location_marker ();
2089 // We need to disconnect the route's inputs and outputs
2091 route->input()->disconnect (0);
2092 route->output()->disconnect (0);
2094 /* if the route had internal sends sending to it, remove them */
2095 if (route->internal_return()) {
2097 boost::shared_ptr<RouteList> r = routes.reader ();
2098 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2099 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2100 if (s) {
2101 (*i)->remove_processor (s);
2106 update_latency_compensation (false, false);
2107 set_dirty();
2109 /* Re-sort routes to remove the graph's current references to the one that is
2110 * going away, then flush old references out of the graph.
2113 resort_routes ();
2114 route_graph->clear_other_chain ();
2116 /* get rid of it from the dead wood collection in the route list manager */
2118 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2120 routes.flush ();
2122 /* try to cause everyone to drop their references */
2124 route->drop_references ();
2126 sync_order_keys (N_("session"));
2128 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2130 /* save the new state of the world */
2132 if (save_state (_current_snapshot_name)) {
2133 save_history (_current_snapshot_name);
2137 void
2138 Session::route_mute_changed (void* /*src*/)
2140 set_dirty ();
2143 void
2144 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2146 boost::shared_ptr<Route> route = wpr.lock();
2147 if (!route) {
2148 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2149 return;
2152 if (route->listening()) {
2154 if (Config->get_exclusive_solo()) {
2155 /* new listen: disable all other listen */
2156 shared_ptr<RouteList> r = routes.reader ();
2157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2158 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2159 continue;
2161 (*i)->set_listen (false, this);
2165 _listen_cnt++;
2167 } else if (_listen_cnt > 0) {
2169 _listen_cnt--;
2172 void
2173 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2175 boost::shared_ptr<Route> route = wpr.lock ();
2177 if (!route) {
2178 /* should not happen */
2179 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2180 return;
2183 bool send_changed = false;
2185 if (route->solo_isolated()) {
2186 if (_solo_isolated_cnt == 0) {
2187 send_changed = true;
2189 _solo_isolated_cnt++;
2190 } else if (_solo_isolated_cnt > 0) {
2191 _solo_isolated_cnt--;
2192 if (_solo_isolated_cnt == 0) {
2193 send_changed = true;
2197 if (send_changed) {
2198 IsolatedChanged (); /* EMIT SIGNAL */
2202 void
2203 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2205 if (!self_solo_change) {
2206 // session doesn't care about changes to soloed-by-others
2207 return;
2210 if (solo_update_disabled) {
2211 // We know already
2212 return;
2215 boost::shared_ptr<Route> route = wpr.lock ();
2217 if (!route) {
2218 /* should not happen */
2219 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2220 return;
2223 shared_ptr<RouteList> r = routes.reader ();
2224 int32_t delta;
2226 if (route->self_soloed()) {
2227 delta = 1;
2228 } else {
2229 delta = -1;
2232 if (delta == 1 && Config->get_exclusive_solo()) {
2233 /* new solo: disable all other solos */
2234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2235 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2236 continue;
2238 (*i)->set_solo (false, this);
2242 solo_update_disabled = true;
2244 RouteList uninvolved;
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 bool via_sends_only;
2248 bool in_signal_flow;
2250 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2251 continue;
2254 in_signal_flow = false;
2256 if ((*i)->feeds (route, &via_sends_only)) {
2257 if (!via_sends_only) {
2258 if (!route->soloed_by_others_upstream()) {
2259 (*i)->mod_solo_by_others_downstream (delta);
2261 in_signal_flow = true;
2265 if (route->feeds (*i, &via_sends_only)) {
2266 (*i)->mod_solo_by_others_upstream (delta);
2267 in_signal_flow = true;
2270 if (!in_signal_flow) {
2271 uninvolved.push_back (*i);
2275 solo_update_disabled = false;
2276 update_route_solo_state (r);
2278 /* now notify that the mute state of the routes not involved in the signal
2279 pathway of the just-solo-changed route may have altered.
2282 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2283 (*i)->mute_changed (this);
2286 SoloChanged (); /* EMIT SIGNAL */
2287 set_dirty();
2290 void
2291 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2293 /* now figure out if anything that matters is soloed (or is "listening")*/
2295 bool something_soloed = false;
2296 uint32_t listeners = 0;
2297 uint32_t isolated = 0;
2299 if (!r) {
2300 r = routes.reader();
2303 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2304 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2305 something_soloed = true;
2308 if (!(*i)->is_hidden() && (*i)->listening()) {
2309 if (Config->get_solo_control_is_listen_control()) {
2310 listeners++;
2311 } else {
2312 (*i)->set_listen (false, this);
2316 if ((*i)->solo_isolated()) {
2317 isolated++;
2321 if (something_soloed != _non_soloed_outs_muted) {
2322 _non_soloed_outs_muted = something_soloed;
2323 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2326 _listen_cnt = listeners;
2328 if (isolated != _solo_isolated_cnt) {
2329 _solo_isolated_cnt = isolated;
2330 IsolatedChanged (); /* EMIT SIGNAL */
2334 boost::shared_ptr<RouteList>
2335 Session::get_routes_with_internal_returns() const
2337 shared_ptr<RouteList> r = routes.reader ();
2338 boost::shared_ptr<RouteList> rl (new RouteList);
2340 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2341 if ((*i)->internal_return ()) {
2342 rl->push_back (*i);
2345 return rl;
2348 bool
2349 Session::io_name_is_legal (const std::string& name)
2351 shared_ptr<RouteList> r = routes.reader ();
2353 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2354 if ((*i)->name() == name) {
2355 return false;
2358 if ((*i)->has_io_processor_named (name)) {
2359 return false;
2363 return true;
2366 shared_ptr<Route>
2367 Session::route_by_name (string name)
2369 shared_ptr<RouteList> r = routes.reader ();
2371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2372 if ((*i)->name() == name) {
2373 return *i;
2377 return shared_ptr<Route> ((Route*) 0);
2380 shared_ptr<Route>
2381 Session::route_by_id (PBD::ID id)
2383 shared_ptr<RouteList> r = routes.reader ();
2385 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2386 if ((*i)->id() == id) {
2387 return *i;
2391 return shared_ptr<Route> ((Route*) 0);
2394 shared_ptr<Route>
2395 Session::route_by_remote_id (uint32_t id)
2397 shared_ptr<RouteList> r = routes.reader ();
2399 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2400 if ((*i)->remote_control_id() == id) {
2401 return *i;
2405 return shared_ptr<Route> ((Route*) 0);
2408 /** If either end of the session range location marker lies inside the current
2409 * session extent, move it to the corresponding session extent.
2411 void
2412 Session::update_session_range_location_marker ()
2414 if (_state_of_the_state & Loading) {
2415 return;
2418 pair<nframes_t, nframes_t> const ext = get_extent ();
2420 if (_session_range_location == 0) {
2421 /* we don't have a session range yet; use this one (provided it is valid) */
2422 if (ext.first != max_frames) {
2423 add_session_range_location (ext.first, ext.second);
2425 } else {
2426 /* update the existing session range */
2427 if (ext.first < _session_range_location->start()) {
2428 _session_range_location->set_start (ext.first);
2429 set_dirty ();
2432 if (ext.second > _session_range_location->end()) {
2433 _session_range_location->set_end (ext.second);
2434 set_dirty ();
2440 /** @return Extent of the session's contents; if the session is empty, the first value of
2441 * the pair will equal max_frames.
2443 pair<nframes_t, nframes_t>
2444 Session::get_extent () const
2446 pair<nframes_t, nframes_t> ext (max_frames, 0);
2448 boost::shared_ptr<RouteList> rl = routes.reader ();
2449 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2450 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2451 if (!tr || tr->destructive()) {
2452 // ignore tape tracks when getting extents
2453 continue;
2456 pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
2457 if (e.first < ext.first) {
2458 ext.first = e.first;
2460 if (e.second > ext.second) {
2461 ext.second = e.second;
2465 return ext;
2468 /* Region management */
2470 boost::shared_ptr<Region>
2471 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2473 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2474 RegionFactory::RegionMap::const_iterator i;
2475 boost::shared_ptr<Region> region;
2477 Glib::Mutex::Lock lm (region_lock);
2479 for (i = regions.begin(); i != regions.end(); ++i) {
2481 region = i->second;
2483 if (region->whole_file()) {
2485 if (child->source_equivalent (region)) {
2486 return region;
2491 return boost::shared_ptr<Region> ();
2495 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2497 set<boost::shared_ptr<Region> > relevant_regions;
2499 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2500 RegionFactory::get_regions_using_source (*s, relevant_regions);
2503 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2505 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2506 set<boost::shared_ptr<Region> >::iterator tmp;
2508 tmp = r;
2509 ++tmp;
2511 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2513 playlists->destroy_region (*r);
2514 RegionFactory::map_remove (*r);
2516 (*r)->drop_sources ();
2517 (*r)->drop_references ();
2519 cerr << "\tdone UC = " << (*r).use_count() << endl;
2521 relevant_regions.erase (r);
2523 r = tmp;
2526 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2529 Glib::Mutex::Lock ls (source_lock);
2530 /* remove from the main source list */
2531 sources.erase ((*s)->id());
2534 (*s)->mark_for_remove ();
2535 (*s)->drop_references ();
2537 s = srcs.erase (s);
2540 return 0;
2544 Session::remove_last_capture ()
2546 list<boost::shared_ptr<Source> > srcs;
2548 boost::shared_ptr<RouteList> rl = routes.reader ();
2549 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2550 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2551 if (!tr) {
2552 continue;
2555 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2557 if (!l.empty()) {
2558 srcs.insert (srcs.end(), l.begin(), l.end());
2559 l.clear ();
2563 destroy_sources (srcs);
2565 save_state (_current_snapshot_name);
2567 return 0;
2570 /* Source Management */
2572 void
2573 Session::add_source (boost::shared_ptr<Source> source)
2575 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2576 pair<SourceMap::iterator,bool> result;
2578 entry.first = source->id();
2579 entry.second = source;
2582 Glib::Mutex::Lock lm (source_lock);
2583 result = sources.insert (entry);
2586 if (result.second) {
2588 /* yay, new source */
2590 set_dirty();
2592 boost::shared_ptr<AudioFileSource> afs;
2594 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2595 if (Config->get_auto_analyse_audio()) {
2596 Analyser::queue_source_for_analysis (source, false);
2602 void
2603 Session::remove_source (boost::weak_ptr<Source> src)
2605 SourceMap::iterator i;
2606 boost::shared_ptr<Source> source = src.lock();
2608 if (!source) {
2609 return;
2613 Glib::Mutex::Lock lm (source_lock);
2615 if ((i = sources.find (source->id())) != sources.end()) {
2616 cerr << "Removing source " << source->name() << endl;
2617 sources.erase (i);
2621 if (!_state_of_the_state & InCleanup) {
2623 /* save state so we don't end up with a session file
2624 referring to non-existent sources.
2627 save_state (_current_snapshot_name);
2631 boost::shared_ptr<Source>
2632 Session::source_by_id (const PBD::ID& id)
2634 Glib::Mutex::Lock lm (source_lock);
2635 SourceMap::iterator i;
2636 boost::shared_ptr<Source> source;
2638 if ((i = sources.find (id)) != sources.end()) {
2639 source = i->second;
2642 return source;
2645 boost::shared_ptr<Source>
2646 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2648 Glib::Mutex::Lock lm (source_lock);
2650 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2651 boost::shared_ptr<AudioFileSource> afs
2652 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2654 if (afs && afs->path() == path && chn == afs->channel()) {
2655 return afs;
2658 return boost::shared_ptr<Source>();
2662 string
2663 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2665 string look_for;
2666 string old_basename = PBD::basename_nosuffix (oldname);
2667 string new_legalized = legalize_for_path (newname);
2669 /* note: we know (or assume) the old path is already valid */
2671 if (destructive) {
2673 /* destructive file sources have a name of the form:
2675 /path/to/Tnnnn-NAME(%[LR])?.wav
2677 the task here is to replace NAME with the new name.
2680 string dir;
2681 string prefix;
2682 string::size_type dash;
2684 dir = Glib::path_get_dirname (path);
2685 path = Glib::path_get_basename (path);
2687 /* '-' is not a legal character for the NAME part of the path */
2689 if ((dash = path.find_last_of ('-')) == string::npos) {
2690 return "";
2693 prefix = path.substr (0, dash);
2695 path += prefix;
2696 path += '-';
2697 path += new_legalized;
2698 path += ".wav"; /* XXX gag me with a spoon */
2700 path = Glib::build_filename (dir, path);
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 dash;
2714 string::size_type postfix;
2716 dir = Glib::path_get_dirname (path);
2717 path = Glib::path_get_basename (path);
2719 /* '-' is not a legal character for the NAME part of the path */
2721 if ((dash = path.find_last_of ('-')) == string::npos) {
2722 return "";
2725 suffix = path.substr (dash+1);
2727 // Suffix is now everything after the dash. Now we need to eliminate
2728 // the nnnnn part, which is done by either finding a '%' or a '.'
2730 postfix = suffix.find_last_of ("%");
2731 if (postfix == string::npos) {
2732 postfix = suffix.find_last_of ('.');
2735 if (postfix != string::npos) {
2736 suffix = suffix.substr (postfix);
2737 } else {
2738 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2739 return "";
2742 const uint32_t limit = 10000;
2743 char buf[PATH_MAX+1];
2745 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2747 snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
2749 string p = Glib::build_filename (dir, buf);
2751 if (!Glib::file_test (p, Glib::FILE_TEST_EXISTS)) {
2752 path = p;
2753 break;
2755 path = "";
2758 if (path == "") {
2759 error << "FATAL ERROR! Could not find a " << endl;
2763 return path;
2766 /** Return the full path (in some session directory) for a new within-session source.
2767 * \a name must be a session-unique name that does not contain slashes
2768 * (e.g. as returned by new_*_source_name)
2770 string
2771 Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
2773 assert(name.find("/") == string::npos);
2775 SessionDirectory sdir(get_best_session_directory_for_new_source());
2777 sys::path p;
2778 if (type == DataType::AUDIO) {
2779 p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
2780 } else if (type == DataType::MIDI) {
2781 p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
2782 } else {
2783 error << "Unknown source type, unable to create file path" << endmsg;
2784 return "";
2787 p /= name;
2788 return p.to_string();
2791 Glib::ustring
2792 Session::peak_path (Glib::ustring base) const
2794 sys::path peakfile_path(_session_dir->peak_path());
2795 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2796 return peakfile_path.to_string();
2799 /** Return a unique name based on \a base for a new internal audio source */
2800 string
2801 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2803 string spath;
2804 uint32_t cnt;
2805 char buf[PATH_MAX+1];
2806 const uint32_t limit = 10000;
2807 string legalized;
2809 buf[0] = '\0';
2810 legalized = legalize_for_path (base);
2812 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2813 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2815 vector<space_and_path>::iterator i;
2816 uint32_t existing = 0;
2818 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2820 SessionDirectory sdir((*i).path);
2822 spath = sdir.sound_path().to_string();
2824 if (destructive) {
2826 if (nchan < 2) {
2827 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
2828 spath.c_str(), cnt, legalized.c_str());
2829 } else if (nchan == 2) {
2830 if (chan == 0) {
2831 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
2832 spath.c_str(), cnt, legalized.c_str());
2833 } else {
2834 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
2835 spath.c_str(), cnt, legalized.c_str());
2837 } else if (nchan < 26) {
2838 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
2839 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2840 } else {
2841 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
2842 spath.c_str(), cnt, legalized.c_str());
2845 } else {
2847 spath += '/';
2848 spath += legalized;
2850 if (nchan < 2) {
2851 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2852 } else if (nchan == 2) {
2853 if (chan == 0) {
2854 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2855 } else {
2856 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2858 } else if (nchan < 26) {
2859 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2860 } else {
2861 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2865 if (sys::exists(buf)) {
2866 existing++;
2871 if (existing == 0) {
2872 break;
2875 if (cnt > limit) {
2876 error << string_compose(
2877 _("There are already %1 recordings for %2, which I consider too many."),
2878 limit, base) << endmsg;
2879 destroy ();
2880 throw failed_constructor();
2884 return Glib::path_get_basename(buf);
2887 /** Create a new within-session audio source */
2888 boost::shared_ptr<AudioFileSource>
2889 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
2891 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2892 const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
2894 return boost::dynamic_pointer_cast<AudioFileSource> (
2895 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
2898 /** Return a unique name based on \a base for a new internal MIDI source */
2899 string
2900 Session::new_midi_source_name (const string& base)
2902 uint32_t cnt;
2903 char buf[PATH_MAX+1];
2904 const uint32_t limit = 10000;
2905 string legalized;
2907 buf[0] = '\0';
2908 legalized = legalize_for_path (base);
2910 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2911 for (cnt = 1; cnt <= limit; ++cnt) {
2913 vector<space_and_path>::iterator i;
2914 uint32_t existing = 0;
2916 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2918 SessionDirectory sdir((*i).path);
2920 sys::path p = sdir.midi_path();
2921 p /= legalized;
2923 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
2925 if (sys::exists (buf)) {
2926 existing++;
2930 if (existing == 0) {
2931 break;
2934 if (cnt > limit) {
2935 error << string_compose(
2936 _("There are already %1 recordings for %2, which I consider too many."),
2937 limit, base) << endmsg;
2938 destroy ();
2939 throw failed_constructor();
2943 return Glib::path_get_basename(buf);
2947 /** Create a new within-session MIDI source */
2948 boost::shared_ptr<MidiSource>
2949 Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
2951 /* try to use the existing write source for the track, to keep numbering sane
2954 if (track) {
2955 /*MidiTrack* mt = dynamic_cast<Track*> (track);
2956 assert (mt);
2959 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
2961 if (!l.empty()) {
2962 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
2963 return boost::dynamic_pointer_cast<MidiSource> (l.front());
2967 const string name = new_midi_source_name (n);
2968 const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
2970 return boost::dynamic_pointer_cast<SMFSource> (
2971 SourceFactory::createWritable (
2972 DataType::MIDI, *this, path, false, frame_rate()));
2976 void
2977 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
2979 if (playlist->hidden()) {
2980 return;
2983 playlists->add (playlist);
2985 if (unused) {
2986 playlist->release();
2989 set_dirty();
2992 void
2993 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
2995 if (_state_of_the_state & Deletion) {
2996 return;
2999 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3001 if (!playlist) {
3002 return;
3005 playlists->remove (playlist);
3007 set_dirty();
3010 void
3011 Session::set_audition (boost::shared_ptr<Region> r)
3013 pending_audition_region = r;
3014 add_post_transport_work (PostTransportAudition);
3015 _butler->schedule_transport_work ();
3018 void
3019 Session::audition_playlist ()
3021 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3022 ev->region.reset ();
3023 queue_event (ev);
3026 void
3027 Session::non_realtime_set_audition ()
3029 if (!pending_audition_region) {
3030 auditioner->audition_current_playlist ();
3031 } else {
3032 auditioner->audition_region (pending_audition_region);
3033 pending_audition_region.reset ();
3035 AuditionActive (true); /* EMIT SIGNAL */
3038 void
3039 Session::audition_region (boost::shared_ptr<Region> r)
3041 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3042 ev->region = r;
3043 queue_event (ev);
3046 void
3047 Session::cancel_audition ()
3049 if (auditioner->auditioning()) {
3050 auditioner->cancel_audition ();
3051 AuditionActive (false); /* EMIT SIGNAL */
3055 bool
3056 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3058 if (a->is_monitor()) {
3059 return true;
3061 if (b->is_monitor()) {
3062 return false;
3064 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3067 bool
3068 Session::is_auditioning () const
3070 /* can be called before we have an auditioner object */
3071 if (auditioner) {
3072 return auditioner->auditioning();
3073 } else {
3074 return false;
3078 void
3079 Session::graph_reordered ()
3081 /* don't do this stuff if we are setting up connections
3082 from a set_state() call or creating new tracks. Ditto for deletion.
3085 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3086 return;
3089 /* every track/bus asked for this to be handled but it was deferred because
3090 we were connecting. do it now.
3093 request_input_change_handling ();
3095 resort_routes ();
3097 /* force all diskstreams to update their capture offset values to
3098 reflect any changes in latencies within the graph.
3101 boost::shared_ptr<RouteList> rl = routes.reader ();
3102 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3103 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3104 if (tr) {
3105 tr->set_capture_offset ();
3110 nframes_t
3111 Session::available_capture_duration ()
3113 float sample_bytes_on_disk = 4.0; // keep gcc happy
3115 switch (config.get_native_file_data_format()) {
3116 case FormatFloat:
3117 sample_bytes_on_disk = 4.0;
3118 break;
3120 case FormatInt24:
3121 sample_bytes_on_disk = 3.0;
3122 break;
3124 case FormatInt16:
3125 sample_bytes_on_disk = 2.0;
3126 break;
3128 default:
3129 /* impossible, but keep some gcc versions happy */
3130 fatal << string_compose (_("programming error: %1"),
3131 X_("illegal native file data format"))
3132 << endmsg;
3133 /*NOTREACHED*/
3136 double scale = 4096.0 / sample_bytes_on_disk;
3138 if (_total_free_4k_blocks * scale > (double) max_frames) {
3139 return max_frames;
3142 return (nframes_t) floor (_total_free_4k_blocks * scale);
3145 void
3146 Session::add_bundle (shared_ptr<Bundle> bundle)
3149 RCUWriter<BundleList> writer (_bundles);
3150 boost::shared_ptr<BundleList> b = writer.get_copy ();
3151 b->push_back (bundle);
3154 BundleAdded (bundle); /* EMIT SIGNAL */
3156 set_dirty();
3159 void
3160 Session::remove_bundle (shared_ptr<Bundle> bundle)
3162 bool removed = false;
3165 RCUWriter<BundleList> writer (_bundles);
3166 boost::shared_ptr<BundleList> b = writer.get_copy ();
3167 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3169 if (i != b->end()) {
3170 b->erase (i);
3171 removed = true;
3175 if (removed) {
3176 BundleRemoved (bundle); /* EMIT SIGNAL */
3179 set_dirty();
3182 shared_ptr<Bundle>
3183 Session::bundle_by_name (string name) const
3185 boost::shared_ptr<BundleList> b = _bundles.reader ();
3187 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3188 if ((*i)->name() == name) {
3189 return* i;
3193 return boost::shared_ptr<Bundle> ();
3196 void
3197 Session::tempo_map_changed (const PropertyChange&)
3199 clear_clicks ();
3201 playlists->update_after_tempo_map_change ();
3203 set_dirty ();
3206 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3207 * the given count with the current block size.
3209 void
3210 Session::ensure_buffers (ChanCount howmany)
3212 BufferManager::ensure_buffers (howmany);
3215 void
3216 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3218 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3219 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3223 uint32_t
3224 Session::next_insert_id ()
3226 /* this doesn't really loop forever. just think about it */
3228 while (true) {
3229 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3230 if (!insert_bitset[n]) {
3231 insert_bitset[n] = true;
3232 return n;
3237 /* none available, so resize and try again */
3239 insert_bitset.resize (insert_bitset.size() + 16, false);
3243 uint32_t
3244 Session::next_send_id ()
3246 /* this doesn't really loop forever. just think about it */
3248 while (true) {
3249 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3250 if (!send_bitset[n]) {
3251 send_bitset[n] = true;
3252 return n;
3257 /* none available, so resize and try again */
3259 send_bitset.resize (send_bitset.size() + 16, false);
3263 uint32_t
3264 Session::next_return_id ()
3266 /* this doesn't really loop forever. just think about it */
3268 while (true) {
3269 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3270 if (!return_bitset[n]) {
3271 return_bitset[n] = true;
3272 return n;
3277 /* none available, so resize and try again */
3279 return_bitset.resize (return_bitset.size() + 16, false);
3283 void
3284 Session::mark_send_id (uint32_t id)
3286 if (id >= send_bitset.size()) {
3287 send_bitset.resize (id+16, false);
3289 if (send_bitset[id]) {
3290 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3292 send_bitset[id] = true;
3295 void
3296 Session::mark_return_id (uint32_t id)
3298 if (id >= return_bitset.size()) {
3299 return_bitset.resize (id+16, false);
3301 if (return_bitset[id]) {
3302 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3304 return_bitset[id] = true;
3307 void
3308 Session::mark_insert_id (uint32_t id)
3310 if (id >= insert_bitset.size()) {
3311 insert_bitset.resize (id+16, false);
3313 if (insert_bitset[id]) {
3314 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3316 insert_bitset[id] = true;
3319 void
3320 Session::unmark_send_id (uint32_t id)
3322 if (id < send_bitset.size()) {
3323 send_bitset[id] = false;
3327 void
3328 Session::unmark_return_id (uint32_t id)
3330 if (id < return_bitset.size()) {
3331 return_bitset[id] = false;
3335 void
3336 Session::unmark_insert_id (uint32_t id)
3338 if (id < insert_bitset.size()) {
3339 insert_bitset[id] = false;
3344 /* Named Selection management */
3346 boost::shared_ptr<NamedSelection>
3347 Session::named_selection_by_name (string name)
3349 Glib::Mutex::Lock lm (named_selection_lock);
3350 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3351 if ((*i)->name == name) {
3352 return *i;
3355 return boost::shared_ptr<NamedSelection>();
3358 void
3359 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3362 Glib::Mutex::Lock lm (named_selection_lock);
3363 named_selections.insert (named_selections.begin(), named_selection);
3366 set_dirty();
3368 NamedSelectionAdded (); /* EMIT SIGNAL */
3371 void
3372 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3374 bool removed = false;
3377 Glib::Mutex::Lock lm (named_selection_lock);
3379 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3381 if (i != named_selections.end()) {
3382 named_selections.erase (i);
3383 set_dirty();
3384 removed = true;
3388 if (removed) {
3389 NamedSelectionRemoved (); /* EMIT SIGNAL */
3393 void
3394 Session::reset_native_file_format ()
3396 boost::shared_ptr<RouteList> rl = routes.reader ();
3397 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3398 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3399 if (tr) {
3400 tr->reset_write_sources (false);
3405 bool
3406 Session::route_name_unique (string n) const
3408 shared_ptr<RouteList> r = routes.reader ();
3410 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3411 if ((*i)->name() == n) {
3412 return false;
3416 return true;
3419 bool
3420 Session::route_name_internal (string n) const
3422 if (auditioner && auditioner->name() == n) {
3423 return true;
3426 if (_click_io && _click_io->name() == n) {
3427 return true;
3430 return false;
3434 Session::freeze_all (InterThreadInfo& itt)
3436 shared_ptr<RouteList> r = routes.reader ();
3438 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3440 boost::shared_ptr<Track> t;
3442 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3443 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3444 of every track.
3446 t->freeze_me (itt);
3450 return 0;
3453 boost::shared_ptr<Region>
3454 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3455 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3456 InterThreadInfo& itt, bool enable_processing)
3458 boost::shared_ptr<Region> result;
3459 boost::shared_ptr<Playlist> playlist;
3460 boost::shared_ptr<AudioFileSource> fsource;
3461 uint32_t x;
3462 char buf[PATH_MAX+1];
3463 ChanCount nchans(track.n_channels());
3464 nframes_t position;
3465 nframes_t this_chunk;
3466 nframes_t to_do;
3467 BufferSet buffers;
3468 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3469 const string sound_dir = sdir.sound_path().to_string();
3470 nframes_t len = end - start;
3472 if (end <= start) {
3473 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3474 end, start) << endmsg;
3475 return result;
3478 const nframes_t chunk_size = (256 * 1024)/4;
3480 // block all process callback handling
3482 block_processing ();
3484 /* call tree *MUST* hold route_lock */
3486 if ((playlist = track.playlist()) == 0) {
3487 goto out;
3490 /* external redirects will be a problem */
3492 if (track.has_external_redirects()) {
3493 goto out;
3496 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3498 for (x = 0; x < 99999; ++x) {
3499 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3500 if (access (buf, F_OK) != 0) {
3501 break;
3505 if (x == 99999) {
3506 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3507 goto out;
3510 try {
3511 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3512 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3515 catch (failed_constructor& err) {
3516 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3517 goto out;
3520 srcs.push_back (fsource);
3523 /* XXX need to flush all redirects */
3525 position = start;
3526 to_do = len;
3528 /* create a set of reasonably-sized buffers */
3529 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3530 buffers.set_count(nchans);
3532 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3533 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3534 if (afs)
3535 afs->prepare_for_peakfile_writes ();
3538 while (to_do && !itt.cancel) {
3540 this_chunk = min (to_do, chunk_size);
3542 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3543 goto out;
3546 uint32_t n = 0;
3547 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3548 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3550 if (afs) {
3551 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3552 goto out;
3557 start += this_chunk;
3558 to_do -= this_chunk;
3560 itt.progress = (float) (1.0 - ((double) to_do / len));
3564 if (!itt.cancel) {
3566 time_t now;
3567 struct tm* xnow;
3568 time (&now);
3569 xnow = localtime (&now);
3571 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3572 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3574 if (afs) {
3575 afs->update_header (position, *xnow, now);
3576 afs->flush_header ();
3580 /* construct a region to represent the bounced material */
3582 PropertyList plist;
3584 plist.add (Properties::start, 0);
3585 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3586 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3588 result = RegionFactory::create (srcs, plist);
3592 out:
3593 if (!result) {
3594 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3595 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3597 if (afs) {
3598 afs->mark_for_remove ();
3601 (*src)->drop_references ();
3604 } else {
3605 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3606 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3608 if (afs)
3609 afs->done_with_peakfile_writes ();
3613 unblock_processing ();
3615 return result;
3618 gain_t*
3619 Session::gain_automation_buffer() const
3621 return ProcessThread::gain_automation_buffer ();
3624 pan_t**
3625 Session::pan_automation_buffer() const
3627 return ProcessThread::pan_automation_buffer ();
3630 BufferSet&
3631 Session::get_silent_buffers (ChanCount count)
3633 return ProcessThread::get_silent_buffers (count);
3634 #if 0
3635 assert(_silent_buffers->available() >= count);
3636 _silent_buffers->set_count(count);
3638 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3639 for (size_t i= 0; i < count.get(*t); ++i) {
3640 _silent_buffers->get(*t, i).clear();
3644 return *_silent_buffers;
3645 #endif
3648 BufferSet&
3649 Session::get_scratch_buffers (ChanCount count)
3651 return ProcessThread::get_scratch_buffers (count);
3652 #if 0
3653 if (count != ChanCount::ZERO) {
3654 assert(_scratch_buffers->available() >= count);
3655 _scratch_buffers->set_count(count);
3656 } else {
3657 _scratch_buffers->set_count (_scratch_buffers->available());
3660 return *_scratch_buffers;
3661 #endif
3664 BufferSet&
3665 Session::get_mix_buffers (ChanCount count)
3667 return ProcessThread::get_mix_buffers (count);
3668 #if 0
3669 assert(_mix_buffers->available() >= count);
3670 _mix_buffers->set_count(count);
3671 return *_mix_buffers;
3672 #endif
3675 uint32_t
3676 Session::ntracks () const
3678 uint32_t n = 0;
3679 shared_ptr<RouteList> r = routes.reader ();
3681 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3682 if (boost::dynamic_pointer_cast<Track> (*i)) {
3683 ++n;
3687 return n;
3690 uint32_t
3691 Session::nbusses () const
3693 uint32_t n = 0;
3694 shared_ptr<RouteList> r = routes.reader ();
3696 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3697 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3698 ++n;
3702 return n;
3705 void
3706 Session::add_automation_list(AutomationList *al)
3708 automation_lists[al->id()] = al;
3711 void
3712 Session::sync_order_keys (std::string const & base)
3714 if (deletion_in_progress()) {
3715 return;
3718 if (!Config->get_sync_all_route_ordering()) {
3719 /* leave order keys as they are */
3720 return;
3723 boost::shared_ptr<RouteList> r = routes.reader ();
3725 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3726 (*i)->sync_order_keys (base);
3729 Route::SyncOrderKeys (base); // EMIT SIGNAL
3731 /* this might not do anything */
3733 set_remote_control_ids ();
3736 /** @return true if there is at least one record-enabled track, otherwise false */
3737 bool
3738 Session::have_rec_enabled_track () const
3740 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3743 /** Update the state of our rec-enabled tracks flag */
3744 void
3745 Session::update_have_rec_enabled_track ()
3747 boost::shared_ptr<RouteList> rl = routes.reader ();
3748 RouteList::iterator i = rl->begin();
3749 while (i != rl->end ()) {
3751 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3752 if (tr && tr->record_enabled ()) {
3753 break;
3756 ++i;
3759 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3761 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3763 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3764 RecordStateChanged (); /* EMIT SIGNAL */
3768 void
3769 Session::listen_position_changed ()
3771 Placement p;
3773 switch (Config->get_listen_position()) {
3774 case AfterFaderListen:
3775 p = PostFader;
3776 break;
3778 case PreFaderListen:
3779 p = PreFader;
3780 break;
3783 boost::shared_ptr<RouteList> r = routes.reader ();
3785 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3786 (*i)->put_monitor_send_at (p);
3790 void
3791 Session::solo_control_mode_changed ()
3793 /* cancel all solo or all listen when solo control mode changes */
3795 if (soloing()) {
3796 set_solo (get_routes(), false);
3797 } else if (listening()) {
3798 set_listen (get_routes(), false);
3802 /** Called when anything about any of our route groups changes (membership, state etc.) */
3803 void
3804 Session::route_group_changed ()
3806 RouteGroupChanged (); /* EMIT SIGNAL */
3809 vector<SyncSource>
3810 Session::get_available_sync_options () const
3812 vector<SyncSource> ret;
3814 ret.push_back (JACK);
3815 ret.push_back (MTC);
3816 ret.push_back (MIDIClock);
3818 return ret;
3821 boost::shared_ptr<RouteList>
3822 Session::get_routes_with_regions_at (nframes64_t const p) const
3824 shared_ptr<RouteList> r = routes.reader ();
3825 shared_ptr<RouteList> rl (new RouteList);
3827 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3828 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3829 if (!tr) {
3830 continue;
3833 boost::shared_ptr<Playlist> pl = tr->playlist ();
3834 if (!pl) {
3835 continue;
3838 if (pl->has_region_at (p)) {
3839 rl->push_back (*i);
3843 return rl;
3846 void
3847 Session::goto_end ()
3849 if (_session_range_location) {
3850 request_locate (_session_range_location->end(), false);
3851 } else {
3852 request_locate (0, false);
3856 void
3857 Session::goto_start ()
3859 if (_session_range_location) {
3860 request_locate (_session_range_location->start(), false);
3861 } else {
3862 request_locate (0, false);
3866 void
3867 Session::set_session_start (nframes_t start)
3869 if (_session_range_location) {
3870 _session_range_location->set_start (start);
3871 } else {
3872 add_session_range_location (start, start);
3876 void
3877 Session::set_session_end (nframes_t end)
3879 if (_session_range_location) {
3880 _session_range_location->set_end (end);
3881 } else {
3882 add_session_range_location (end, end);
3886 nframes_t
3887 Session::current_start_frame () const
3889 return _session_range_location ? _session_range_location->start() : 0;
3892 nframes_t
3893 Session::current_end_frame () const
3895 return _session_range_location ? _session_range_location->end() : 0;
3898 void
3899 Session::add_session_range_location (nframes_t start, nframes_t end)
3901 _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange);
3902 _locations.add (_session_range_location);
3905 /** Called when one of our routes' order keys has changed */
3906 void
3907 Session::route_order_key_changed ()
3909 RouteOrderKeyChanged (); /* EMIT SIGNAL */