beat slicing patch #1 from lincoln spiteri
[ardour2.git] / libs / ardour / session.cc
blob5e56b82e689b7dfa8990d2f1871009516421152b
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"
104 #include "i18n.h"
106 using namespace std;
107 using namespace ARDOUR;
108 using namespace PBD;
109 using boost::shared_ptr;
110 using boost::weak_ptr;
112 bool Session::_disable_all_loaded_plugins = false;
114 PBD::Signal1<void,std::string> Session::Dialog;
115 PBD::Signal0<int> Session::AskAboutPendingState;
116 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
117 PBD::Signal0<void> Session::SendFeedback;
119 PBD::Signal0<void> Session::TimecodeOffsetChanged;
120 PBD::Signal0<void> Session::StartTimeChanged;
121 PBD::Signal0<void> Session::EndTimeChanged;
122 PBD::Signal0<void> Session::AutoBindingOn;
123 PBD::Signal0<void> Session::AutoBindingOff;
124 PBD::Signal2<void,std::string, std::string> Session::Exported;
125 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
127 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
128 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
130 Session::Session (AudioEngine &eng,
131 const string& fullpath,
132 const string& snapshot_name,
133 BusProfile* bus_profile,
134 string mix_template)
136 : _engine (eng),
137 _target_transport_speed (0.0),
138 _requested_return_frame (-1),
139 _mmc (0),
140 _mtc_port (default_mtc_port),
141 _midi_port (default_midi_port),
142 _midi_clock_port (default_midi_clock_port),
143 _session_dir (new SessionDirectory(fullpath)),
144 state_tree (0),
145 _butler (new Butler (*this)),
146 _post_transport_work (0),
147 _send_timecode_update (false),
148 route_graph (new Graph(*this)),
149 routes (new RouteList),
150 _total_free_4k_blocks (0),
151 _bundles (new BundleList),
152 _bundle_xml_node (0),
153 _click_io ((IO*) 0),
154 click_data (0),
155 click_emphasis_data (0),
156 main_outs (0),
157 _metadata (new SessionMetadata()),
158 _have_rec_enabled_track (false)
161 playlists.reset (new SessionPlaylists);
163 interpolation.add_channel_to (0, 0);
165 if (!eng.connected()) {
166 throw failed_constructor();
169 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
170 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
172 first_stage_init (fullpath, snapshot_name);
174 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
176 if (_is_new) {
177 if (create (mix_template, bus_profile)) {
178 destroy ();
179 throw failed_constructor ();
183 if (second_stage_init ()) {
184 destroy ();
185 throw failed_constructor ();
188 store_recent_sessions(_name, _path);
190 bool was_dirty = dirty();
192 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
194 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
195 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
197 if (was_dirty) {
198 DirtyChanged (); /* EMIT SIGNAL */
201 _is_new = false;
204 Session::~Session ()
206 destroy ();
209 void
210 Session::destroy ()
212 vector<void*> debug_pointers;
214 /* if we got to here, leaving pending capture state around
215 is a mistake.
218 remove_pending_capture_state ();
220 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
222 _engine.remove_session ();
224 /* clear history so that no references to objects are held any more */
226 _history.clear ();
228 /* clear state tree so that no references to objects are held any more */
230 delete state_tree;
232 /* reset dynamic state version back to default */
234 Stateful::loading_state_version = 0;
236 _butler->drop_references ();
237 delete _butler;
238 delete midi_control_ui;
240 if (click_data != default_click) {
241 delete [] click_data;
244 if (click_emphasis_data != default_click_emphasis) {
245 delete [] click_emphasis_data;
248 clear_clicks ();
250 /* clear out any pending dead wood from RCU managed objects */
252 routes.flush ();
253 _bundles.flush ();
255 AudioDiskstream::free_working_buffers();
257 /* tell everyone who is still standing that we're about to die */
258 drop_references ();
260 /* tell everyone to drop references and delete objects as we go */
262 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
263 named_selections.clear ();
265 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
266 RegionFactory::delete_all_regions ();
268 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
270 /* reset these three references to special routes before we do the usual route delete thing */
272 auditioner.reset ();
273 _master_out.reset ();
274 _monitor_out.reset ();
277 RCUWriter<RouteList> writer (routes);
278 boost::shared_ptr<RouteList> r = writer.get_copy ();
280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
281 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
282 (*i)->drop_references ();
285 r->clear ();
286 /* writer goes out of scope and updates master */
288 routes.flush ();
290 boost::shared_ptr<RouteList> r = routes.reader ();
292 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
293 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
294 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
295 i->second->drop_references ();
298 sources.clear ();
300 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
301 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
303 delete *i;
306 Crossfade::set_buffer_size (0);
308 delete _mmc;
310 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
311 playlists.reset ();
313 boost_debug_list_ptrs ();
315 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
318 void
319 Session::set_worst_io_latencies ()
321 _worst_output_latency = 0;
322 _worst_input_latency = 0;
324 if (!_engine.connected()) {
325 return;
328 boost::shared_ptr<RouteList> r = routes.reader ();
330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
331 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
332 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
336 void
337 Session::when_engine_running ()
339 string first_physical_output;
341 BootMessage (_("Set block size and sample rate"));
343 set_block_size (_engine.frames_per_cycle());
344 set_frame_rate (_engine.frame_rate());
346 BootMessage (_("Using configuration"));
348 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
349 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
351 Config->map_parameters (ff);
352 config.map_parameters (ft);
354 /* every time we reconnect, recompute worst case output latencies */
356 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
358 if (synced_to_jack()) {
359 _engine.transport_stop ();
362 if (config.get_jack_time_master()) {
363 _engine.transport_locate (_transport_frame);
366 _clicking = false;
368 try {
369 XMLNode* child = 0;
371 _click_io.reset (new ClickIO (*this, "click"));
373 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
375 /* existing state for Click */
376 int c;
378 if (Stateful::loading_state_version < 3000) {
379 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
380 } else {
381 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
385 if (c == 0) {
386 _clicking = Config->get_clicking ();
388 } else {
390 error << _("could not setup Click I/O") << endmsg;
391 _clicking = false;
395 } else {
397 /* default state for Click: dual-mono to first 2 physical outputs */
399 for (int physport = 0; physport < 2; ++physport) {
400 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
402 if (physical_output.length()) {
403 if (_click_io->add_port (physical_output, this)) {
404 // relax, even though its an error
409 if (_click_io->n_ports () > ChanCount::ZERO) {
410 _clicking = Config->get_clicking ();
415 catch (failed_constructor& err) {
416 error << _("cannot setup Click I/O") << endmsg;
419 BootMessage (_("Compute I/O Latencies"));
421 set_worst_io_latencies ();
423 if (_clicking) {
424 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
427 BootMessage (_("Set up standard connections"));
429 /* Create a set of Bundle objects that map
430 to the physical I/O currently available. We create both
431 mono and stereo bundles, so that the common cases of mono
432 and stereo tracks get bundles to put in their mixer strip
433 in / out menus. There may be a nicer way of achieving that;
434 it doesn't really scale that well to higher channel counts
437 /* mono output bundles */
439 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
440 char buf[32];
441 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
443 shared_ptr<Bundle> c (new Bundle (buf, true));
444 c->add_channel (_("mono"), DataType::AUDIO);
445 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
447 add_bundle (c);
450 /* stereo output bundles */
452 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
453 if (np + 1 < n_physical_outputs) {
454 char buf[32];
455 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
456 shared_ptr<Bundle> c (new Bundle (buf, true));
457 c->add_channel (_("L"), DataType::AUDIO);
458 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
459 c->add_channel (_("R"), DataType::AUDIO);
460 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
462 add_bundle (c);
466 /* mono input bundles */
468 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
469 char buf[32];
470 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
472 shared_ptr<Bundle> c (new Bundle (buf, false));
473 c->add_channel (_("mono"), DataType::AUDIO);
474 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
476 add_bundle (c);
479 /* stereo input bundles */
481 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
482 if (np + 1 < n_physical_inputs) {
483 char buf[32];
484 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
486 shared_ptr<Bundle> c (new Bundle (buf, false));
487 c->add_channel (_("L"), DataType::AUDIO);
488 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
489 c->add_channel (_("R"), DataType::AUDIO);
490 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
492 add_bundle (c);
496 BootMessage (_("Setup signal flow and plugins"));
498 hookup_io ();
500 if (_is_new && !no_auto_connect()) {
502 /* don't connect the master bus outputs if there is a monitor bus */
504 if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
506 /* if requested auto-connect the outputs to the first N physical ports.
509 uint32_t limit = _master_out->n_outputs().n_total();
511 for (uint32_t n = 0; n < limit; ++n) {
512 Port* p = _master_out->output()->nth (n);
513 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
515 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
516 if (_master_out->output()->connect (p, connect_to, this)) {
517 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
518 << endmsg;
519 break;
525 if (_monitor_out) {
527 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
528 are undefined, at best.
531 /* control out listens to master bus (but ignores it
532 under some conditions)
535 uint32_t limit = _monitor_out->n_inputs().n_audio();
537 if (_master_out) {
538 for (uint32_t n = 0; n < limit; ++n) {
539 AudioPort* p = _monitor_out->input()->ports().nth_audio_port (n);
540 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
542 if (o) {
543 string connect_to = o->name();
544 if (_monitor_out->input()->connect (p, connect_to, this)) {
545 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
546 << endmsg;
547 break;
553 /* if control out is not connected, connect control out to physical outs
556 if (!_monitor_out->output()->connected ()) {
558 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
560 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
562 if (b) {
563 _monitor_out->output()->connect_ports_to_bundle (b, this);
564 } else {
565 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
566 Config->get_monitor_bus_preferred_bundle())
567 << endmsg;
570 } else {
572 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
573 uint32_t mod = _engine.n_physical_outputs (*t);
574 uint32_t limit = _monitor_out->n_outputs().get(*t);
576 for (uint32_t n = 0; n < limit; ++n) {
578 Port* p = _monitor_out->output()->ports().port(*t, n);
579 string connect_to = _engine.get_nth_physical_output (*t, (n % mod));
581 if (!connect_to.empty()) {
582 if (_monitor_out->output()->connect (p, connect_to, this)) {
583 error << string_compose (
584 _("cannot connect control output %1 to %2"),
585 n, connect_to)
586 << endmsg;
587 break;
597 /* catch up on send+insert cnts */
599 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
601 /* hook us up to the engine */
603 BootMessage (_("Connect to engine"));
605 _engine.set_session (this);
608 void
609 Session::hookup_io ()
611 /* stop graph reordering notifications from
612 causing resorts, etc.
615 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
618 if (!auditioner) {
620 /* we delay creating the auditioner till now because
621 it makes its own connections to ports.
624 try {
625 Auditioner* a = new Auditioner (*this);
626 if (a->init()) {
627 delete a;
628 throw failed_constructor();
630 a->use_new_diskstream ();
631 auditioner.reset (a);
634 catch (failed_constructor& err) {
635 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
639 /* load bundles, which we may have postponed earlier on */
640 if (_bundle_xml_node) {
641 load_bundles (*_bundle_xml_node);
642 delete _bundle_xml_node;
645 /* Tell all IO objects to connect themselves together */
647 IO::enable_connecting ();
648 MIDI::Port::MakeConnections ();
650 /* Now reset all panners */
652 Delivery::reset_panners ();
654 /* Connect tracks to monitor/listen bus if there is one.
655 Note that in an existing session, the internal sends will
656 already exist, but we want the routes to notice that
657 they connect to the control out specifically.
660 if (_monitor_out) {
661 boost::shared_ptr<RouteList> r = routes.reader ();
662 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
664 if ((*x)->is_monitor()) {
666 /* relax */
668 } else if ((*x)->is_master()) {
670 /* relax */
672 } else {
674 (*x)->listen_via (_monitor_out,
675 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
676 false, false);
681 /* Anyone who cares about input state, wake up and do something */
683 IOConnectionsComplete (); /* EMIT SIGNAL */
685 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
687 /* now handle the whole enchilada as if it was one
688 graph reorder event.
691 graph_reordered ();
693 /* update the full solo state, which can't be
694 correctly determined on a per-route basis, but
695 needs the global overview that only the session
696 has.
699 update_route_solo_state ();
702 void
703 Session::playlist_length_changed ()
705 update_session_range_location_marker ();
708 void
709 Session::track_playlist_changed (boost::weak_ptr<Track> wp)
711 boost::shared_ptr<Track> track = wp.lock ();
712 if (!track) {
713 return;
716 boost::shared_ptr<Playlist> playlist;
718 if ((playlist = track->playlist()) != 0) {
719 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
722 update_session_range_location_marker ();
725 bool
726 Session::record_enabling_legal () const
728 /* this used to be in here, but survey says.... we don't need to restrict it */
729 // if (record_status() == Recording) {
730 // return false;
731 // }
733 if (Config->get_all_safe()) {
734 return false;
736 return true;
739 void
740 Session::reset_input_monitor_state ()
742 if (transport_rolling()) {
744 boost::shared_ptr<RouteList> rl = routes.reader ();
745 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
746 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
747 if (tr && tr->record_enabled ()) {
748 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
749 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
753 } else {
755 boost::shared_ptr<RouteList> rl = routes.reader ();
756 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
757 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
758 if (tr && tr->record_enabled ()) {
759 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
760 tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
766 void
767 Session::auto_punch_start_changed (Location* location)
769 replace_event (SessionEvent::PunchIn, location->start());
771 if (get_record_enabled() && config.get_punch_in()) {
772 /* capture start has been changed, so save new pending state */
773 save_state ("", true);
777 void
778 Session::auto_punch_end_changed (Location* location)
780 nframes_t when_to_stop = location->end();
781 // when_to_stop += _worst_output_latency + _worst_input_latency;
782 replace_event (SessionEvent::PunchOut, when_to_stop);
785 void
786 Session::auto_punch_changed (Location* location)
788 nframes_t when_to_stop = location->end();
790 replace_event (SessionEvent::PunchIn, location->start());
791 //when_to_stop += _worst_output_latency + _worst_input_latency;
792 replace_event (SessionEvent::PunchOut, when_to_stop);
795 void
796 Session::auto_loop_changed (Location* location)
798 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
800 if (transport_rolling() && play_loop) {
803 // if (_transport_frame > location->end()) {
805 if (_transport_frame < location->start() || _transport_frame > location->end()) {
806 // relocate to beginning of loop
807 clear_events (SessionEvent::LocateRoll);
809 request_locate (location->start(), true);
812 else if (Config->get_seamless_loop() && !loop_changing) {
814 // schedule a locate-roll to refill the diskstreams at the
815 // previous loop end
816 loop_changing = true;
818 if (location->end() > last_loopend) {
819 clear_events (SessionEvent::LocateRoll);
820 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
821 queue_event (ev);
827 last_loopend = location->end();
830 void
831 Session::set_auto_punch_location (Location* location)
833 Location* existing;
835 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
836 punch_connections.drop_connections();
837 existing->set_auto_punch (false, this);
838 remove_event (existing->start(), SessionEvent::PunchIn);
839 clear_events (SessionEvent::PunchOut);
840 auto_punch_location_changed (0);
843 set_dirty();
845 if (location == 0) {
846 return;
849 if (location->end() <= location->start()) {
850 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
851 return;
854 punch_connections.drop_connections ();
856 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
857 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
858 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
860 location->set_auto_punch (true, this);
862 auto_punch_changed (location);
864 auto_punch_location_changed (location);
867 void
868 Session::set_auto_loop_location (Location* location)
870 Location* existing;
872 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
873 loop_connections.drop_connections ();
874 existing->set_auto_loop (false, this);
875 remove_event (existing->end(), SessionEvent::AutoLoop);
876 auto_loop_location_changed (0);
879 set_dirty();
881 if (location == 0) {
882 return;
885 if (location->end() <= location->start()) {
886 error << _("Session: you can't use a mark for auto loop") << endmsg;
887 return;
890 last_loopend = location->end();
892 loop_connections.drop_connections ();
894 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
895 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
896 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
898 location->set_auto_loop (true, this);
900 /* take care of our stuff first */
902 auto_loop_changed (location);
904 /* now tell everyone else */
906 auto_loop_location_changed (location);
909 void
910 Session::locations_added (Location *)
912 set_dirty ();
915 void
916 Session::locations_changed ()
918 _locations.apply (*this, &Session::handle_locations_changed);
921 void
922 Session::handle_locations_changed (Locations::LocationList& locations)
924 Locations::LocationList::iterator i;
925 Location* location;
926 bool set_loop = false;
927 bool set_punch = false;
929 for (i = locations.begin(); i != locations.end(); ++i) {
931 location =* i;
933 if (location->is_auto_punch()) {
934 set_auto_punch_location (location);
935 set_punch = true;
937 if (location->is_auto_loop()) {
938 set_auto_loop_location (location);
939 set_loop = true;
942 if (location->is_session_range()) {
943 _session_range_location = location;
947 if (!set_loop) {
948 set_auto_loop_location (0);
950 if (!set_punch) {
951 set_auto_punch_location (0);
954 set_dirty();
957 void
958 Session::enable_record ()
960 while (1) {
961 RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
963 if (rs == Recording) {
964 break;
967 if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
969 _last_record_location = _transport_frame;
970 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
972 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
974 boost::shared_ptr<RouteList> rl = routes.reader ();
975 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
976 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
977 if (tr && tr->record_enabled ()) {
978 tr->monitor_input (true);
983 RecordStateChanged ();
984 break;
989 void
990 Session::disable_record (bool rt_context, bool force)
992 RecordState rs;
994 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
996 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
997 g_atomic_int_set (&_record_status, Disabled);
998 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
999 } else {
1000 if (rs == Recording) {
1001 g_atomic_int_set (&_record_status, Enabled);
1005 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1007 boost::shared_ptr<RouteList> rl = routes.reader ();
1008 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1009 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1010 if (tr && tr->record_enabled ()) {
1011 tr->monitor_input (false);
1016 RecordStateChanged (); /* emit signal */
1018 if (!rt_context) {
1019 remove_pending_capture_state ();
1024 void
1025 Session::step_back_from_record ()
1027 if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
1029 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1030 boost::shared_ptr<RouteList> rl = routes.reader ();
1031 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1032 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1033 if (tr && tr->record_enabled ()) {
1034 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1035 tr->monitor_input (false);
1042 void
1043 Session::maybe_enable_record ()
1045 g_atomic_int_set (&_record_status, Enabled);
1047 /* this function is currently called from somewhere other than an RT thread.
1048 this save_state() call therefore doesn't impact anything.
1051 save_state ("", true);
1053 if (_transport_speed) {
1054 if (!config.get_punch_in()) {
1055 enable_record ();
1057 } else {
1058 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
1059 RecordStateChanged (); /* EMIT SIGNAL */
1062 set_dirty();
1065 nframes64_t
1066 Session::audible_frame () const
1068 nframes64_t ret;
1069 nframes64_t tf;
1070 nframes_t offset;
1072 /* the first of these two possible settings for "offset"
1073 mean that the audible frame is stationary until
1074 audio emerges from the latency compensation
1075 "pseudo-pipeline".
1077 the second means that the audible frame is stationary
1078 until audio would emerge from a physical port
1079 in the absence of any plugin latency compensation
1082 offset = _worst_output_latency;
1084 if (offset > current_block_size) {
1085 offset -= current_block_size;
1086 } else {
1087 /* XXX is this correct? if we have no external
1088 physical connections and everything is internal
1089 then surely this is zero? still, how
1090 likely is that anyway?
1092 offset = current_block_size;
1095 if (synced_to_jack()) {
1096 tf = _engine.transport_frame();
1097 } else {
1098 tf = _transport_frame;
1101 ret = tf;
1103 if (!non_realtime_work_pending()) {
1105 /* MOVING */
1107 /* Check to see if we have passed the first guaranteed
1108 audible frame past our last start position. if not,
1109 return that last start point because in terms
1110 of audible frames, we have not moved yet.
1112 `Start position' in this context means the time we last
1113 either started or changed transport direction.
1116 if (_transport_speed > 0.0f) {
1118 if (!play_loop || !have_looped) {
1119 if (tf < _last_roll_or_reversal_location + offset) {
1120 return _last_roll_or_reversal_location;
1125 /* forwards */
1126 ret -= offset;
1128 } else if (_transport_speed < 0.0f) {
1130 /* XXX wot? no backward looping? */
1132 if (tf > _last_roll_or_reversal_location - offset) {
1133 return _last_roll_or_reversal_location;
1134 } else {
1135 /* backwards */
1136 ret += offset;
1141 return ret;
1144 void
1145 Session::set_frame_rate (nframes_t frames_per_second)
1147 /** \fn void Session::set_frame_size(nframes_t)
1148 the AudioEngine object that calls this guarantees
1149 that it will not be called while we are also in
1150 ::process(). Its fine to do things that block
1151 here.
1154 _base_frame_rate = frames_per_second;
1156 sync_time_vars();
1158 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1160 clear_clicks ();
1162 // XXX we need some equivalent to this, somehow
1163 // SndFileSource::setup_standard_crossfades (frames_per_second);
1165 set_dirty();
1167 /* XXX need to reset/reinstantiate all LADSPA plugins */
1170 void
1171 Session::set_block_size (nframes_t nframes)
1173 /* the AudioEngine guarantees
1174 that it will not be called while we are also in
1175 ::process(). It is therefore fine to do things that block
1176 here.
1180 current_block_size = nframes;
1182 ensure_buffers ();
1184 boost::shared_ptr<RouteList> r = routes.reader ();
1186 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1187 (*i)->set_block_size (nframes);
1190 boost::shared_ptr<RouteList> rl = routes.reader ();
1191 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1192 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1193 if (tr) {
1194 tr->set_block_size (nframes);
1198 set_worst_io_latencies ();
1202 void
1203 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1205 #if 0
1206 nframes_t fade_frames;
1208 /* Don't allow fade of less 1 frame */
1210 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1212 fade_msecs = 0;
1213 fade_frames = 0;
1215 } else {
1217 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1221 default_fade_msecs = fade_msecs;
1222 default_fade_steepness = steepness;
1225 // jlc, WTF is this!
1226 Glib::RWLock::ReaderLock lm (route_lock);
1227 AudioRegion::set_default_fade (steepness, fade_frames);
1230 set_dirty();
1232 /* XXX have to do this at some point */
1233 /* foreach region using default fade, reset, then
1234 refill_all_diskstream_buffers ();
1236 #endif
1239 struct RouteSorter {
1240 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1241 if (r2->feeds (r1)) {
1242 return false;
1243 } else if (r1->feeds (r2)) {
1244 return true;
1245 } else {
1246 if (r1->not_fed ()) {
1247 if (r2->not_fed ()) {
1248 /* no ardour-based connections inbound to either route. just use signal order */
1249 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1250 } else {
1251 /* r2 has connections, r1 does not; run r1 early */
1252 return true;
1254 } else {
1255 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1261 static void
1262 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1264 shared_ptr<Route> r2;
1266 if (r1->feeds (rbase) && rbase->feeds (r1)) {
1267 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1268 return;
1271 /* make a copy of the existing list of routes that feed r1 */
1273 Route::FedBy existing (r1->fed_by());
1275 /* for each route that feeds r1, recurse, marking it as feeding
1276 rbase as well.
1279 for (Route::FedBy::iterator i = existing.begin(); i != existing.end(); ++i) {
1280 if (!(r2 = i->r.lock ())) {
1281 /* (*i) went away, ignore it */
1282 continue;
1285 /* r2 is a route that feeds r1 which somehow feeds base. mark
1286 base as being fed by r2
1289 rbase->add_fed_by (r2, i->sends_only);
1291 if (r2 != rbase) {
1293 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1294 stop here.
1297 if (r1->feeds (r2) && r2->feeds (r1)) {
1298 continue;
1301 /* now recurse, so that we can mark base as being fed by
1302 all routes that feed r2
1305 trace_terminal (r2, rbase);
1311 void
1312 Session::resort_routes ()
1314 /* don't do anything here with signals emitted
1315 by Routes while we are being destroyed.
1318 if (_state_of_the_state & Deletion) {
1319 return;
1323 RCUWriter<RouteList> writer (routes);
1324 shared_ptr<RouteList> r = writer.get_copy ();
1325 resort_routes_using (r);
1326 /* writer goes out of scope and forces update */
1329 //route_graph->dump(1);
1331 #ifndef NDEBUG
1332 boost::shared_ptr<RouteList> rl = routes.reader ();
1333 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1334 DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
1336 const Route::FedBy& fb ((*i)->fed_by());
1338 for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
1339 boost::shared_ptr<Route> sf = f->r.lock();
1340 if (sf) {
1341 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 (sends only ? %2)\n", sf->name(), f->sends_only));
1345 #endif
1348 void
1349 Session::resort_routes_using (shared_ptr<RouteList> r)
1351 RouteList::iterator i, j;
1353 for (i = r->begin(); i != r->end(); ++i) {
1355 (*i)->clear_fed_by ();
1357 for (j = r->begin(); j != r->end(); ++j) {
1359 /* although routes can feed themselves, it will
1360 cause an endless recursive descent if we
1361 detect it. so don't bother checking for
1362 self-feeding.
1365 if (*j == *i) {
1366 continue;
1369 bool via_sends_only;
1371 if ((*j)->direct_feeds (*i, &via_sends_only)) {
1372 (*i)->add_fed_by (*j, via_sends_only);
1377 for (i = r->begin(); i != r->end(); ++i) {
1378 trace_terminal (*i, *i);
1381 RouteSorter cmp;
1382 r->sort (cmp);
1384 route_graph->rechain (r);
1386 #ifndef NDEBUG
1387 DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
1388 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1389 DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
1390 (*i)->name(), (*i)->order_key ("signal")));
1392 #endif
1396 /** Find the route name starting with \a base with the lowest \a id.
1398 * Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
1399 * The available route name with the lowest ID will be used, and \a id
1400 * will be set to the ID.
1402 * \return false if a route name could not be found, and \a track_name
1403 * and \a id do not reflect a free route name.
1405 bool
1406 Session::find_route_name (const char* base, uint32_t& id, char* name, size_t name_len)
1408 do {
1409 snprintf (name, name_len, "%s %" PRIu32, base, id);
1411 if (route_by_name (name) == 0) {
1412 return true;
1415 ++id;
1417 } while (id < (UINT_MAX-1));
1419 return false;
1422 void
1423 Session::count_existing_route_channels (ChanCount& in, ChanCount& out)
1425 in = ChanCount::ZERO;
1426 out = ChanCount::ZERO;
1427 shared_ptr<RouteList> r = routes.reader ();
1428 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1429 if (!(*i)->is_hidden()) {
1430 in += (*i)->n_inputs();
1431 out += (*i)->n_outputs();
1436 list<boost::shared_ptr<MidiTrack> >
1437 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1439 char track_name[32];
1440 uint32_t track_id = 0;
1441 ChanCount existing_inputs;
1442 ChanCount existing_outputs;
1443 string port;
1444 RouteList new_routes;
1445 list<boost::shared_ptr<MidiTrack> > ret;
1446 uint32_t control_id;
1448 count_existing_route_channels (existing_inputs, existing_outputs);
1450 control_id = ntracks() + nbusses();
1452 while (how_many) {
1453 if (!find_route_name ("Midi", ++track_id, track_name, sizeof(track_name))) {
1454 error << "cannot find name for new midi track" << endmsg;
1455 goto failed;
1458 shared_ptr<MidiTrack> track;
1460 try {
1461 MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1463 if (mt->init ()) {
1464 delete mt;
1465 goto failed;
1468 mt->use_new_diskstream();
1470 boost_debug_shared_ptr_mark_interesting (mt, "Track");
1471 track = boost::shared_ptr<MidiTrack>(mt);
1473 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1474 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1475 goto failed;
1479 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1480 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1481 goto failed;
1484 auto_connect_route (track, existing_inputs, existing_outputs);
1486 track->non_realtime_input_change();
1488 if (route_group) {
1489 route_group->add (track);
1492 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1493 track->set_remote_control_id (control_id);
1495 new_routes.push_back (track);
1496 ret.push_back (track);
1499 catch (failed_constructor &err) {
1500 error << _("Session: could not create new midi track.") << endmsg;
1501 goto failed;
1504 catch (AudioEngine::PortRegistrationFailure& pfe) {
1506 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;
1507 goto failed;
1510 --how_many;
1513 failed:
1514 if (!new_routes.empty()) {
1515 add_routes (new_routes, false);
1516 save_state (_current_snapshot_name);
1519 return ret;
1522 void
1523 Session::auto_connect_route (boost::shared_ptr<Route> route,
1524 ChanCount& existing_inputs, ChanCount& existing_outputs)
1526 /* If both inputs and outputs are auto-connected to physical ports,
1527 use the max of input and output offsets to ensure auto-connected
1528 port numbers always match up (e.g. the first audio input and the
1529 first audio output of the route will have the same physical
1530 port number). Otherwise just use the lowest input or output
1531 offset possible.
1533 const bool in_out_physical =
1534 (Config->get_input_auto_connect() & AutoConnectPhysical)
1535 && (Config->get_output_auto_connect() & AutoConnectPhysical);
1537 const ChanCount in_offset = in_out_physical
1538 ? ChanCount::max(existing_inputs, existing_outputs)
1539 : existing_inputs;
1541 const ChanCount out_offset = in_out_physical
1542 ? ChanCount::max(existing_inputs, existing_outputs)
1543 : existing_outputs;
1545 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1546 vector<string> physinputs;
1547 vector<string> physoutputs;
1549 _engine.get_physical_outputs (*t, physoutputs);
1550 _engine.get_physical_inputs (*t, physinputs);
1552 if (!physinputs.empty()) {
1553 uint32_t nphysical_in = physinputs.size();
1554 for (uint32_t i = 0; i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
1555 string port;
1557 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1558 port = physinputs[(in_offset.get(*t) + i) % nphysical_in];
1561 if (!port.empty() && route->input()->connect (
1562 route->input()->ports().port(*t, i), port, this)) {
1563 break;
1568 if (!physoutputs.empty()) {
1569 uint32_t nphysical_out = physoutputs.size();
1570 for (uint32_t i = 0; i < route->n_outputs().get(*t); ++i) {
1571 string port;
1573 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1574 port = physoutputs[(out_offset.get(*t) + i) % nphysical_out];
1575 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1576 if (_master_out && _master_out->n_inputs().get(*t) > 0) {
1577 port = _master_out->input()->ports().port(*t,
1578 i % _master_out->input()->n_ports().get(*t))->name();
1582 if (!port.empty() && route->output()->connect (
1583 route->output()->ports().port(*t, i), port, this)) {
1584 break;
1590 existing_inputs += route->n_inputs();
1591 existing_outputs += route->n_outputs();
1594 list< boost::shared_ptr<AudioTrack> >
1595 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1597 char track_name[32];
1598 uint32_t track_id = 0;
1599 ChanCount existing_inputs;
1600 ChanCount existing_outputs;
1601 string port;
1602 RouteList new_routes;
1603 list<boost::shared_ptr<AudioTrack> > ret;
1604 uint32_t control_id;
1606 count_existing_route_channels (existing_inputs, existing_outputs);
1608 control_id = ntracks() + nbusses() + 1;
1610 while (how_many) {
1611 if (!find_route_name ("Audio", ++track_id, track_name, sizeof(track_name))) {
1612 error << "cannot find name for new audio track" << endmsg;
1613 goto failed;
1616 shared_ptr<AudioTrack> track;
1618 try {
1619 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1621 if (at->init ()) {
1622 delete at;
1623 goto failed;
1626 at->use_new_diskstream();
1628 boost_debug_shared_ptr_mark_interesting (at, "Track");
1629 track = boost::shared_ptr<AudioTrack>(at);
1631 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1632 error << string_compose (
1633 _("cannot configure %1 in/%2 out configuration for new audio track"),
1634 input_channels, output_channels)
1635 << endmsg;
1636 goto failed;
1639 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1640 error << string_compose (
1641 _("cannot configure %1 in/%2 out configuration for new audio track"),
1642 input_channels, output_channels)
1643 << endmsg;
1644 goto failed;
1647 auto_connect_route (track, existing_inputs, existing_outputs);
1649 if (route_group) {
1650 route_group->add (track);
1653 track->non_realtime_input_change();
1655 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1656 track->set_remote_control_id (control_id);
1657 ++control_id;
1659 new_routes.push_back (track);
1660 ret.push_back (track);
1663 catch (failed_constructor &err) {
1664 error << _("Session: could not create new audio track.") << endmsg;
1665 goto failed;
1668 catch (AudioEngine::PortRegistrationFailure& pfe) {
1670 error << pfe.what() << endmsg;
1671 goto failed;
1674 --how_many;
1677 failed:
1678 if (!new_routes.empty()) {
1679 add_routes (new_routes, true);
1682 return ret;
1685 void
1686 Session::set_remote_control_ids ()
1688 RemoteModel m = Config->get_remote_model();
1689 bool emit_signal = false;
1691 shared_ptr<RouteList> r = routes.reader ();
1693 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1694 if (MixerOrdered == m) {
1695 long order = (*i)->order_key(N_("signal"));
1696 (*i)->set_remote_control_id (order+1, false);
1697 emit_signal = true;
1698 } else if (EditorOrdered == m) {
1699 long order = (*i)->order_key(N_("editor"));
1700 (*i)->set_remote_control_id (order+1, false);
1701 emit_signal = true;
1702 } else if (UserOrdered == m) {
1703 //do nothing ... only changes to remote id's are initiated by user
1707 if (emit_signal) {
1708 Route::RemoteControlIDChange();
1713 RouteList
1714 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1716 char bus_name[32];
1717 uint32_t bus_id = 0;
1718 ChanCount existing_inputs;
1719 ChanCount existing_outputs;
1720 string port;
1721 RouteList ret;
1722 uint32_t control_id;
1724 count_existing_route_channels (existing_inputs, existing_outputs);
1726 control_id = ntracks() + nbusses() + 1;
1728 while (how_many) {
1729 if (!find_route_name ("Bus", ++bus_id, bus_name, sizeof(bus_name))) {
1730 error << "cannot find name for new audio bus" << endmsg;
1731 goto failure;
1734 try {
1735 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1737 if (rt->init ()) {
1738 delete rt;
1739 goto failure;
1742 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1743 shared_ptr<Route> bus (rt);
1745 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1746 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1747 input_channels, output_channels)
1748 << endmsg;
1749 goto failure;
1753 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1754 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1755 input_channels, output_channels)
1756 << endmsg;
1757 goto failure;
1760 auto_connect_route (bus, existing_inputs, existing_outputs);
1762 if (route_group) {
1763 route_group->add (bus);
1765 bus->set_remote_control_id (control_id);
1766 ++control_id;
1768 if (aux) {
1769 bus->add_internal_return ();
1772 ret.push_back (bus);
1776 catch (failed_constructor &err) {
1777 error << _("Session: could not create new audio route.") << endmsg;
1778 goto failure;
1781 catch (AudioEngine::PortRegistrationFailure& pfe) {
1782 error << pfe.what() << endmsg;
1783 goto failure;
1787 --how_many;
1790 failure:
1791 if (!ret.empty()) {
1792 add_routes (ret, true);
1795 return ret;
1799 RouteList
1800 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1802 char name[32];
1803 RouteList ret;
1804 uint32_t control_id;
1805 XMLTree tree;
1806 uint32_t number = 0;
1808 if (!tree.read (template_path.c_str())) {
1809 return ret;
1812 XMLNode* node = tree.root();
1814 control_id = ntracks() + nbusses() + 1;
1816 while (how_many) {
1818 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1820 std::string node_name = IO::name_from_state (*node_copy.children().front());
1822 /* generate a new name by adding a number to the end of the template name */
1823 if (!find_route_name (node_name.c_str(), ++number, name, sizeof(name))) {
1824 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
1825 /*NOTREACHED*/
1828 /* set IO children to use the new name */
1829 XMLNodeList const & children = node_copy.children ();
1830 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
1831 if ((*i)->name() == IO::state_node_name) {
1832 IO::set_name_in_state (**i, name);
1836 Track::zero_diskstream_id_in_xml (node_copy);
1838 try {
1839 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
1841 if (route == 0) {
1842 error << _("Session: cannot create track/bus from template description") << endmsg;
1843 goto out;
1846 if (boost::dynamic_pointer_cast<Track>(route)) {
1847 /* force input/output change signals so that the new diskstream
1848 picks up the configuration of the route. During session
1849 loading this normally happens in a different way.
1851 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
1852 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
1855 route->set_remote_control_id (control_id);
1856 ++control_id;
1858 ret.push_back (route);
1861 catch (failed_constructor &err) {
1862 error << _("Session: could not create new route from template") << endmsg;
1863 goto out;
1866 catch (AudioEngine::PortRegistrationFailure& pfe) {
1867 error << pfe.what() << endmsg;
1868 goto out;
1871 --how_many;
1874 out:
1875 if (!ret.empty()) {
1876 add_routes (ret, true);
1879 return ret;
1882 void
1883 Session::add_routes (RouteList& new_routes, bool save)
1886 RCUWriter<RouteList> writer (routes);
1887 shared_ptr<RouteList> r = writer.get_copy ();
1888 r->insert (r->end(), new_routes.begin(), new_routes.end());
1891 /* if there is no control out and we're not in the middle of loading,
1892 resort the graph here. if there is a control out, we will resort
1893 toward the end of this method. if we are in the middle of loading,
1894 we will resort when done.
1897 if (!_monitor_out && IO::connecting_legal) {
1898 resort_routes_using (r);
1902 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1904 boost::weak_ptr<Route> wpr (*x);
1905 boost::shared_ptr<Route> r (*x);
1907 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
1908 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
1909 r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
1910 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
1911 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
1912 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
1914 if (r->is_master()) {
1915 _master_out = r;
1918 if (r->is_monitor()) {
1919 _monitor_out = r;
1922 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (r);
1923 if (tr) {
1924 tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr<Track> (tr)));
1925 track_playlist_changed (boost::weak_ptr<Track> (tr));
1926 tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this));
1930 if (_monitor_out && IO::connecting_legal) {
1932 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1933 if ((*x)->is_monitor()) {
1934 /* relax */
1935 } else if ((*x)->is_master()) {
1936 /* relax */
1937 } else {
1938 (*x)->listen_via (_monitor_out,
1939 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
1940 false, false);
1944 resort_routes ();
1947 set_dirty();
1949 if (save) {
1950 save_state (_current_snapshot_name);
1953 RouteAdded (new_routes); /* EMIT SIGNAL */
1954 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
1957 void
1958 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
1960 boost::shared_ptr<RouteList> r = routes.reader ();
1961 boost::shared_ptr<Send> s;
1963 /* only tracks */
1965 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1966 if (boost::dynamic_pointer_cast<Track>(*i)) {
1967 if ((s = (*i)->internal_send_for (dest)) != 0) {
1968 s->amp()->gain_control()->set_value (0.0);
1974 void
1975 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
1977 boost::shared_ptr<RouteList> r = routes.reader ();
1978 boost::shared_ptr<Send> s;
1980 /* only tracks */
1982 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1983 if (boost::dynamic_pointer_cast<Track>(*i)) {
1984 if ((s = (*i)->internal_send_for (dest)) != 0) {
1985 s->amp()->gain_control()->set_value (1.0);
1991 void
1992 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
1994 boost::shared_ptr<RouteList> r = routes.reader ();
1995 boost::shared_ptr<Send> s;
1997 /* only tracks */
1999 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2000 if (boost::dynamic_pointer_cast<Track>(*i)) {
2001 if ((s = (*i)->internal_send_for (dest)) != 0) {
2002 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2008 void
2009 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2011 boost::shared_ptr<RouteList> r = routes.reader ();
2012 boost::shared_ptr<RouteList> t (new RouteList);
2014 /* only send tracks */
2016 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2017 if (boost::dynamic_pointer_cast<Track>(*i)) {
2018 t->push_back (*i);
2022 add_internal_sends (dest, p, t);
2025 void
2026 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2028 if (dest->is_monitor() || dest->is_master()) {
2029 return;
2032 if (!dest->internal_return()) {
2033 dest->add_internal_return();
2036 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2038 if ((*i)->is_monitor() || (*i)->is_master() || (*i) == dest) {
2039 continue;
2042 (*i)->listen_via (dest, p, true, true);
2045 graph_reordered ();
2048 void
2049 Session::remove_route (shared_ptr<Route> route)
2051 if (((route == _master_out) || (route == _monitor_out)) && !Config->get_allow_special_bus_removal()) {
2052 return;
2056 RCUWriter<RouteList> writer (routes);
2057 shared_ptr<RouteList> rs = writer.get_copy ();
2059 rs->remove (route);
2061 /* deleting the master out seems like a dumb
2062 idea, but its more of a UI policy issue
2063 than our concern.
2066 if (route == _master_out) {
2067 _master_out = shared_ptr<Route> ();
2070 if (route == _monitor_out) {
2072 /* cancel control outs for all routes */
2074 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2075 (*r)->drop_listen (_monitor_out);
2078 _monitor_out.reset ();
2081 /* writer goes out of scope, forces route list update */
2084 update_route_solo_state ();
2085 update_session_range_location_marker ();
2087 // We need to disconnect the route's inputs and outputs
2089 route->input()->disconnect (0);
2090 route->output()->disconnect (0);
2092 /* if the route had internal sends sending to it, remove them */
2093 if (route->internal_return()) {
2095 boost::shared_ptr<RouteList> r = routes.reader ();
2096 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2097 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2098 if (s) {
2099 (*i)->remove_processor (s);
2104 update_latency_compensation (false, false);
2105 set_dirty();
2107 /* flush references out of the graph
2110 route_graph->clear_other_chain ();
2112 /* get rid of it from the dead wood collection in the route list manager */
2114 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2116 routes.flush ();
2118 /* try to cause everyone to drop their references */
2120 route->drop_references ();
2122 sync_order_keys (N_("session"));
2124 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2126 /* save the new state of the world */
2128 if (save_state (_current_snapshot_name)) {
2129 save_history (_current_snapshot_name);
2133 void
2134 Session::route_mute_changed (void* /*src*/)
2136 set_dirty ();
2139 void
2140 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2142 boost::shared_ptr<Route> route = wpr.lock();
2143 if (!route) {
2144 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2145 return;
2148 if (route->listening()) {
2150 if (Config->get_exclusive_solo()) {
2151 /* new listen: disable all other listen */
2152 shared_ptr<RouteList> r = routes.reader ();
2153 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2154 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2155 continue;
2157 (*i)->set_listen (false, this);
2161 _listen_cnt++;
2163 } else if (_listen_cnt > 0) {
2165 _listen_cnt--;
2168 void
2169 Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2171 boost::shared_ptr<Route> route = wpr.lock ();
2173 if (!route) {
2174 /* should not happen */
2175 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2176 return;
2179 bool send_changed = false;
2181 if (route->solo_isolated()) {
2182 if (_solo_isolated_cnt == 0) {
2183 send_changed = true;
2185 _solo_isolated_cnt++;
2186 } else if (_solo_isolated_cnt > 0) {
2187 _solo_isolated_cnt--;
2188 if (_solo_isolated_cnt == 0) {
2189 send_changed = true;
2193 if (send_changed) {
2194 IsolatedChanged (); /* EMIT SIGNAL */
2198 void
2199 Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
2201 if (!self_solo_change) {
2202 // session doesn't care about changes to soloed-by-others
2203 return;
2206 if (solo_update_disabled) {
2207 // We know already
2208 return;
2211 boost::shared_ptr<Route> route = wpr.lock ();
2213 if (!route) {
2214 /* should not happen */
2215 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2216 return;
2219 shared_ptr<RouteList> r = routes.reader ();
2220 int32_t delta;
2222 if (route->self_soloed()) {
2223 delta = 1;
2224 } else {
2225 delta = -1;
2228 if (delta == 1 && Config->get_exclusive_solo()) {
2229 /* new solo: disable all other solos */
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2231 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2232 continue;
2234 (*i)->set_solo (false, this);
2238 solo_update_disabled = true;
2240 RouteList uninvolved;
2242 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2243 bool via_sends_only;
2244 bool in_signal_flow;
2246 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
2247 continue;
2250 in_signal_flow = false;
2252 if ((*i)->feeds (route, &via_sends_only)) {
2253 if (!via_sends_only) {
2254 if (!route->soloed_by_others_upstream()) {
2255 (*i)->mod_solo_by_others_downstream (delta);
2257 in_signal_flow = true;
2261 if (route->feeds (*i, &via_sends_only)) {
2262 (*i)->mod_solo_by_others_upstream (delta);
2263 in_signal_flow = true;
2266 if (!in_signal_flow) {
2267 uninvolved.push_back (*i);
2271 solo_update_disabled = false;
2272 update_route_solo_state (r);
2274 /* now notify that the mute state of the routes not involved in the signal
2275 pathway of the just-solo-changed route may have altered.
2278 for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
2279 (*i)->mute_changed (this);
2282 SoloChanged (); /* EMIT SIGNAL */
2283 set_dirty();
2286 void
2287 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2289 /* now figure out if anything that matters is soloed (or is "listening")*/
2291 bool something_soloed = false;
2292 uint32_t listeners = 0;
2293 uint32_t isolated = 0;
2295 if (!r) {
2296 r = routes.reader();
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2301 something_soloed = true;
2304 if (!(*i)->is_hidden() && (*i)->listening()) {
2305 if (Config->get_solo_control_is_listen_control()) {
2306 listeners++;
2307 } else {
2308 (*i)->set_listen (false, this);
2312 if ((*i)->solo_isolated()) {
2313 isolated++;
2317 if (something_soloed != _non_soloed_outs_muted) {
2318 _non_soloed_outs_muted = something_soloed;
2319 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2322 _listen_cnt = listeners;
2324 if (isolated != _solo_isolated_cnt) {
2325 _solo_isolated_cnt = isolated;
2326 IsolatedChanged (); /* EMIT SIGNAL */
2330 boost::shared_ptr<RouteList>
2331 Session::get_routes_with_internal_returns() const
2333 shared_ptr<RouteList> r = routes.reader ();
2334 boost::shared_ptr<RouteList> rl (new RouteList);
2336 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337 if ((*i)->internal_return ()) {
2338 rl->push_back (*i);
2341 return rl;
2344 bool
2345 Session::io_name_is_legal (const std::string& name)
2347 shared_ptr<RouteList> r = routes.reader ();
2349 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2350 if ((*i)->name() == name) {
2351 return false;
2354 if ((*i)->has_io_processor_named (name)) {
2355 return false;
2359 return true;
2362 shared_ptr<Route>
2363 Session::route_by_name (string name)
2365 shared_ptr<RouteList> r = routes.reader ();
2367 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2368 if ((*i)->name() == name) {
2369 return *i;
2373 return shared_ptr<Route> ((Route*) 0);
2376 shared_ptr<Route>
2377 Session::route_by_id (PBD::ID id)
2379 shared_ptr<RouteList> r = routes.reader ();
2381 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2382 if ((*i)->id() == id) {
2383 return *i;
2387 return shared_ptr<Route> ((Route*) 0);
2390 shared_ptr<Route>
2391 Session::route_by_remote_id (uint32_t id)
2393 shared_ptr<RouteList> r = routes.reader ();
2395 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2396 if ((*i)->remote_control_id() == id) {
2397 return *i;
2401 return shared_ptr<Route> ((Route*) 0);
2404 /** If either end of the session range location marker lies inside the current
2405 * session extent, move it to the corresponding session extent.
2407 void
2408 Session::update_session_range_location_marker ()
2410 if (_state_of_the_state & Loading) {
2411 return;
2414 pair<nframes_t, nframes_t> const ext = get_extent ();
2416 if (_session_range_location == 0) {
2417 /* we don't have a session range yet; use this one (provided it is valid) */
2418 if (ext.first != max_frames) {
2419 add_session_range_location (ext.first, ext.second);
2421 } else {
2422 /* update the existing session range */
2423 if (ext.first < _session_range_location->start()) {
2424 _session_range_location->set_start (ext.first);
2425 set_dirty ();
2428 if (ext.second > _session_range_location->end()) {
2429 _session_range_location->set_end (ext.second);
2430 set_dirty ();
2436 /** @return Extent of the session's contents; if the session is empty, the first value of
2437 * the pair will equal max_frames.
2439 pair<nframes_t, nframes_t>
2440 Session::get_extent () const
2442 pair<nframes_t, nframes_t> ext (max_frames, 0);
2444 boost::shared_ptr<RouteList> rl = routes.reader ();
2445 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2446 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2447 if (!tr || tr->destructive()) {
2448 // ignore tape tracks when getting extents
2449 continue;
2452 pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
2453 if (e.first < ext.first) {
2454 ext.first = e.first;
2456 if (e.second > ext.second) {
2457 ext.second = e.second;
2461 return ext;
2464 /* Region management */
2466 boost::shared_ptr<Region>
2467 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
2469 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2470 RegionFactory::RegionMap::const_iterator i;
2471 boost::shared_ptr<Region> region;
2473 Glib::Mutex::Lock lm (region_lock);
2475 for (i = regions.begin(); i != regions.end(); ++i) {
2477 region = i->second;
2479 if (region->whole_file()) {
2481 if (child->source_equivalent (region)) {
2482 return region;
2487 return boost::shared_ptr<Region> ();
2491 Session::destroy_sources (list<boost::shared_ptr<Source> > srcs)
2493 set<boost::shared_ptr<Region> > relevant_regions;
2495 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ++s) {
2496 RegionFactory::get_regions_using_source (*s, relevant_regions);
2499 cerr << "There are " << relevant_regions.size() << " using " << srcs.size() << " sources" << endl;
2501 for (set<boost::shared_ptr<Region> >::iterator r = relevant_regions.begin(); r != relevant_regions.end(); ) {
2502 set<boost::shared_ptr<Region> >::iterator tmp;
2504 tmp = r;
2505 ++tmp;
2507 cerr << "Cleanup " << (*r)->name() << " UC = " << (*r).use_count() << endl;
2509 playlists->destroy_region (*r);
2510 RegionFactory::map_remove (*r);
2512 (*r)->drop_sources ();
2513 (*r)->drop_references ();
2515 cerr << "\tdone UC = " << (*r).use_count() << endl;
2517 relevant_regions.erase (r);
2519 r = tmp;
2522 for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
2525 Glib::Mutex::Lock ls (source_lock);
2526 /* remove from the main source list */
2527 sources.erase ((*s)->id());
2530 (*s)->mark_for_remove ();
2531 (*s)->drop_references ();
2533 s = srcs.erase (s);
2536 return 0;
2540 Session::remove_last_capture ()
2542 list<boost::shared_ptr<Source> > srcs;
2544 boost::shared_ptr<RouteList> rl = routes.reader ();
2545 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2546 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2547 if (!tr) {
2548 continue;
2551 list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
2553 if (!l.empty()) {
2554 srcs.insert (srcs.end(), l.begin(), l.end());
2555 l.clear ();
2559 destroy_sources (srcs);
2561 save_state (_current_snapshot_name);
2563 return 0;
2566 /* Source Management */
2568 void
2569 Session::add_source (boost::shared_ptr<Source> source)
2571 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2572 pair<SourceMap::iterator,bool> result;
2574 entry.first = source->id();
2575 entry.second = source;
2578 Glib::Mutex::Lock lm (source_lock);
2579 result = sources.insert (entry);
2582 if (result.second) {
2584 /* yay, new source */
2586 set_dirty();
2588 boost::shared_ptr<AudioFileSource> afs;
2590 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2591 if (Config->get_auto_analyse_audio()) {
2592 Analyser::queue_source_for_analysis (source, false);
2598 void
2599 Session::remove_source (boost::weak_ptr<Source> src)
2601 SourceMap::iterator i;
2602 boost::shared_ptr<Source> source = src.lock();
2604 if (!source) {
2605 return;
2609 Glib::Mutex::Lock lm (source_lock);
2611 if ((i = sources.find (source->id())) != sources.end()) {
2612 sources.erase (i);
2616 if (!_state_of_the_state & InCleanup) {
2618 /* save state so we don't end up with a session file
2619 referring to non-existent sources.
2622 save_state (_current_snapshot_name);
2626 boost::shared_ptr<Source>
2627 Session::source_by_id (const PBD::ID& id)
2629 Glib::Mutex::Lock lm (source_lock);
2630 SourceMap::iterator i;
2631 boost::shared_ptr<Source> source;
2633 if ((i = sources.find (id)) != sources.end()) {
2634 source = i->second;
2637 return source;
2640 boost::shared_ptr<Source>
2641 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2643 Glib::Mutex::Lock lm (source_lock);
2645 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2646 cerr << "comparing " << path << " with " << i->second->name() << endl;
2647 boost::shared_ptr<AudioFileSource> afs
2648 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2650 if (afs && afs->path() == path && chn == afs->channel()) {
2651 return afs;
2654 return boost::shared_ptr<Source>();
2658 string
2659 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
2661 string look_for;
2662 string old_basename = PBD::basename_nosuffix (oldname);
2663 string new_legalized = legalize_for_path (newname);
2665 /* note: we know (or assume) the old path is already valid */
2667 if (destructive) {
2669 /* destructive file sources have a name of the form:
2671 /path/to/Tnnnn-NAME(%[LR])?.wav
2673 the task here is to replace NAME with the new name.
2676 /* find last slash */
2678 string dir;
2679 string prefix;
2680 string::size_type slash;
2681 string::size_type dash;
2683 if ((slash = path.find_last_of ('/')) == string::npos) {
2684 return "";
2687 dir = path.substr (0, slash+1);
2689 /* '-' is not a legal character for the NAME part of the path */
2691 if ((dash = path.find_last_of ('-')) == string::npos) {
2692 return "";
2695 prefix = path.substr (slash+1, dash-(slash+1));
2697 path = dir;
2698 path += prefix;
2699 path += '-';
2700 path += new_legalized;
2701 path += ".wav"; /* XXX gag me with a spoon */
2703 } else {
2705 /* non-destructive file sources have a name of the form:
2707 /path/to/NAME-nnnnn(%[LR])?.ext
2709 the task here is to replace NAME with the new name.
2712 string dir;
2713 string suffix;
2714 string::size_type slash;
2715 string::size_type dash;
2716 string::size_type postfix;
2718 /* find last slash */
2720 if ((slash = path.find_last_of ('/')) == string::npos) {
2721 return "";
2724 dir = path.substr (0, slash+1);
2726 /* '-' is not a legal character for the NAME part of the path */
2728 if ((dash = path.find_last_of ('-')) == string::npos) {
2729 return "";
2732 suffix = path.substr (dash+1);
2734 // Suffix is now everything after the dash. Now we need to eliminate
2735 // the nnnnn part, which is done by either finding a '%' or a '.'
2737 postfix = suffix.find_last_of ("%");
2738 if (postfix == string::npos) {
2739 postfix = suffix.find_last_of ('.');
2742 if (postfix != string::npos) {
2743 suffix = suffix.substr (postfix);
2744 } else {
2745 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
2746 return "";
2749 const uint32_t limit = 10000;
2750 char buf[PATH_MAX+1];
2752 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2754 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2756 if (access (buf, F_OK) != 0) {
2757 path = buf;
2758 break;
2760 path = "";
2763 if (path == "") {
2764 error << "FATAL ERROR! Could not find a " << endl;
2769 return path;
2772 /** Return the full path (in some session directory) for a new within-session source.
2773 * \a name must be a session-unique name that does not contain slashes
2774 * (e.g. as returned by new_*_source_name)
2776 string
2777 Session::new_source_path_from_name (DataType type, const string& name)
2779 assert(name.find("/") == string::npos);
2781 SessionDirectory sdir(get_best_session_directory_for_new_source());
2783 sys::path p;
2784 if (type == DataType::AUDIO) {
2785 p = sdir.sound_path();
2786 } else if (type == DataType::MIDI) {
2787 p = sdir.midi_path();
2788 } else {
2789 error << "Unknown source type, unable to create file path" << endmsg;
2790 return "";
2793 p /= name;
2794 return p.to_string();
2797 Glib::ustring
2798 Session::peak_path (Glib::ustring base) const
2800 sys::path peakfile_path(_session_dir->peak_path());
2801 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
2802 return peakfile_path.to_string();
2805 /** Return a unique name based on \a base for a new internal audio source */
2806 string
2807 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
2809 string spath;
2810 uint32_t cnt;
2811 char buf[PATH_MAX+1];
2812 const uint32_t limit = 10000;
2813 string legalized;
2815 buf[0] = '\0';
2816 legalized = legalize_for_path (base);
2818 // Find a "version" of the base name that doesn't exist in any of the possible directories.
2819 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2821 vector<space_and_path>::iterator i;
2822 uint32_t existing = 0;
2824 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2826 SessionDirectory sdir((*i).path);
2828 spath = sdir.sound_path().to_string();
2830 if (destructive) {
2832 if (nchan < 2) {
2833 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
2834 spath.c_str(), cnt, legalized.c_str());
2835 } else if (nchan == 2) {
2836 if (chan == 0) {
2837 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
2838 spath.c_str(), cnt, legalized.c_str());
2839 } else {
2840 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
2841 spath.c_str(), cnt, legalized.c_str());
2843 } else if (nchan < 26) {
2844 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
2845 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2846 } else {
2847 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
2848 spath.c_str(), cnt, legalized.c_str());
2851 } else {
2853 spath += '/';
2854 spath += legalized;
2856 if (nchan < 2) {
2857 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2858 } else if (nchan == 2) {
2859 if (chan == 0) {
2860 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2861 } else {
2862 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2864 } else if (nchan < 26) {
2865 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2866 } else {
2867 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2871 if (sys::exists(buf)) {
2872 existing++;
2877 if (existing == 0) {
2878 break;
2881 if (cnt > limit) {
2882 error << string_compose(
2883 _("There are already %1 recordings for %2, which I consider too many."),
2884 limit, base) << endmsg;
2885 destroy ();
2886 throw failed_constructor();
2890 return Glib::path_get_basename(buf);
2893 /** Create a new within-session audio source */
2894 boost::shared_ptr<AudioFileSource>
2895 Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
2897 const string name = new_audio_source_name (n, n_chans, chan, destructive);
2898 const string path = new_source_path_from_name(DataType::AUDIO, name);
2900 return boost::dynamic_pointer_cast<AudioFileSource> (
2901 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
2904 /** Return a unique name based on \a base for a new internal MIDI source */
2905 string
2906 Session::new_midi_source_name (const string& base)
2908 uint32_t cnt;
2909 char buf[PATH_MAX+1];
2910 const uint32_t limit = 10000;
2911 string legalized;
2913 buf[0] = '\0';
2914 legalized = legalize_for_path (base);
2916 // Find a "version" of the file name that doesn't exist in any of the possible directories.
2917 for (cnt = 1; cnt <= limit; ++cnt) {
2919 vector<space_and_path>::iterator i;
2920 uint32_t existing = 0;
2922 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2924 SessionDirectory sdir((*i).path);
2926 sys::path p = sdir.midi_path();
2927 p /= legalized;
2929 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
2931 if (sys::exists (buf)) {
2932 existing++;
2936 if (existing == 0) {
2937 break;
2940 if (cnt > limit) {
2941 error << string_compose(
2942 _("There are already %1 recordings for %2, which I consider too many."),
2943 limit, base) << endmsg;
2944 destroy ();
2945 throw failed_constructor();
2949 return Glib::path_get_basename(buf);
2953 /** Create a new within-session MIDI source */
2954 boost::shared_ptr<MidiSource>
2955 Session::create_midi_source_for_session (Track* track, string const & n)
2957 /* try to use the existing write source for the track, to keep numbering sane
2960 if (track) {
2961 /*MidiTrack* mt = dynamic_cast<Track*> (track);
2962 assert (mt);
2965 list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
2967 if (!l.empty()) {
2968 assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
2969 return boost::dynamic_pointer_cast<MidiSource> (l.front());
2973 const string name = new_midi_source_name (n);
2974 const string path = new_source_path_from_name (DataType::MIDI, name);
2976 return boost::dynamic_pointer_cast<SMFSource> (
2977 SourceFactory::createWritable (
2978 DataType::MIDI, *this, path, false, frame_rate()));
2982 void
2983 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
2985 if (playlist->hidden()) {
2986 return;
2989 playlists->add (playlist);
2991 if (unused) {
2992 playlist->release();
2995 set_dirty();
2998 void
2999 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3001 if (_state_of_the_state & Deletion) {
3002 return;
3005 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3007 if (!playlist) {
3008 return;
3011 playlists->remove (playlist);
3013 set_dirty();
3016 void
3017 Session::set_audition (boost::shared_ptr<Region> r)
3019 pending_audition_region = r;
3020 add_post_transport_work (PostTransportAudition);
3021 _butler->schedule_transport_work ();
3024 void
3025 Session::audition_playlist ()
3027 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3028 ev->region.reset ();
3029 queue_event (ev);
3032 void
3033 Session::non_realtime_set_audition ()
3035 if (!pending_audition_region) {
3036 auditioner->audition_current_playlist ();
3037 } else {
3038 auditioner->audition_region (pending_audition_region);
3039 pending_audition_region.reset ();
3041 AuditionActive (true); /* EMIT SIGNAL */
3044 void
3045 Session::audition_region (boost::shared_ptr<Region> r)
3047 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3048 ev->region = r;
3049 queue_event (ev);
3052 void
3053 Session::cancel_audition ()
3055 if (auditioner->auditioning()) {
3056 auditioner->cancel_audition ();
3057 AuditionActive (false); /* EMIT SIGNAL */
3061 bool
3062 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3064 if (a->is_monitor()) {
3065 return true;
3067 if (b->is_monitor()) {
3068 return false;
3070 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3073 void
3074 Session::remove_empty_sounds ()
3076 vector<string> audio_filenames;
3078 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3080 Glib::Mutex::Lock lm (source_lock);
3082 TapeFileMatcher tape_file_matcher;
3084 remove_if (audio_filenames.begin(), audio_filenames.end(),
3085 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3087 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3089 sys::path audio_file_path (_session_dir->sound_path());
3091 audio_file_path /= *i;
3093 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3097 sys::remove (audio_file_path);
3098 const string peakfile = peak_path (audio_file_path.to_string());
3099 sys::remove (peakfile);
3101 catch (const sys::filesystem_error& err)
3103 error << err.what() << endmsg;
3109 bool
3110 Session::is_auditioning () const
3112 /* can be called before we have an auditioner object */
3113 if (auditioner) {
3114 return auditioner->auditioning();
3115 } else {
3116 return false;
3120 void
3121 Session::graph_reordered ()
3123 /* don't do this stuff if we are setting up connections
3124 from a set_state() call or creating new tracks. Ditto for deletion.
3127 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3128 return;
3131 /* every track/bus asked for this to be handled but it was deferred because
3132 we were connecting. do it now.
3135 request_input_change_handling ();
3137 resort_routes ();
3139 /* force all diskstreams to update their capture offset values to
3140 reflect any changes in latencies within the graph.
3143 boost::shared_ptr<RouteList> rl = routes.reader ();
3144 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3145 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3146 if (tr) {
3147 tr->set_capture_offset ();
3152 nframes_t
3153 Session::available_capture_duration ()
3155 float sample_bytes_on_disk = 4.0; // keep gcc happy
3157 switch (config.get_native_file_data_format()) {
3158 case FormatFloat:
3159 sample_bytes_on_disk = 4.0;
3160 break;
3162 case FormatInt24:
3163 sample_bytes_on_disk = 3.0;
3164 break;
3166 case FormatInt16:
3167 sample_bytes_on_disk = 2.0;
3168 break;
3170 default:
3171 /* impossible, but keep some gcc versions happy */
3172 fatal << string_compose (_("programming error: %1"),
3173 X_("illegal native file data format"))
3174 << endmsg;
3175 /*NOTREACHED*/
3178 double scale = 4096.0 / sample_bytes_on_disk;
3180 if (_total_free_4k_blocks * scale > (double) max_frames) {
3181 return max_frames;
3184 return (nframes_t) floor (_total_free_4k_blocks * scale);
3187 void
3188 Session::add_bundle (shared_ptr<Bundle> bundle)
3191 RCUWriter<BundleList> writer (_bundles);
3192 boost::shared_ptr<BundleList> b = writer.get_copy ();
3193 b->push_back (bundle);
3196 BundleAdded (bundle); /* EMIT SIGNAL */
3198 set_dirty();
3201 void
3202 Session::remove_bundle (shared_ptr<Bundle> bundle)
3204 bool removed = false;
3207 RCUWriter<BundleList> writer (_bundles);
3208 boost::shared_ptr<BundleList> b = writer.get_copy ();
3209 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3211 if (i != b->end()) {
3212 b->erase (i);
3213 removed = true;
3217 if (removed) {
3218 BundleRemoved (bundle); /* EMIT SIGNAL */
3221 set_dirty();
3224 shared_ptr<Bundle>
3225 Session::bundle_by_name (string name) const
3227 boost::shared_ptr<BundleList> b = _bundles.reader ();
3229 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3230 if ((*i)->name() == name) {
3231 return* i;
3235 return boost::shared_ptr<Bundle> ();
3238 void
3239 Session::tempo_map_changed (const PropertyChange&)
3241 clear_clicks ();
3243 playlists->update_after_tempo_map_change ();
3245 set_dirty ();
3248 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3249 * the given count with the current block size.
3251 void
3252 Session::ensure_buffers (ChanCount howmany)
3254 BufferManager::ensure_buffers (howmany);
3257 void
3258 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3260 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3261 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3265 uint32_t
3266 Session::next_insert_id ()
3268 /* this doesn't really loop forever. just think about it */
3270 while (true) {
3271 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3272 if (!insert_bitset[n]) {
3273 insert_bitset[n] = true;
3274 return n;
3279 /* none available, so resize and try again */
3281 insert_bitset.resize (insert_bitset.size() + 16, false);
3285 uint32_t
3286 Session::next_send_id ()
3288 /* this doesn't really loop forever. just think about it */
3290 while (true) {
3291 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3292 if (!send_bitset[n]) {
3293 send_bitset[n] = true;
3294 return n;
3299 /* none available, so resize and try again */
3301 send_bitset.resize (send_bitset.size() + 16, false);
3305 uint32_t
3306 Session::next_return_id ()
3308 /* this doesn't really loop forever. just think about it */
3310 while (true) {
3311 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3312 if (!return_bitset[n]) {
3313 return_bitset[n] = true;
3314 return n;
3319 /* none available, so resize and try again */
3321 return_bitset.resize (return_bitset.size() + 16, false);
3325 void
3326 Session::mark_send_id (uint32_t id)
3328 if (id >= send_bitset.size()) {
3329 send_bitset.resize (id+16, false);
3331 if (send_bitset[id]) {
3332 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3334 send_bitset[id] = true;
3337 void
3338 Session::mark_return_id (uint32_t id)
3340 if (id >= return_bitset.size()) {
3341 return_bitset.resize (id+16, false);
3343 if (return_bitset[id]) {
3344 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3346 return_bitset[id] = true;
3349 void
3350 Session::mark_insert_id (uint32_t id)
3352 if (id >= insert_bitset.size()) {
3353 insert_bitset.resize (id+16, false);
3355 if (insert_bitset[id]) {
3356 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3358 insert_bitset[id] = true;
3361 void
3362 Session::unmark_send_id (uint32_t id)
3364 if (id < send_bitset.size()) {
3365 send_bitset[id] = false;
3369 void
3370 Session::unmark_return_id (uint32_t id)
3372 if (id < return_bitset.size()) {
3373 return_bitset[id] = false;
3377 void
3378 Session::unmark_insert_id (uint32_t id)
3380 if (id < insert_bitset.size()) {
3381 insert_bitset[id] = false;
3386 /* Named Selection management */
3388 boost::shared_ptr<NamedSelection>
3389 Session::named_selection_by_name (string name)
3391 Glib::Mutex::Lock lm (named_selection_lock);
3392 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3393 if ((*i)->name == name) {
3394 return *i;
3397 return boost::shared_ptr<NamedSelection>();
3400 void
3401 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3404 Glib::Mutex::Lock lm (named_selection_lock);
3405 named_selections.insert (named_selections.begin(), named_selection);
3408 set_dirty();
3410 NamedSelectionAdded (); /* EMIT SIGNAL */
3413 void
3414 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3416 bool removed = false;
3419 Glib::Mutex::Lock lm (named_selection_lock);
3421 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3423 if (i != named_selections.end()) {
3424 named_selections.erase (i);
3425 set_dirty();
3426 removed = true;
3430 if (removed) {
3431 NamedSelectionRemoved (); /* EMIT SIGNAL */
3435 void
3436 Session::reset_native_file_format ()
3438 boost::shared_ptr<RouteList> rl = routes.reader ();
3439 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3440 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3441 if (tr) {
3442 tr->reset_write_sources (false);
3447 bool
3448 Session::route_name_unique (string n) const
3450 shared_ptr<RouteList> r = routes.reader ();
3452 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3453 if ((*i)->name() == n) {
3454 return false;
3458 return true;
3461 bool
3462 Session::route_name_internal (string n) const
3464 if (auditioner && auditioner->name() == n) {
3465 return true;
3468 if (_click_io && _click_io->name() == n) {
3469 return true;
3472 return false;
3476 Session::freeze_all (InterThreadInfo& itt)
3478 shared_ptr<RouteList> r = routes.reader ();
3480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3482 boost::shared_ptr<Track> t;
3484 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3485 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3486 of every track.
3488 t->freeze_me (itt);
3492 return 0;
3495 boost::shared_ptr<Region>
3496 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3497 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3498 InterThreadInfo& itt, bool enable_processing)
3500 boost::shared_ptr<Region> result;
3501 boost::shared_ptr<Playlist> playlist;
3502 boost::shared_ptr<AudioFileSource> fsource;
3503 uint32_t x;
3504 char buf[PATH_MAX+1];
3505 ChanCount nchans(track.n_channels());
3506 nframes_t position;
3507 nframes_t this_chunk;
3508 nframes_t to_do;
3509 BufferSet buffers;
3510 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3511 const string sound_dir = sdir.sound_path().to_string();
3512 nframes_t len = end - start;
3514 if (end <= start) {
3515 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3516 end, start) << endmsg;
3517 return result;
3520 const nframes_t chunk_size = (256 * 1024)/4;
3522 // block all process callback handling
3524 block_processing ();
3526 /* call tree *MUST* hold route_lock */
3528 if ((playlist = track.playlist()) == 0) {
3529 goto out;
3532 /* external redirects will be a problem */
3534 if (track.has_external_redirects()) {
3535 goto out;
3538 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3540 for (x = 0; x < 99999; ++x) {
3541 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3542 if (access (buf, F_OK) != 0) {
3543 break;
3547 if (x == 99999) {
3548 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3549 goto out;
3552 try {
3553 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3554 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3557 catch (failed_constructor& err) {
3558 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3559 goto out;
3562 srcs.push_back (fsource);
3565 /* XXX need to flush all redirects */
3567 position = start;
3568 to_do = len;
3570 /* create a set of reasonably-sized buffers */
3571 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
3572 buffers.set_count(nchans);
3574 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3575 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3576 if (afs)
3577 afs->prepare_for_peakfile_writes ();
3580 while (to_do && !itt.cancel) {
3582 this_chunk = min (to_do, chunk_size);
3584 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
3585 goto out;
3588 uint32_t n = 0;
3589 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3590 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3592 if (afs) {
3593 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3594 goto out;
3599 start += this_chunk;
3600 to_do -= this_chunk;
3602 itt.progress = (float) (1.0 - ((double) to_do / len));
3606 if (!itt.cancel) {
3608 time_t now;
3609 struct tm* xnow;
3610 time (&now);
3611 xnow = localtime (&now);
3613 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3614 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3616 if (afs) {
3617 afs->update_header (position, *xnow, now);
3618 afs->flush_header ();
3622 /* construct a region to represent the bounced material */
3624 PropertyList plist;
3626 plist.add (Properties::start, 0);
3627 plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
3628 plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
3630 result = RegionFactory::create (srcs, plist);
3634 out:
3635 if (!result) {
3636 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3637 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3639 if (afs) {
3640 afs->mark_for_remove ();
3643 (*src)->drop_references ();
3646 } else {
3647 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3648 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3650 if (afs)
3651 afs->done_with_peakfile_writes ();
3655 unblock_processing ();
3657 return result;
3660 gain_t*
3661 Session::gain_automation_buffer() const
3663 return ProcessThread::gain_automation_buffer ();
3666 pan_t**
3667 Session::pan_automation_buffer() const
3669 return ProcessThread::pan_automation_buffer ();
3672 BufferSet&
3673 Session::get_silent_buffers (ChanCount count)
3675 return ProcessThread::get_silent_buffers (count);
3676 #if 0
3677 assert(_silent_buffers->available() >= count);
3678 _silent_buffers->set_count(count);
3680 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3681 for (size_t i= 0; i < count.get(*t); ++i) {
3682 _silent_buffers->get(*t, i).clear();
3686 return *_silent_buffers;
3687 #endif
3690 BufferSet&
3691 Session::get_scratch_buffers (ChanCount count)
3693 return ProcessThread::get_scratch_buffers (count);
3694 #if 0
3695 if (count != ChanCount::ZERO) {
3696 assert(_scratch_buffers->available() >= count);
3697 _scratch_buffers->set_count(count);
3698 } else {
3699 _scratch_buffers->set_count (_scratch_buffers->available());
3702 return *_scratch_buffers;
3703 #endif
3706 BufferSet&
3707 Session::get_mix_buffers (ChanCount count)
3709 return ProcessThread::get_mix_buffers (count);
3710 #if 0
3711 assert(_mix_buffers->available() >= count);
3712 _mix_buffers->set_count(count);
3713 return *_mix_buffers;
3714 #endif
3717 uint32_t
3718 Session::ntracks () const
3720 uint32_t n = 0;
3721 shared_ptr<RouteList> r = routes.reader ();
3723 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3724 if (boost::dynamic_pointer_cast<Track> (*i)) {
3725 ++n;
3729 return n;
3732 uint32_t
3733 Session::nbusses () const
3735 uint32_t n = 0;
3736 shared_ptr<RouteList> r = routes.reader ();
3738 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3739 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
3740 ++n;
3744 return n;
3747 void
3748 Session::add_automation_list(AutomationList *al)
3750 automation_lists[al->id()] = al;
3753 void
3754 Session::sync_order_keys (std::string const & base)
3756 if (deletion_in_progress()) {
3757 return;
3760 if (!Config->get_sync_all_route_ordering()) {
3761 /* leave order keys as they are */
3762 return;
3765 boost::shared_ptr<RouteList> r = routes.reader ();
3767 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3768 (*i)->sync_order_keys (base);
3771 Route::SyncOrderKeys (base); // EMIT SIGNAL
3773 /* this might not do anything */
3775 set_remote_control_ids ();
3778 /** @return true if there is at least one record-enabled track, otherwise false */
3779 bool
3780 Session::have_rec_enabled_track () const
3782 return g_atomic_int_get (&_have_rec_enabled_track) == 1;
3785 /** Update the state of our rec-enabled tracks flag */
3786 void
3787 Session::update_have_rec_enabled_track ()
3789 boost::shared_ptr<RouteList> rl = routes.reader ();
3790 RouteList::iterator i = rl->begin();
3791 while (i != rl->end ()) {
3793 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3794 if (tr && tr->record_enabled ()) {
3795 break;
3798 ++i;
3801 int const old = g_atomic_int_get (&_have_rec_enabled_track);
3803 g_atomic_int_set (&_have_rec_enabled_track, i != rl->end () ? 1 : 0);
3805 if (g_atomic_int_get (&_have_rec_enabled_track) != old) {
3806 RecordStateChanged (); /* EMIT SIGNAL */
3810 void
3811 Session::listen_position_changed ()
3813 Placement p;
3815 switch (Config->get_listen_position()) {
3816 case AfterFaderListen:
3817 p = PostFader;
3818 break;
3820 case PreFaderListen:
3821 p = PreFader;
3822 break;
3825 boost::shared_ptr<RouteList> r = routes.reader ();
3827 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3828 (*i)->put_monitor_send_at (p);
3832 void
3833 Session::solo_control_mode_changed ()
3835 /* cancel all solo or all listen when solo control mode changes */
3837 if (soloing()) {
3838 set_solo (get_routes(), false);
3839 } else if (listening()) {
3840 set_listen (get_routes(), false);
3844 /** Called when anything about any of our route groups changes (membership, state etc.) */
3845 void
3846 Session::route_group_changed ()
3848 RouteGroupChanged (); /* EMIT SIGNAL */
3851 vector<SyncSource>
3852 Session::get_available_sync_options () const
3854 vector<SyncSource> ret;
3856 ret.push_back (JACK);
3858 if (mtc_port()) {
3859 ret.push_back (MTC);
3862 if (midi_clock_port()) {
3863 ret.push_back (MIDIClock);
3866 return ret;
3869 boost::shared_ptr<RouteList>
3870 Session::get_routes_with_regions_at (nframes64_t const p) const
3872 shared_ptr<RouteList> r = routes.reader ();
3873 shared_ptr<RouteList> rl (new RouteList);
3875 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3876 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3877 if (!tr) {
3878 continue;
3881 boost::shared_ptr<Playlist> pl = tr->playlist ();
3882 if (!pl) {
3883 continue;
3886 if (pl->has_region_at (p)) {
3887 rl->push_back (*i);
3891 return rl;
3894 void
3895 Session::goto_end ()
3897 if (_session_range_location) {
3898 request_locate (_session_range_location->end(), false);
3899 } else {
3900 request_locate (0, false);
3904 void
3905 Session::goto_start ()
3907 if (_session_range_location) {
3908 request_locate (_session_range_location->start(), false);
3909 } else {
3910 request_locate (0, false);
3914 void
3915 Session::set_session_start (nframes_t start)
3917 if (_session_range_location) {
3918 _session_range_location->set_start (start);
3919 } else {
3920 add_session_range_location (start, start);
3924 void
3925 Session::set_session_end (nframes_t end)
3927 if (_session_range_location) {
3928 _session_range_location->set_end (end);
3929 } else {
3930 add_session_range_location (end, end);
3934 nframes_t
3935 Session::current_start_frame () const
3937 return _session_range_location ? _session_range_location->start() : 0;
3940 nframes_t
3941 Session::current_end_frame () const
3943 return _session_range_location ? _session_range_location->end() : 0;
3946 void
3947 Session::add_session_range_location (nframes_t start, nframes_t end)
3949 _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange);
3950 _locations.add (_session_range_location);