2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <glibmm/thread.h>
33 #include <glibmm/miscutils.h>
34 #include <glibmm/fileutils.h>
35 #include <glibmm/thread.h>
37 #include "pbd/error.h"
38 #include "pbd/boost_debug.h"
39 #include "pbd/pathscanner.h"
40 #include "pbd/stl_delete.h"
41 #include "pbd/basename.h"
42 #include "pbd/stacktrace.h"
43 #include "pbd/file_utils.h"
45 #include "ardour/amp.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_port.h"
50 #include "ardour/audio_track.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/audiofilesource.h"
53 #include "ardour/audioplaylist.h"
54 #include "ardour/audioregion.h"
55 #include "ardour/auditioner.h"
56 #include "ardour/buffer_set.h"
57 #include "ardour/bundle.h"
58 #include "ardour/butler.h"
59 #include "ardour/click.h"
60 #include "ardour/configuration.h"
61 #include "ardour/crossfade.h"
62 #include "ardour/cycle_timer.h"
63 #include "ardour/data_type.h"
64 #include "ardour/debug.h"
65 #include "ardour/filename_extensions.h"
66 #include "ardour/internal_send.h"
67 #include "ardour/io_processor.h"
68 #include "ardour/midi_diskstream.h"
69 #include "ardour/midi_playlist.h"
70 #include "ardour/midi_region.h"
71 #include "ardour/midi_track.h"
72 #include "ardour/midi_ui.h"
73 #include "ardour/named_selection.h"
74 #include "ardour/playlist.h"
75 #include "ardour/plugin_insert.h"
76 #include "ardour/port_insert.h"
77 #include "ardour/processor.h"
78 #include "ardour/rc_configuration.h"
79 #include "ardour/recent_sessions.h"
80 #include "ardour/region_factory.h"
81 #include "ardour/return.h"
82 #include "ardour/route_group.h"
83 #include "ardour/send.h"
84 #include "ardour/session.h"
85 #include "ardour/session_directory.h"
86 #include "ardour/session_directory.h"
87 #include "ardour/session_metadata.h"
88 #include "ardour/session_playlists.h"
89 #include "ardour/slave.h"
90 #include "ardour/smf_source.h"
91 #include "ardour/source_factory.h"
92 #include "ardour/tape_file_matcher.h"
93 #include "ardour/tempo.h"
94 #include "ardour/utils.h"
96 #include "midi++/jack.h"
101 using namespace ARDOUR;
103 using boost::shared_ptr;
104 using boost::weak_ptr;
106 bool Session::_disable_all_loaded_plugins = false;
108 PBD::Signal1<void,std::string> Session::Dialog;
109 PBD::Signal0<int> Session::AskAboutPendingState;
110 PBD::Signal2<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
111 PBD::Signal0<void> Session::SendFeedback;
113 PBD::Signal0<void> Session::TimecodeOffsetChanged;
114 PBD::Signal0<void> Session::StartTimeChanged;
115 PBD::Signal0<void> Session::EndTimeChanged;
116 PBD::Signal0<void> Session::AutoBindingOn;
117 PBD::Signal0<void> Session::AutoBindingOff;
118 PBD::Signal2<void,std::string, std::string> Session::Exported;
119 PBD::Signal1<int,boost::shared_ptr<Playlist> > Session::AskAboutPlaylistDeletion;
121 static void clean_up_session_event (SessionEvent* ev) { delete ev; }
122 const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event);
124 Session::Session (AudioEngine &eng,
125 const string& fullpath,
126 const string& snapshot_name,
130 _target_transport_speed (0.0),
131 _requested_return_frame (-1),
132 _scratch_buffers(new BufferSet()),
133 _silent_buffers(new BufferSet()),
134 _mix_buffers(new BufferSet()),
136 _mmc_port (default_mmc_port),
137 _mtc_port (default_mtc_port),
138 _midi_port (default_midi_port),
139 _midi_clock_port (default_midi_clock_port),
140 _session_dir (new SessionDirectory(fullpath)),
142 _butler (new Butler (*this)),
143 _post_transport_work (0),
144 _send_timecode_update (false),
145 diskstreams (new DiskstreamList),
146 routes (new RouteList),
147 _total_free_4k_blocks (0),
148 _bundles (new BundleList),
149 _bundle_xml_node (0),
152 click_emphasis_data (0),
154 _metadata (new SessionMetadata()),
155 _have_rec_enabled_diskstream (false)
158 playlists.reset (new SessionPlaylists);
162 interpolation.add_channel_to (0, 0);
164 if (!eng.connected()) {
165 throw failed_constructor();
168 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
170 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
171 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
173 first_stage_init (fullpath, snapshot_name);
175 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
178 if (create (new_session, mix_template, compute_initial_length())) {
180 throw failed_constructor ();
184 if (second_stage_init (new_session)) {
186 throw failed_constructor ();
189 store_recent_sessions(_name, _path);
191 bool was_dirty = dirty();
193 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
195 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
196 config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true));
199 DirtyChanged (); /* EMIT SIGNAL */
203 Session::Session (AudioEngine &eng,
205 string snapshot_name,
206 AutoConnectOption input_ac,
207 AutoConnectOption output_ac,
208 uint32_t control_out_channels,
209 uint32_t master_out_channels,
210 uint32_t requested_physical_in,
211 uint32_t requested_physical_out,
212 nframes_t initial_length)
215 _target_transport_speed (0.0),
216 _requested_return_frame (-1),
217 _scratch_buffers(new BufferSet()),
218 _silent_buffers(new BufferSet()),
219 _mix_buffers(new BufferSet()),
221 _mmc_port (default_mmc_port),
222 _mtc_port (default_mtc_port),
223 _midi_port (default_midi_port),
224 _midi_clock_port (default_midi_clock_port),
225 _session_dir ( new SessionDirectory(fullpath)),
227 _butler (new Butler (*this)),
228 _post_transport_work (0),
229 _send_timecode_update (false),
230 diskstreams (new DiskstreamList),
231 routes (new RouteList),
232 _total_free_4k_blocks (0),
233 _bundles (new BundleList),
234 _bundle_xml_node (0),
235 _click_io ((IO *) 0),
237 click_emphasis_data (0),
239 _metadata (new SessionMetadata()),
240 _have_rec_enabled_diskstream (false)
242 playlists.reset (new SessionPlaylists);
246 interpolation.add_channel_to (0, 0);
248 if (!eng.connected()) {
249 throw failed_constructor();
252 info << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
254 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
255 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
257 if (n_physical_inputs) {
258 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
261 if (n_physical_outputs) {
262 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
265 first_stage_init (fullpath, snapshot_name);
267 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
270 if (create (new_session, string(), initial_length)) {
272 throw failed_constructor ();
277 /* set up Master Out and Control Out if necessary */
282 if (master_out_channels) {
283 ChanCount count(DataType::AUDIO, master_out_channels);
284 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
285 boost_debug_shared_ptr_mark_interesting (rt, "Route");
286 boost::shared_ptr<Route> r (rt);
287 r->input()->ensure_io (count, false, this);
288 r->output()->ensure_io (count, false, this);
289 r->set_remote_control_id (control_id);
293 /* prohibit auto-connect to master, because there isn't one */
294 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
297 if (control_out_channels) {
298 ChanCount count(DataType::AUDIO, control_out_channels);
299 Route* rt = new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO);
300 boost_debug_shared_ptr_mark_interesting (rt, "Route");
301 shared_ptr<Route> r (rt);
302 r->input()->ensure_io (count, false, this);
303 r->output()->ensure_io (count, false, this);
304 r->set_remote_control_id (control_id++);
310 add_routes (rl, false);
315 if (no_auto_connect()) {
316 input_ac = AutoConnectOption (0);
317 output_ac = AutoConnectOption (0);
320 Config->set_input_auto_connect (input_ac);
321 Config->set_output_auto_connect (output_ac);
323 if (second_stage_init (new_session)) {
325 throw failed_constructor ();
328 store_recent_sessions (_name, _path);
330 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
332 Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false));
343 vector<void*> debug_pointers;
345 /* if we got to here, leaving pending capture state around
349 remove_pending_capture_state ();
351 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
353 _engine.remove_session ();
355 /* clear region map. it doesn't hold references, but lets just be sensible here */
357 RegionFactory::clear_map ();
359 /* clear history so that no references to objects are held any more */
363 /* clear state tree so that no references to objects are held any more */
367 /* reset dynamic state version back to default */
369 Stateful::loading_state_version = 0;
372 delete midi_control_ui;
374 if (click_data != default_click) {
375 delete [] click_data;
378 if (click_emphasis_data != default_click_emphasis) {
379 delete [] click_emphasis_data;
384 delete _scratch_buffers;
385 delete _silent_buffers;
388 /* clear out any pending dead wood from RCU managed objects */
391 diskstreams.flush ();
394 AudioDiskstream::free_working_buffers();
396 /* tell everyone who is still standing that we're about to die */
399 /* tell everyone to drop references and delete objects as we go */
401 DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
402 named_selections.clear ();
404 DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
405 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
406 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
407 i->second->drop_references ();
411 DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
413 /* reset these three references to special routes before we do the usual route delete thing */
416 _master_out.reset ();
417 _control_out.reset ();
420 RCUWriter<RouteList> writer (routes);
421 boost::shared_ptr<RouteList> r = writer.get_copy ();
423 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
424 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
425 (*i)->drop_references ();
429 /* writer goes out of scope and updates master */
433 boost::shared_ptr<RouteList> r = routes.reader ();
435 DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n");
437 RCUWriter<DiskstreamList> dwriter (diskstreams);
438 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
439 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
440 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
441 (*i)->drop_references ();
446 diskstreams.flush ();
448 DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
449 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
450 DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
451 i->second->drop_references ();
456 DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
457 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
462 Crossfade::set_buffer_size (0);
466 /* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
469 boost_debug_list_ptrs ();
471 DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
475 Session::set_worst_io_latencies ()
477 _worst_output_latency = 0;
478 _worst_input_latency = 0;
480 if (!_engine.connected()) {
484 boost::shared_ptr<RouteList> r = routes.reader ();
486 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
487 _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency());
488 _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency());
493 Session::when_engine_running ()
495 string first_physical_output;
497 BootMessage (_("Set block size and sample rate"));
499 set_block_size (_engine.frames_per_cycle());
500 set_frame_rate (_engine.frame_rate());
502 BootMessage (_("Using configuration"));
504 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
505 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
507 Config->map_parameters (ff);
508 config.map_parameters (ft);
510 /* every time we reconnect, recompute worst case output latencies */
512 _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this));
514 if (synced_to_jack()) {
515 _engine.transport_stop ();
518 if (config.get_jack_time_master()) {
519 _engine.transport_locate (_transport_frame);
527 _click_io.reset (new ClickIO (*this, "click"));
529 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
531 /* existing state for Click */
534 if (Stateful::loading_state_version < 3000) {
535 c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
537 c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
542 _clicking = Config->get_clicking ();
546 error << _("could not setup Click I/O") << endmsg;
553 /* default state for Click: dual-mono to first 2 physical outputs */
555 for (int physport = 0; physport < 2; ++physport) {
556 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
558 if (physical_output.length()) {
559 if (_click_io->add_port (physical_output, this)) {
560 // relax, even though its an error
565 if (_click_io->n_ports () > ChanCount::ZERO) {
566 _clicking = Config->get_clicking ();
571 catch (failed_constructor& err) {
572 error << _("cannot setup Click I/O") << endmsg;
575 BootMessage (_("Compute I/O Latencies"));
577 set_worst_io_latencies ();
580 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
583 BootMessage (_("Set up standard connections"));
585 /* Create a set of Bundle objects that map
586 to the physical I/O currently available. We create both
587 mono and stereo bundles, so that the common cases of mono
588 and stereo tracks get bundles to put in their mixer strip
589 in / out menus. There may be a nicer way of achieving that;
590 it doesn't really scale that well to higher channel counts
593 /* mono output bundles */
595 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
597 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
599 shared_ptr<Bundle> c (new Bundle (buf, true));
600 c->add_channel (_("mono"));
601 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
606 /* stereo output bundles */
608 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
609 if (np + 1 < n_physical_outputs) {
611 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
612 shared_ptr<Bundle> c (new Bundle (buf, true));
613 c->add_channel (_("L"));
614 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
615 c->add_channel (_("R"));
616 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
622 /* mono input bundles */
624 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
626 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
628 shared_ptr<Bundle> c (new Bundle (buf, false));
629 c->add_channel (_("mono"));
630 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
635 /* stereo input bundles */
637 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
638 if (np + 1 < n_physical_inputs) {
640 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
642 shared_ptr<Bundle> c (new Bundle (buf, false));
643 c->add_channel (_("L"));
644 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
645 c->add_channel (_("R"));
646 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
652 BootMessage (_("Setup signal flow and plugins"));
656 if (!no_auto_connect()) {
658 if (_master_out && Config->get_auto_connect_standard_busses()) {
660 /* if requested auto-connect the outputs to the first N physical ports.
663 uint32_t limit = _master_out->n_outputs().n_total();
665 for (uint32_t n = 0; n < limit; ++n) {
666 Port* p = _master_out->output()->nth (n);
667 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
669 if (!connect_to.empty() && p->connected_to (connect_to) == false) {
670 if (_master_out->output()->connect (p, connect_to, this)) {
671 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
681 /* AUDIO ONLY as of june 29th 2009, because listen semantics for anything else
682 are undefined, at best.
685 /* control out listens to master bus (but ignores it
686 under some conditions)
689 uint32_t limit = _control_out->n_inputs().n_audio();
692 for (uint32_t n = 0; n < limit; ++n) {
693 AudioPort* p = _control_out->input()->ports().nth_audio_port (n);
694 AudioPort* o = _master_out->output()->ports().nth_audio_port (n);
697 string connect_to = o->name();
698 if (_control_out->input()->connect (p, connect_to, this)) {
699 error << string_compose (_("cannot connect control input %1 to %2"), n, connect_to)
707 /* if control out is not connected,
708 connect control out to physical outs, but use ones after the master if possible
711 if (!_control_out->output()->connected_to (boost::shared_ptr<IO>())) {
713 if (!Config->get_monitor_bus_preferred_bundle().empty()) {
715 boost::shared_ptr<Bundle> b = bundle_by_name (Config->get_monitor_bus_preferred_bundle());
718 _control_out->output()->connect_ports_to_bundle (b, this);
720 warning << string_compose (_("The preferred I/O for the monitor bus (%1) cannot be found"),
721 Config->get_monitor_bus_preferred_bundle())
727 /* XXX this logic is wrong for mixed port types */
729 uint32_t shift = _master_out->n_outputs().n_audio();
730 uint32_t mod = _engine.n_physical_outputs (DataType::AUDIO);
731 limit = _control_out->n_outputs().n_audio();
733 cerr << "Connecting " << limit << " control out ports, shift is " << shift << " mod is " << mod << endl;
735 for (uint32_t n = 0; n < limit; ++n) {
737 Port* p = _control_out->output()->nth (n);
738 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), (n+shift) % mod);
740 if (!connect_to.empty()) {
741 if (_control_out->output()->connect (p, connect_to, this)) {
742 error << string_compose (_("cannot connect control output %1 to %2"), n, connect_to)
753 /* catch up on send+insert cnts */
755 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
757 /* hook us up to the engine */
759 BootMessage (_("Connect to engine"));
761 _engine.set_session (this);
765 Session::hookup_io ()
767 /* stop graph reordering notifications from
768 causing resorts, etc.
771 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
776 /* we delay creating the auditioner till now because
777 it makes its own connections to ports.
778 the engine has to be running for this to work.
782 auditioner.reset (new Auditioner (*this));
785 catch (failed_constructor& err) {
786 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
790 /* load bundles, which we may have postponed earlier on */
791 if (_bundle_xml_node) {
792 load_bundles (*_bundle_xml_node);
793 delete _bundle_xml_node;
796 /* Tell all IO objects to connect themselves together */
798 IO::enable_connecting ();
799 MIDI::JACK_MidiPort::MakeConnections ();
801 /* Now reset all panners */
803 Delivery::reset_panners ();
805 /* Connect tracks to listen/solo etc. busses XXX generalize this beyond control_out */
809 boost::shared_ptr<RouteList> r = routes.reader ();
811 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
813 if ((*x)->is_control() || (*x)->is_master()) {
817 (*x)->listen_via (_control_out,
818 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
823 /* Anyone who cares about input state, wake up and do something */
825 IOConnectionsComplete (); /* EMIT SIGNAL */
827 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
829 /* now handle the whole enchilada as if it was one
835 /* update the full solo state, which can't be
836 correctly determined on a per-route basis, but
837 needs the global overview that only the session
841 update_route_solo_state ();
845 Session::playlist_length_changed ()
847 /* we can't just increase end_location->end() if pl->get_maximum_extent()
848 if larger. if the playlist used to be the longest playlist,
849 and its now shorter, we have to decrease end_location->end(). hence,
850 we have to iterate over all diskstreams and check the
851 playlists currently in use.
857 Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
859 boost::shared_ptr<Diskstream> dstream = wp.lock ();
864 boost::shared_ptr<Playlist> playlist;
866 if ((playlist = dstream->playlist()) != 0) {
867 playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
870 /* see comment in playlist_length_changed () */
875 Session::record_enabling_legal () const
877 /* this used to be in here, but survey says.... we don't need to restrict it */
878 // if (record_status() == Recording) {
882 if (Config->get_all_safe()) {
889 Session::reset_input_monitor_state ()
891 if (transport_rolling()) {
893 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
895 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
896 if ((*i)->record_enabled ()) {
897 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
898 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
902 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
904 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
905 if ((*i)->record_enabled ()) {
906 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
907 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
914 Session::auto_punch_start_changed (Location* location)
916 replace_event (SessionEvent::PunchIn, location->start());
918 if (get_record_enabled() && config.get_punch_in()) {
919 /* capture start has been changed, so save new pending state */
920 save_state ("", true);
925 Session::auto_punch_end_changed (Location* location)
927 nframes_t when_to_stop = location->end();
928 // when_to_stop += _worst_output_latency + _worst_input_latency;
929 replace_event (SessionEvent::PunchOut, when_to_stop);
933 Session::auto_punch_changed (Location* location)
935 nframes_t when_to_stop = location->end();
937 replace_event (SessionEvent::PunchIn, location->start());
938 //when_to_stop += _worst_output_latency + _worst_input_latency;
939 replace_event (SessionEvent::PunchOut, when_to_stop);
943 Session::auto_loop_changed (Location* location)
945 replace_event (SessionEvent::AutoLoop, location->end(), location->start());
947 if (transport_rolling() && play_loop) {
950 // if (_transport_frame > location->end()) {
952 if (_transport_frame < location->start() || _transport_frame > location->end()) {
953 // relocate to beginning of loop
954 clear_events (SessionEvent::LocateRoll);
956 request_locate (location->start(), true);
959 else if (Config->get_seamless_loop() && !loop_changing) {
961 // schedule a locate-roll to refill the diskstreams at the
963 loop_changing = true;
965 if (location->end() > last_loopend) {
966 clear_events (SessionEvent::LocateRoll);
967 SessionEvent *ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, last_loopend, last_loopend, 0, true);
974 last_loopend = location->end();
978 Session::set_auto_punch_location (Location* location)
982 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
983 punch_connections.drop_connections();
984 existing->set_auto_punch (false, this);
985 remove_event (existing->start(), SessionEvent::PunchIn);
986 clear_events (SessionEvent::PunchOut);
987 auto_punch_location_changed (0);
996 if (location->end() <= location->start()) {
997 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1001 punch_connections.drop_connections ();
1003 location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1));
1004 location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1));
1005 location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1));
1007 location->set_auto_punch (true, this);
1009 auto_punch_changed (location);
1011 auto_punch_location_changed (location);
1015 Session::set_auto_loop_location (Location* location)
1019 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1020 loop_connections.drop_connections ();
1021 existing->set_auto_loop (false, this);
1022 remove_event (existing->end(), SessionEvent::AutoLoop);
1023 auto_loop_location_changed (0);
1028 if (location == 0) {
1032 if (location->end() <= location->start()) {
1033 error << _("Session: you can't use a mark for auto loop") << endmsg;
1037 last_loopend = location->end();
1039 loop_connections.drop_connections ();
1041 location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1042 location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1043 location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1));
1045 location->set_auto_loop (true, this);
1047 /* take care of our stuff first */
1049 auto_loop_changed (location);
1051 /* now tell everyone else */
1053 auto_loop_location_changed (location);
1057 Session::locations_added (Location *)
1063 Session::locations_changed ()
1065 _locations.apply (*this, &Session::handle_locations_changed);
1069 Session::handle_locations_changed (Locations::LocationList& locations)
1071 Locations::LocationList::iterator i;
1073 bool set_loop = false;
1074 bool set_punch = false;
1076 for (i = locations.begin(); i != locations.end(); ++i) {
1080 if (location->is_auto_punch()) {
1081 set_auto_punch_location (location);
1084 if (location->is_auto_loop()) {
1085 set_auto_loop_location (location);
1089 if (location->is_start()) {
1090 start_location = location;
1092 if (location->is_end()) {
1093 end_location = location;
1098 set_auto_loop_location (0);
1101 set_auto_punch_location (0);
1108 Session::enable_record ()
1110 /* XXX really atomic compare+swap here */
1111 if (g_atomic_int_get (&_record_status) != Recording) {
1112 g_atomic_int_set (&_record_status, Recording);
1113 _last_record_location = _transport_frame;
1114 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1116 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1117 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1118 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1119 if ((*i)->record_enabled ()) {
1120 (*i)->monitor_input (true);
1125 RecordStateChanged ();
1130 Session::disable_record (bool rt_context, bool force)
1134 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1136 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1137 g_atomic_int_set (&_record_status, Disabled);
1139 if (rs == Recording) {
1140 g_atomic_int_set (&_record_status, Enabled);
1144 // FIXME: timestamp correct? [DR]
1145 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1146 // does this /need/ to be sent in all cases?
1148 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1151 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1152 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1154 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1155 if ((*i)->record_enabled ()) {
1156 (*i)->monitor_input (false);
1161 RecordStateChanged (); /* emit signal */
1164 remove_pending_capture_state ();
1170 Session::step_back_from_record ()
1172 /* XXX really atomic compare+swap here */
1173 if (g_atomic_int_get (&_record_status) == Recording) {
1174 g_atomic_int_set (&_record_status, Enabled);
1176 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1177 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1179 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1180 if ((*i)->record_enabled ()) {
1181 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1182 (*i)->monitor_input (false);
1190 Session::maybe_enable_record ()
1192 g_atomic_int_set (&_record_status, Enabled);
1194 /* this function is currently called from somewhere other than an RT thread.
1195 this save_state() call therefore doesn't impact anything.
1198 save_state ("", true);
1200 if (_transport_speed) {
1201 if (!config.get_punch_in()) {
1205 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1206 RecordStateChanged (); /* EMIT SIGNAL */
1213 Session::audible_frame () const
1219 /* the first of these two possible settings for "offset"
1220 mean that the audible frame is stationary until
1221 audio emerges from the latency compensation
1224 the second means that the audible frame is stationary
1225 until audio would emerge from a physical port
1226 in the absence of any plugin latency compensation
1229 offset = _worst_output_latency;
1231 if (offset > current_block_size) {
1232 offset -= current_block_size;
1234 /* XXX is this correct? if we have no external
1235 physical connections and everything is internal
1236 then surely this is zero? still, how
1237 likely is that anyway?
1239 offset = current_block_size;
1242 if (synced_to_jack()) {
1243 tf = _engine.transport_frame();
1245 tf = _transport_frame;
1250 if (!non_realtime_work_pending()) {
1254 /* check to see if we have passed the first guaranteed
1255 audible frame past our last start position. if not,
1256 return that last start point because in terms
1257 of audible frames, we have not moved yet.
1260 if (_transport_speed > 0.0f) {
1262 if (!play_loop || !have_looped) {
1263 if (tf < _last_roll_location + offset) {
1264 return _last_roll_location;
1272 } else if (_transport_speed < 0.0f) {
1274 /* XXX wot? no backward looping? */
1276 if (tf > _last_roll_location - offset) {
1277 return _last_roll_location;
1289 Session::set_frame_rate (nframes_t frames_per_second)
1291 /** \fn void Session::set_frame_size(nframes_t)
1292 the AudioEngine object that calls this guarantees
1293 that it will not be called while we are also in
1294 ::process(). Its fine to do things that block
1298 _base_frame_rate = frames_per_second;
1302 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1306 // XXX we need some equivalent to this, somehow
1307 // SndFileSource::setup_standard_crossfades (frames_per_second);
1311 /* XXX need to reset/reinstantiate all LADSPA plugins */
1315 Session::set_block_size (nframes_t nframes)
1317 /* the AudioEngine guarantees
1318 that it will not be called while we are also in
1319 ::process(). It is therefore fine to do things that block
1324 current_block_size = nframes;
1326 ensure_buffers(_scratch_buffers->available());
1328 delete [] _gain_automation_buffer;
1329 _gain_automation_buffer = new gain_t[nframes];
1331 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1333 boost::shared_ptr<RouteList> r = routes.reader ();
1335 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1336 (*i)->set_block_size (nframes);
1339 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1340 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1341 (*i)->set_block_size (nframes);
1344 set_worst_io_latencies ();
1349 Session::set_default_fade (float /*steepness*/, float /*fade_msecs*/)
1352 nframes_t fade_frames;
1354 /* Don't allow fade of less 1 frame */
1356 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1363 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1367 default_fade_msecs = fade_msecs;
1368 default_fade_steepness = steepness;
1371 // jlc, WTF is this!
1372 Glib::RWLock::ReaderLock lm (route_lock);
1373 AudioRegion::set_default_fade (steepness, fade_frames);
1378 /* XXX have to do this at some point */
1379 /* foreach region using default fade, reset, then
1380 refill_all_diskstream_buffers ();
1385 struct RouteSorter {
1386 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1387 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1389 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1392 if (r1->fed_by.empty()) {
1393 if (r2->fed_by.empty()) {
1394 /* no ardour-based connections inbound to either route. just use signal order */
1395 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1397 /* r2 has connections, r1 does not; run r1 early */
1401 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1408 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1410 shared_ptr<Route> r2;
1412 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1413 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1417 /* make a copy of the existing list of routes that feed r1 */
1419 set<weak_ptr<Route> > existing = r1->fed_by;
1421 /* for each route that feeds r1, recurse, marking it as feeding
1425 for (set<weak_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1426 if (!(r2 = (*i).lock ())) {
1427 /* (*i) went away, ignore it */
1431 /* r2 is a route that feeds r1 which somehow feeds base. mark
1432 base as being fed by r2
1435 rbase->fed_by.insert (r2);
1439 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1443 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1447 /* now recurse, so that we can mark base as being fed by
1448 all routes that feed r2
1451 trace_terminal (r2, rbase);
1458 Session::resort_routes ()
1460 /* don't do anything here with signals emitted
1461 by Routes while we are being destroyed.
1464 if (_state_of_the_state & Deletion) {
1471 RCUWriter<RouteList> writer (routes);
1472 shared_ptr<RouteList> r = writer.get_copy ();
1473 resort_routes_using (r);
1474 /* writer goes out of scope and forces update */
1479 Session::resort_routes_using (shared_ptr<RouteList> r)
1481 RouteList::iterator i, j;
1483 for (i = r->begin(); i != r->end(); ++i) {
1485 (*i)->fed_by.clear ();
1487 for (j = r->begin(); j != r->end(); ++j) {
1489 /* although routes can feed themselves, it will
1490 cause an endless recursive descent if we
1491 detect it. so don't bother checking for
1499 if ((*j)->feeds (*i)) {
1500 (*i)->fed_by.insert (*j);
1505 for (i = r->begin(); i != r->end(); ++i) {
1506 trace_terminal (*i, *i);
1513 cerr << "finished route resort\n";
1515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1516 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1523 list<boost::shared_ptr<MidiTrack> >
1524 Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1526 char track_name[32];
1527 uint32_t track_id = 0;
1530 RouteList new_routes;
1531 list<boost::shared_ptr<MidiTrack> > ret;
1532 //uint32_t control_id;
1534 // FIXME: need physical I/O and autoconnect stuff for MIDI
1536 /* count existing midi tracks */
1539 shared_ptr<RouteList> r = routes.reader ();
1541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1542 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1543 if (!(*i)->is_hidden()) {
1545 //channels_used += (*i)->n_inputs().n_midi();
1551 vector<string> physinputs;
1552 vector<string> physoutputs;
1554 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1555 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1557 // control_id = ntracks() + nbusses();
1561 /* check for duplicate route names, since we might have pre-existing
1562 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1563 save, close,restart,add new route - first named route is now
1571 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1573 if (route_by_name (track_name) == 0) {
1577 } while (track_id < (UINT_MAX-1));
1579 shared_ptr<MidiTrack> track;
1582 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1584 if (track->input()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1585 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1590 if (track->output()->ensure_io (ChanCount(DataType::MIDI, 1), false, this)) {
1591 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1597 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1601 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1602 port = physinputs[(channels_used+x)%nphysical_in];
1605 if (port.length() && track->connect_input (track->input (x), port, this)) {
1611 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1615 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1616 port = physoutputs[(channels_used+x)%nphysical_out];
1617 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1619 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1623 if (port.length() && track->connect_output (track->output (x), port, this)) {
1628 channels_used += track->n_inputs ().n_midi();
1632 track->midi_diskstream()->non_realtime_input_change();
1634 route_group->add (track);
1637 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1638 //track->set_remote_control_id (control_id);
1640 new_routes.push_back (track);
1641 ret.push_back (track);
1644 catch (failed_constructor &err) {
1645 error << _("Session: could not create new midi track.") << endmsg;
1648 /* we need to get rid of this, since the track failed to be created */
1649 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1652 RCUWriter<DiskstreamList> writer (diskstreams);
1653 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1654 ds->remove (track->midi_diskstream());
1661 catch (AudioEngine::PortRegistrationFailure& pfe) {
1663 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1666 /* we need to get rid of this, since the track failed to be created */
1667 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1670 RCUWriter<DiskstreamList> writer (diskstreams);
1671 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1672 ds->remove (track->midi_diskstream());
1683 if (!new_routes.empty()) {
1684 add_routes (new_routes, false);
1685 save_state (_current_snapshot_name);
1691 list<boost::shared_ptr<AudioTrack> >
1692 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1694 char track_name[32];
1695 uint32_t track_id = 0;
1697 uint32_t channels_used = 0;
1699 RouteList new_routes;
1700 list<boost::shared_ptr<AudioTrack> > ret;
1701 uint32_t control_id;
1703 /* count existing audio tracks */
1706 shared_ptr<RouteList> r = routes.reader ();
1708 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1709 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1710 if (!(*i)->is_hidden()) {
1712 channels_used += (*i)->n_inputs().n_audio();
1718 vector<string> physinputs;
1719 vector<string> physoutputs;
1721 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1722 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1724 control_id = ntracks() + nbusses() + 1;
1728 /* check for duplicate route names, since we might have pre-existing
1729 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1730 save, close,restart,add new route - first named route is now
1738 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1740 if (route_by_name (track_name) == 0) {
1744 } while (track_id < (UINT_MAX-1));
1746 shared_ptr<AudioTrack> track;
1749 AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1750 boost_debug_shared_ptr_mark_interesting (at, "Track");
1751 track = boost::shared_ptr<AudioTrack>(at);
1753 if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1754 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1755 input_channels, output_channels)
1760 if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1761 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1762 input_channels, output_channels)
1767 if (!physinputs.empty()) {
1768 uint32_t nphysical_in = physinputs.size();
1770 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1774 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1775 port = physinputs[(channels_used+x)%nphysical_in];
1778 if (port.length() && track->input()->connect (track->input()->nth(x), port, this)) {
1784 if (!physoutputs.empty()) {
1785 uint32_t nphysical_out = physoutputs.size();
1787 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1790 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1791 port = physoutputs[(channels_used+x)%nphysical_out];
1792 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1793 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1794 port = _master_out->input()->nth (x % _master_out->input()->n_ports().n_audio())->name();
1798 if (port.length() && track->output()->connect (track->output()->nth(x), port, this)) {
1804 channels_used += track->n_inputs ().n_audio();
1807 route_group->add (track);
1810 track->audio_diskstream()->non_realtime_input_change();
1812 track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
1813 track->set_remote_control_id (control_id);
1816 new_routes.push_back (track);
1817 ret.push_back (track);
1820 catch (failed_constructor &err) {
1821 error << _("Session: could not create new audio track.") << endmsg;
1824 /* we need to get rid of this, since the track failed to be created */
1825 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1828 RCUWriter<DiskstreamList> writer (diskstreams);
1829 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1830 ds->remove (track->audio_diskstream());
1837 catch (AudioEngine::PortRegistrationFailure& pfe) {
1839 error << pfe.what() << endmsg;
1842 /* we need to get rid of this, since the track failed to be created */
1843 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1846 RCUWriter<DiskstreamList> writer (diskstreams);
1847 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1848 ds->remove (track->audio_diskstream());
1859 if (!new_routes.empty()) {
1860 add_routes (new_routes, true);
1867 Session::set_remote_control_ids ()
1869 RemoteModel m = Config->get_remote_model();
1870 bool emit_signal = false;
1872 shared_ptr<RouteList> r = routes.reader ();
1874 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1875 if (MixerOrdered == m) {
1876 long order = (*i)->order_key(N_("signal"));
1877 (*i)->set_remote_control_id (order+1, false);
1879 } else if (EditorOrdered == m) {
1880 long order = (*i)->order_key(N_("editor"));
1881 (*i)->set_remote_control_id (order+1, false);
1883 } else if (UserOrdered == m) {
1884 //do nothing ... only changes to remote id's are initiated by user
1889 Route::RemoteControlIDChange();
1895 Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
1898 uint32_t bus_id = 1;
1900 uint32_t channels_used = 0;
1903 uint32_t control_id;
1905 /* count existing audio busses */
1908 shared_ptr<RouteList> r = routes.reader ();
1910 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1911 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1913 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1916 channels_used += (*i)->n_inputs().n_audio();
1922 vector<string> physinputs;
1923 vector<string> physoutputs;
1925 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1926 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1928 n_physical_audio_outputs = physoutputs.size();
1929 n_physical_audio_inputs = physinputs.size();
1931 control_id = ntracks() + nbusses() + 1;
1936 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1940 if (route_by_name (bus_name) == 0) {
1944 } while (bus_id < (UINT_MAX-1));
1947 Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO);
1948 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1949 shared_ptr<Route> bus (rt);
1951 if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) {
1952 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1953 input_channels, output_channels)
1959 if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
1960 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1961 input_channels, output_channels)
1966 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->input()->n_ports().n_audio(); ++x) {
1969 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1970 port = physinputs[((n+x)%n_physical_audio_inputs)];
1973 if (port.length() && bus->input()->connect (bus->input()->nth (x), port, this)) {
1978 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1981 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1982 port = physoutputs[((n+x)%n_physical_outputs)];
1983 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1985 port = _master_out->input()->nth (x%_master_out->input()->n_ports().n_audio())->name();
1989 if (port.length() && bus->output()->connect (bus->output()->nth(x), port, this)) {
1994 channels_used += bus->n_inputs ().n_audio();
1997 route_group->add (bus);
1999 bus->set_remote_control_id (control_id);
2003 bus->add_internal_return ();
2006 ret.push_back (bus);
2010 catch (failed_constructor &err) {
2011 error << _("Session: could not create new audio route.") << endmsg;
2015 catch (AudioEngine::PortRegistrationFailure& pfe) {
2016 error << pfe.what() << endmsg;
2026 add_routes (ret, true);
2034 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
2038 uint32_t control_id;
2040 uint32_t number = 1;
2042 if (!tree.read (template_path.c_str())) {
2046 XMLNode* node = tree.root();
2048 control_id = ntracks() + nbusses() + 1;
2052 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2054 std::string node_name = IO::name_from_state (*node_copy.children().front());
2056 /* generate a new name by adding a number to the end of the template name */
2059 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2063 if (route_by_name (name) == 0) {
2067 } while (number < UINT_MAX);
2069 if (number == UINT_MAX) {
2070 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2074 IO::set_name_in_state (*node_copy.children().front(), name);
2076 Track::zero_diskstream_id_in_xml (node_copy);
2079 shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000));
2082 error << _("Session: cannot create track/bus from template description") << endmsg;
2086 if (boost::dynamic_pointer_cast<Track>(route)) {
2087 /* force input/output change signals so that the new diskstream
2088 picks up the configuration of the route. During session
2089 loading this normally happens in a different way.
2091 route->input()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2092 route->output()->changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2095 route->set_remote_control_id (control_id);
2098 ret.push_back (route);
2101 catch (failed_constructor &err) {
2102 error << _("Session: could not create new route from template") << endmsg;
2106 catch (AudioEngine::PortRegistrationFailure& pfe) {
2107 error << pfe.what() << endmsg;
2116 add_routes (ret, true);
2123 Session::add_routes (RouteList& new_routes, bool save)
2126 RCUWriter<RouteList> writer (routes);
2127 shared_ptr<RouteList> r = writer.get_copy ();
2128 r->insert (r->end(), new_routes.begin(), new_routes.end());
2131 /* if there is no control out and we're not in the middle of loading,
2132 resort the graph here. if there is a control out, we will resort
2133 toward the end of this method. if we are in the middle of loading,
2134 we will resort when done.
2137 if (!_control_out && IO::connecting_legal) {
2138 resort_routes_using (r);
2142 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2144 boost::weak_ptr<Route> wpr (*x);
2145 boost::shared_ptr<Route> r (*x);
2147 r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
2148 r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr));
2149 r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
2150 r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
2151 r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
2152 r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2154 if (r->is_master()) {
2158 if (r->is_control()) {
2163 if (_control_out && IO::connecting_legal) {
2165 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2166 if ((*x)->is_control() || (*x)->is_master()) {
2169 (*x)->listen_via (_control_out,
2170 (Config->get_listen_position() == AfterFaderListen ? PostFader : PreFader),
2180 save_state (_current_snapshot_name);
2183 RouteAdded (new_routes); /* EMIT SIGNAL */
2184 Route::RemoteControlIDChange (); /* EMIT SIGNAL */
2188 Session::globally_set_send_gains_to_zero (boost::shared_ptr<Route> dest)
2190 boost::shared_ptr<RouteList> r = routes.reader ();
2191 boost::shared_ptr<Send> s;
2195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2196 if (boost::dynamic_pointer_cast<Track>(*i)) {
2197 if ((s = (*i)->internal_send_for (dest)) != 0) {
2198 s->amp()->gain_control()->set_value (0.0);
2205 Session::globally_set_send_gains_to_unity (boost::shared_ptr<Route> dest)
2207 boost::shared_ptr<RouteList> r = routes.reader ();
2208 boost::shared_ptr<Send> s;
2212 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2213 if (boost::dynamic_pointer_cast<Track>(*i)) {
2214 if ((s = (*i)->internal_send_for (dest)) != 0) {
2215 s->amp()->gain_control()->set_value (1.0);
2222 Session::globally_set_send_gains_from_track(boost::shared_ptr<Route> dest)
2224 boost::shared_ptr<RouteList> r = routes.reader ();
2225 boost::shared_ptr<Send> s;
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if (boost::dynamic_pointer_cast<Track>(*i)) {
2231 if ((s = (*i)->internal_send_for (dest)) != 0) {
2232 s->amp()->gain_control()->set_value ((*i)->gain_control()->get_value());
2239 Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p)
2241 boost::shared_ptr<RouteList> r = routes.reader ();
2242 boost::shared_ptr<RouteList> t (new RouteList);
2244 /* only send tracks */
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 if (boost::dynamic_pointer_cast<Track>(*i)) {
2252 add_internal_sends (dest, p, t);
2256 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
2258 if (dest->is_control() || dest->is_master()) {
2262 if (!dest->internal_return()) {
2263 dest->add_internal_return();
2266 for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
2268 if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
2272 (*i)->listen_via (dest, p, true, true);
2279 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2281 /* need to do this in case we're rolling at the time, to prevent false underruns */
2282 dstream->do_refill_with_alloc ();
2284 dstream->set_block_size (current_block_size);
2287 RCUWriter<DiskstreamList> writer (diskstreams);
2288 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2289 ds->push_back (dstream);
2290 /* writer goes out of scope, copies ds back to main */
2293 dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr<Diskstream> (dstream)));
2294 /* this will connect to future changes, and check the current length */
2295 diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
2297 dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this));
2299 dstream->prepare ();
2304 Session::remove_route (shared_ptr<Route> route)
2307 RCUWriter<RouteList> writer (routes);
2308 shared_ptr<RouteList> rs = writer.get_copy ();
2312 /* deleting the master out seems like a dumb
2313 idea, but its more of a UI policy issue
2317 if (route == _master_out) {
2318 _master_out = shared_ptr<Route> ();
2321 if (route == _control_out) {
2323 /* cancel control outs for all routes */
2325 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2326 (*r)->drop_listen (_control_out);
2329 _control_out.reset ();
2332 update_route_solo_state ();
2334 /* writer goes out of scope, forces route list update */
2337 boost::shared_ptr<Track> t;
2338 boost::shared_ptr<Diskstream> ds;
2340 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2341 ds = t->diskstream();
2347 RCUWriter<DiskstreamList> dsl (diskstreams);
2348 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2353 find_current_end ();
2355 // We need to disconnect the routes inputs and outputs
2357 route->input()->disconnect (0);
2358 route->output()->disconnect (0);
2360 /* if the route had internal sends sending to it, remove them */
2361 if (route->internal_return()) {
2363 boost::shared_ptr<RouteList> r = routes.reader ();
2364 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2365 boost::shared_ptr<Send> s = (*i)->internal_send_for (route);
2367 (*i)->remove_processor (s);
2372 update_latency_compensation (false, false);
2375 /* get rid of it from the dead wood collection in the route list manager */
2377 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2381 /* try to cause everyone to drop their references */
2383 route->drop_references ();
2385 sync_order_keys (N_("session"));
2387 Route::RemoteControlIDChange(); /* EMIT SIGNAL */
2389 /* save the new state of the world */
2391 if (save_state (_current_snapshot_name)) {
2392 save_history (_current_snapshot_name);
2397 Session::route_mute_changed (void* /*src*/)
2403 Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2405 boost::shared_ptr<Route> route = wpr.lock();
2407 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2411 if (route->listening()) {
2413 } else if (_listen_cnt > 0) {
2419 Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
2421 if (solo_update_disabled) {
2426 boost::shared_ptr<Route> route = wpr.lock ();
2429 /* should not happen */
2430 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2434 shared_ptr<RouteList> r = routes.reader ();
2437 if (route->self_soloed()) {
2443 /* now mod the solo level of all other routes except master & control outs
2444 so that they will be silent if appropriate.
2447 solo_update_disabled = true;
2449 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2450 bool via_sends_only;
2452 if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_control() || (*i)->is_hidden()) {
2454 } else if ((*i)->feeds (route, &via_sends_only)) {
2455 if (!via_sends_only) {
2456 (*i)->mod_solo_by_others (delta);
2461 /* make sure master is never muted by solo */
2463 if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
2464 _master_out->mod_solo_by_others (1);
2467 /* ditto for control outs make sure master is never muted by solo */
2469 if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
2470 _control_out->mod_solo_by_others (1);
2473 solo_update_disabled = false;
2474 update_route_solo_state (r);
2475 SoloChanged (); /* EMIT SIGNAL */
2480 Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
2482 /* now figure out if anything that matters is soloed */
2484 bool something_soloed = false;
2487 r = routes.reader();
2490 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2491 if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
2492 something_soloed = true;
2497 if (something_soloed != _non_soloed_outs_muted) {
2498 _non_soloed_outs_muted = something_soloed;
2499 SoloActive (_non_soloed_outs_muted); /* EMIT SIGNAL */
2503 boost::shared_ptr<RouteList>
2504 Session::get_routes_with_internal_returns() const
2506 shared_ptr<RouteList> r = routes.reader ();
2507 boost::shared_ptr<RouteList> rl (new RouteList);
2509 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2510 if ((*i)->internal_return ()) {
2518 Session::route_by_name (string name)
2520 shared_ptr<RouteList> r = routes.reader ();
2522 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2523 if ((*i)->name() == name) {
2528 return shared_ptr<Route> ((Route*) 0);
2532 Session::route_by_id (PBD::ID id)
2534 shared_ptr<RouteList> r = routes.reader ();
2536 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2537 if ((*i)->id() == id) {
2542 return shared_ptr<Route> ((Route*) 0);
2546 Session::route_by_remote_id (uint32_t id)
2548 shared_ptr<RouteList> r = routes.reader ();
2550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2551 if ((*i)->remote_control_id() == id) {
2556 return shared_ptr<Route> ((Route*) 0);
2560 Session::find_current_end ()
2562 if (_state_of_the_state & Loading) {
2566 nframes_t max = get_maximum_extent ();
2568 if (max > end_location->end()) {
2569 end_location->set_end (max);
2571 DurationChanged(); /* EMIT SIGNAL */
2576 Session::get_maximum_extent () const
2581 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2583 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2584 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2586 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2587 if ((me = pl->get_maximum_extent()) > max) {
2595 boost::shared_ptr<Diskstream>
2596 Session::diskstream_by_name (string name)
2598 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2600 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2601 if ((*i)->name() == name) {
2606 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2609 boost::shared_ptr<Diskstream>
2610 Session::diskstream_by_id (const PBD::ID& id)
2612 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2614 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2615 if ((*i)->id() == id) {
2620 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2623 /* Region management */
2626 Session::new_region_name (string old)
2628 string::size_type last_period;
2630 string::size_type len = old.length() + 64;
2633 if ((last_period = old.find_last_of ('.')) == string::npos) {
2635 /* no period present - add one explicitly */
2638 last_period = old.length() - 1;
2643 number = atoi (old.substr (last_period+1).c_str());
2647 while (number < (UINT_MAX-1)) {
2649 RegionList::const_iterator i;
2654 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2657 for (i = regions.begin(); i != regions.end(); ++i) {
2658 if (i->second->name() == sbuf) {
2663 if (i == regions.end()) {
2668 if (number != (UINT_MAX-1)) {
2672 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2677 Session::region_name (string& result, string base, bool newlevel)
2682 if (base.find("/") != string::npos) {
2683 base = base.substr(base.find_last_of("/") + 1);
2688 Glib::Mutex::Lock lm (region_lock);
2690 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2699 string::size_type pos;
2701 pos = base.find_last_of ('.');
2703 /* pos may be npos, but then we just use entire base */
2705 subbase = base.substr (0, pos);
2710 Glib::Mutex::Lock lm (region_lock);
2712 map<string,uint32_t>::iterator x;
2716 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2718 region_name_map[subbase] = 1;
2721 snprintf (buf, sizeof (buf), ".%d", x->second);
2732 Session::add_region (boost::shared_ptr<Region> region)
2734 vector<boost::shared_ptr<Region> > v;
2735 v.push_back (region);
2740 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2745 Glib::Mutex::Lock lm (region_lock);
2747 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2749 boost::shared_ptr<Region> region = *ii;
2753 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2757 RegionList::iterator x;
2759 for (x = regions.begin(); x != regions.end(); ++x) {
2761 if (region->region_list_equivalent (x->second)) {
2766 if (x == regions.end()) {
2768 pair<RegionList::key_type,RegionList::mapped_type> entry;
2770 entry.first = region->id();
2771 entry.second = region;
2773 pair<RegionList::iterator,bool> x = regions.insert (entry);
2785 /* mark dirty because something has changed even if we didn't
2786 add the region to the region list.
2793 vector<boost::weak_ptr<Region> > v;
2794 boost::shared_ptr<Region> first_r;
2796 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2798 boost::shared_ptr<Region> region = *ii;
2802 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2805 v.push_back (region);
2812 region->StateChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region)));
2813 update_region_name_map (region);
2817 RegionsAdded (v); /* EMIT SIGNAL */
2823 Session::update_region_name_map (boost::shared_ptr<Region> region)
2825 string::size_type last_period = region->name().find_last_of ('.');
2827 if (last_period != string::npos && last_period < region->name().length() - 1) {
2829 string base = region->name().substr (0, last_period);
2830 string number = region->name().substr (last_period+1);
2831 map<string,uint32_t>::iterator x;
2833 /* note that if there is no number, we get zero from atoi,
2837 region_name_map[base] = atoi (number);
2842 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2844 boost::shared_ptr<Region> region (weak_region.lock ());
2850 if (what_changed & Region::HiddenChanged) {
2851 /* relay hidden changes */
2852 RegionHiddenChange (region);
2855 if (what_changed & NameChanged) {
2856 update_region_name_map (region);
2861 Session::remove_region (boost::weak_ptr<Region> weak_region)
2863 RegionList::iterator i;
2864 boost::shared_ptr<Region> region (weak_region.lock ());
2870 bool removed = false;
2873 Glib::Mutex::Lock lm (region_lock);
2875 if ((i = regions.find (region->id())) != regions.end()) {
2881 /* mark dirty because something has changed even if we didn't
2882 remove the region from the region list.
2888 RegionRemoved(region); /* EMIT SIGNAL */
2892 boost::shared_ptr<Region>
2893 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2895 RegionList::iterator i;
2896 boost::shared_ptr<Region> region;
2898 Glib::Mutex::Lock lm (region_lock);
2900 for (i = regions.begin(); i != regions.end(); ++i) {
2904 if (region->whole_file()) {
2906 if (child->source_equivalent (region)) {
2912 return boost::shared_ptr<Region> ();
2916 Session::destroy_region (boost::shared_ptr<Region> region)
2918 vector<boost::shared_ptr<Source> > srcs;
2921 if (region->playlist()) {
2922 region->playlist()->destroy_region (region);
2925 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2926 srcs.push_back (region->source (n));
2930 region->drop_references ();
2932 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2934 (*i)->mark_for_remove ();
2935 (*i)->drop_references ();
2937 cerr << "source was not used by any playlist\n";
2944 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2946 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2947 destroy_region (*i);
2953 Session::remove_last_capture ()
2955 list<boost::shared_ptr<Region> > r;
2957 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2959 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2960 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2963 r.insert (r.end(), l.begin(), l.end());
2968 for (list<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
2972 destroy_regions (r);
2974 save_state (_current_snapshot_name);
2980 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2986 /* Source Management */
2989 Session::add_source (boost::shared_ptr<Source> source)
2991 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2992 pair<SourceMap::iterator,bool> result;
2994 entry.first = source->id();
2995 entry.second = source;
2998 Glib::Mutex::Lock lm (source_lock);
2999 result = sources.insert (entry);
3002 if (result.second) {
3006 boost::shared_ptr<AudioFileSource> afs;
3008 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
3009 if (Config->get_auto_analyse_audio()) {
3010 Analyser::queue_source_for_analysis (source, false);
3016 Session::remove_source (boost::weak_ptr<Source> src)
3018 SourceMap::iterator i;
3019 boost::shared_ptr<Source> source = src.lock();
3026 Glib::Mutex::Lock lm (source_lock);
3028 if ((i = sources.find (source->id())) != sources.end()) {
3033 if (!_state_of_the_state & InCleanup) {
3035 /* save state so we don't end up with a session file
3036 referring to non-existent sources.
3039 save_state (_current_snapshot_name);
3043 boost::shared_ptr<Source>
3044 Session::source_by_id (const PBD::ID& id)
3046 Glib::Mutex::Lock lm (source_lock);
3047 SourceMap::iterator i;
3048 boost::shared_ptr<Source> source;
3050 if ((i = sources.find (id)) != sources.end()) {
3057 boost::shared_ptr<Source>
3058 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3060 Glib::Mutex::Lock lm (source_lock);
3062 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3063 cerr << "comparing " << path << " with " << i->second->name() << endl;
3064 boost::shared_ptr<AudioFileSource> afs
3065 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3067 if (afs && afs->path() == path && chn == afs->channel()) {
3071 return boost::shared_ptr<Source>();
3076 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3079 string old_basename = PBD::basename_nosuffix (oldname);
3080 string new_legalized = legalize_for_path (newname);
3082 /* note: we know (or assume) the old path is already valid */
3086 /* destructive file sources have a name of the form:
3088 /path/to/Tnnnn-NAME(%[LR])?.wav
3090 the task here is to replace NAME with the new name.
3093 /* find last slash */
3097 string::size_type slash;
3098 string::size_type dash;
3100 if ((slash = path.find_last_of ('/')) == string::npos) {
3104 dir = path.substr (0, slash+1);
3106 /* '-' is not a legal character for the NAME part of the path */
3108 if ((dash = path.find_last_of ('-')) == string::npos) {
3112 prefix = path.substr (slash+1, dash-(slash+1));
3117 path += new_legalized;
3118 path += ".wav"; /* XXX gag me with a spoon */
3122 /* non-destructive file sources have a name of the form:
3124 /path/to/NAME-nnnnn(%[LR])?.ext
3126 the task here is to replace NAME with the new name.
3131 string::size_type slash;
3132 string::size_type dash;
3133 string::size_type postfix;
3135 /* find last slash */
3137 if ((slash = path.find_last_of ('/')) == string::npos) {
3141 dir = path.substr (0, slash+1);
3143 /* '-' is not a legal character for the NAME part of the path */
3145 if ((dash = path.find_last_of ('-')) == string::npos) {
3149 suffix = path.substr (dash+1);
3151 // Suffix is now everything after the dash. Now we need to eliminate
3152 // the nnnnn part, which is done by either finding a '%' or a '.'
3154 postfix = suffix.find_last_of ("%");
3155 if (postfix == string::npos) {
3156 postfix = suffix.find_last_of ('.');
3159 if (postfix != string::npos) {
3160 suffix = suffix.substr (postfix);
3162 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3166 const uint32_t limit = 10000;
3167 char buf[PATH_MAX+1];
3169 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3171 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3173 if (access (buf, F_OK) != 0) {
3181 error << "FATAL ERROR! Could not find a " << endl;
3189 /** Return the full path (in some session directory) for a new within-session source.
3190 * \a name must be a session-unique name that does not contain slashes
3191 * (e.g. as returned by new_*_source_name)
3194 Session::new_source_path_from_name (DataType type, const string& name)
3196 assert(name.find("/") == string::npos);
3198 SessionDirectory sdir(get_best_session_directory_for_new_source());
3201 if (type == DataType::AUDIO) {
3202 p = sdir.sound_path();
3203 } else if (type == DataType::MIDI) {
3204 p = sdir.midi_path();
3206 error << "Unknown source type, unable to create file path" << endmsg;
3211 return p.to_string();
3215 Session::peak_path (Glib::ustring base) const
3217 sys::path peakfile_path(_session_dir->peak_path());
3218 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3219 return peakfile_path.to_string();
3222 /** Return a unique name based on \a base for a new internal audio source */
3224 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3228 char buf[PATH_MAX+1];
3229 const uint32_t limit = 10000;
3233 legalized = legalize_for_path (base);
3235 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3236 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3238 vector<space_and_path>::iterator i;
3239 uint32_t existing = 0;
3241 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3243 SessionDirectory sdir((*i).path);
3245 spath = sdir.sound_path().to_string();
3250 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3251 spath.c_str(), cnt, legalized.c_str());
3252 } else if (nchan == 2) {
3254 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3255 spath.c_str(), cnt, legalized.c_str());
3257 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3258 spath.c_str(), cnt, legalized.c_str());
3260 } else if (nchan < 26) {
3261 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3262 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3264 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3265 spath.c_str(), cnt, legalized.c_str());
3274 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3275 } else if (nchan == 2) {
3277 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3279 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3281 } else if (nchan < 26) {
3282 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3284 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3288 if (sys::exists(buf)) {
3294 if (existing == 0) {
3299 error << string_compose(
3300 _("There are already %1 recordings for %2, which I consider too many."),
3301 limit, base) << endmsg;
3303 throw failed_constructor();
3307 return Glib::path_get_basename(buf);
3310 /** Create a new within-session audio source */
3311 boost::shared_ptr<AudioFileSource>
3312 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3314 const size_t n_chans = ds.n_channels().n_audio();
3315 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3316 const string path = new_source_path_from_name(DataType::AUDIO, name);
3318 return boost::dynamic_pointer_cast<AudioFileSource> (
3319 SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
3322 /** Return a unique name based on \a base for a new internal MIDI source */
3324 Session::new_midi_source_name (const string& base)
3327 char buf[PATH_MAX+1];
3328 const uint32_t limit = 10000;
3332 legalized = legalize_for_path (base);
3334 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3335 for (cnt = 1; cnt <= limit; ++cnt) {
3337 vector<space_and_path>::iterator i;
3338 uint32_t existing = 0;
3340 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3342 SessionDirectory sdir((*i).path);
3344 sys::path p = sdir.midi_path();
3347 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3349 if (sys::exists (buf)) {
3354 if (existing == 0) {
3359 error << string_compose(
3360 _("There are already %1 recordings for %2, which I consider too many."),
3361 limit, base) << endmsg;
3363 throw failed_constructor();
3367 return Glib::path_get_basename(buf);
3371 /** Create a new within-session MIDI source */
3372 boost::shared_ptr<MidiSource>
3373 Session::create_midi_source_for_session (MidiDiskstream& ds)
3375 const string name = new_midi_source_name (ds.name());
3376 const string path = new_source_path_from_name (DataType::MIDI, name);
3378 return boost::dynamic_pointer_cast<SMFSource> (
3379 SourceFactory::createWritable (
3380 DataType::MIDI, *this, path, false, frame_rate()));
3385 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3387 if (playlist->hidden()) {
3391 playlists->add (playlist);
3394 playlist->release();
3401 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3403 if (_state_of_the_state & Deletion) {
3407 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3413 playlists->remove (playlist);
3419 Session::set_audition (boost::shared_ptr<Region> r)
3421 pending_audition_region = r;
3422 add_post_transport_work (PostTransportAudition);
3423 _butler->schedule_transport_work ();
3427 Session::audition_playlist ()
3429 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3430 ev->region.reset ();
3435 Session::non_realtime_set_audition ()
3437 if (!pending_audition_region) {
3438 auditioner->audition_current_playlist ();
3440 auditioner->audition_region (pending_audition_region);
3441 pending_audition_region.reset ();
3443 AuditionActive (true); /* EMIT SIGNAL */
3447 Session::audition_region (boost::shared_ptr<Region> r)
3449 SessionEvent* ev = new SessionEvent (SessionEvent::Audition, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
3455 Session::cancel_audition ()
3457 if (auditioner->active()) {
3458 auditioner->cancel_audition ();
3459 AuditionActive (false); /* EMIT SIGNAL */
3464 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3466 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3470 Session::remove_empty_sounds ()
3472 vector<string> audio_filenames;
3474 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3476 Glib::Mutex::Lock lm (source_lock);
3478 TapeFileMatcher tape_file_matcher;
3480 remove_if (audio_filenames.begin(), audio_filenames.end(),
3481 boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
3483 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3485 sys::path audio_file_path (_session_dir->sound_path());
3487 audio_file_path /= *i;
3489 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3493 sys::remove (audio_file_path);
3494 const string peakfile = peak_path (audio_file_path.to_string());
3495 sys::remove (peakfile);
3497 catch (const sys::filesystem_error& err)
3499 error << err.what() << endmsg;
3506 Session::is_auditioning () const
3508 /* can be called before we have an auditioner object */
3510 return auditioner->active();
3517 Session::n_diskstreams () const
3521 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3523 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3524 if (!(*i)->hidden()) {
3532 Session::graph_reordered ()
3534 /* don't do this stuff if we are setting up connections
3535 from a set_state() call or creating new tracks. Ditto for deletion.
3538 if (_state_of_the_state & (InitialConnecting|Deletion)) {
3542 /* every track/bus asked for this to be handled but it was deferred because
3543 we were connecting. do it now.
3546 request_input_change_handling ();
3550 /* force all diskstreams to update their capture offset values to
3551 reflect any changes in latencies within the graph.
3554 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3556 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3557 (*i)->set_capture_offset ();
3562 Session::add_processor (Processor* processor)
3564 /* Session does not own Processors (they belong to a Route) but we do want to track
3565 the arrival and departure of port inserts, sends and returns for naming
3568 processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
3573 Session::remove_processor (Processor* processor)
3577 PortInsert* port_insert;
3579 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3580 insert_bitset[port_insert->bit_slot()] = false;
3581 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3582 send_bitset[send->bit_slot()] = false;
3583 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3584 return_bitset[retrn->bit_slot()] = false;
3591 Session::available_capture_duration ()
3593 float sample_bytes_on_disk = 4.0; // keep gcc happy
3595 switch (config.get_native_file_data_format()) {
3597 sample_bytes_on_disk = 4.0;
3601 sample_bytes_on_disk = 3.0;
3605 sample_bytes_on_disk = 2.0;
3609 /* impossible, but keep some gcc versions happy */
3610 fatal << string_compose (_("programming error: %1"),
3611 X_("illegal native file data format"))
3616 double scale = 4096.0 / sample_bytes_on_disk;
3618 if (_total_free_4k_blocks * scale > (double) max_frames) {
3622 return (nframes_t) floor (_total_free_4k_blocks * scale);
3626 Session::add_bundle (shared_ptr<Bundle> bundle)
3629 RCUWriter<BundleList> writer (_bundles);
3630 boost::shared_ptr<BundleList> b = writer.get_copy ();
3631 b->push_back (bundle);
3634 BundleAdded (bundle); /* EMIT SIGNAL */
3640 Session::remove_bundle (shared_ptr<Bundle> bundle)
3642 bool removed = false;
3645 RCUWriter<BundleList> writer (_bundles);
3646 boost::shared_ptr<BundleList> b = writer.get_copy ();
3647 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3649 if (i != b->end()) {
3656 BundleRemoved (bundle); /* EMIT SIGNAL */
3663 Session::bundle_by_name (string name) const
3665 boost::shared_ptr<BundleList> b = _bundles.reader ();
3667 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3668 if ((*i)->name() == name) {
3673 return boost::shared_ptr<Bundle> ();
3677 Session::tempo_map_changed (Change)
3681 playlists->update_after_tempo_map_change ();
3686 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3687 * the given count with the current block size.
3690 Session::ensure_buffers (ChanCount howmany)
3692 if (current_block_size == 0) {
3693 return; // too early? (is this ok?)
3696 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3697 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3698 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3699 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3700 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3703 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3707 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3709 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3710 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3715 Session::next_insert_id ()
3717 /* this doesn't really loop forever. just think about it */
3720 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3721 if (!insert_bitset[n]) {
3722 insert_bitset[n] = true;
3728 /* none available, so resize and try again */
3730 insert_bitset.resize (insert_bitset.size() + 16, false);
3735 Session::next_send_id ()
3737 /* this doesn't really loop forever. just think about it */
3740 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3741 if (!send_bitset[n]) {
3742 send_bitset[n] = true;
3748 /* none available, so resize and try again */
3750 send_bitset.resize (send_bitset.size() + 16, false);
3755 Session::next_return_id ()
3757 /* this doesn't really loop forever. just think about it */
3760 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3761 if (!return_bitset[n]) {
3762 return_bitset[n] = true;
3768 /* none available, so resize and try again */
3770 return_bitset.resize (return_bitset.size() + 16, false);
3775 Session::mark_send_id (uint32_t id)
3777 if (id >= send_bitset.size()) {
3778 send_bitset.resize (id+16, false);
3780 if (send_bitset[id]) {
3781 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3783 send_bitset[id] = true;
3787 Session::mark_return_id (uint32_t id)
3789 if (id >= return_bitset.size()) {
3790 return_bitset.resize (id+16, false);
3792 if (return_bitset[id]) {
3793 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3795 return_bitset[id] = true;
3799 Session::mark_insert_id (uint32_t id)
3801 if (id >= insert_bitset.size()) {
3802 insert_bitset.resize (id+16, false);
3804 if (insert_bitset[id]) {
3805 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3807 insert_bitset[id] = true;
3810 /* Named Selection management */
3812 boost::shared_ptr<NamedSelection>
3813 Session::named_selection_by_name (string name)
3815 Glib::Mutex::Lock lm (named_selection_lock);
3816 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3817 if ((*i)->name == name) {
3821 return boost::shared_ptr<NamedSelection>();
3825 Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3828 Glib::Mutex::Lock lm (named_selection_lock);
3829 named_selections.insert (named_selections.begin(), named_selection);
3834 NamedSelectionAdded (); /* EMIT SIGNAL */
3838 Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
3840 bool removed = false;
3843 Glib::Mutex::Lock lm (named_selection_lock);
3845 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3847 if (i != named_selections.end()) {
3848 named_selections.erase (i);
3855 NamedSelectionRemoved (); /* EMIT SIGNAL */
3860 Session::reset_native_file_format ()
3862 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3864 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3865 (*i)->reset_write_sources (false);
3870 Session::route_name_unique (string n) const
3872 shared_ptr<RouteList> r = routes.reader ();
3874 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3875 if ((*i)->name() == n) {
3884 Session::route_name_internal (string n) const
3886 if (auditioner && auditioner->name() == n) {
3890 if (_click_io && _click_io->name() == n) {
3898 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3900 if (!force && howmany <= _npan_buffers) {
3904 if (_pan_automation_buffer) {
3906 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3907 delete [] _pan_automation_buffer[i];
3910 delete [] _pan_automation_buffer;
3913 _pan_automation_buffer = new pan_t*[howmany];
3915 for (uint32_t i = 0; i < howmany; ++i) {
3916 _pan_automation_buffer[i] = new pan_t[nframes];
3919 _npan_buffers = howmany;
3923 Session::freeze (InterThreadInfo& itt)
3925 shared_ptr<RouteList> r = routes.reader ();
3927 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3929 boost::shared_ptr<Track> t;
3931 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3932 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3942 boost::shared_ptr<Region>
3943 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
3944 bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
3945 InterThreadInfo& itt, bool enable_processing)
3947 boost::shared_ptr<Region> result;
3948 boost::shared_ptr<Playlist> playlist;
3949 boost::shared_ptr<AudioFileSource> fsource;
3951 char buf[PATH_MAX+1];
3952 ChanCount nchans(track.audio_diskstream()->n_channels());
3954 nframes_t this_chunk;
3957 SessionDirectory sdir(get_best_session_directory_for_new_source ());
3958 const string sound_dir = sdir.sound_path().to_string();
3959 nframes_t len = end - start;
3962 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
3963 end, start) << endmsg;
3967 const nframes_t chunk_size = (256 * 1024)/4;
3969 // block all process callback handling
3971 block_processing ();
3973 /* call tree *MUST* hold route_lock */
3975 if ((playlist = track.diskstream()->playlist()) == 0) {
3979 /* external redirects will be a problem */
3981 if (track.has_external_redirects()) {
3985 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3987 for (x = 0; x < 99999; ++x) {
3988 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3989 if (access (buf, F_OK) != 0) {
3995 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4000 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4001 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
4004 catch (failed_constructor& err) {
4005 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4009 srcs.push_back (fsource);
4012 /* XXX need to flush all redirects */
4017 /* create a set of reasonably-sized buffers */
4018 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4019 buffers.set_count(nchans);
4021 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4022 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4024 afs->prepare_for_peakfile_writes ();
4027 while (to_do && !itt.cancel) {
4029 this_chunk = min (to_do, chunk_size);
4031 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4036 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4037 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4040 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4046 start += this_chunk;
4047 to_do -= this_chunk;
4049 itt.progress = (float) (1.0 - ((double) to_do / len));
4058 xnow = localtime (&now);
4060 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4061 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4064 afs->update_header (position, *xnow, now);
4065 afs->flush_header ();
4069 /* construct a region to represent the bounced material */
4071 result = RegionFactory::create (srcs, 0,
4072 srcs.front()->length(srcs.front()->timeline_position()),
4073 region_name_from_path (srcs.front()->name(), true));
4078 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4079 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4082 afs->mark_for_remove ();
4085 (*src)->drop_references ();
4089 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4090 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4093 afs->done_with_peakfile_writes ();
4097 unblock_processing ();
4103 Session::get_silent_buffers (ChanCount count)
4105 assert(_silent_buffers->available() >= count);
4106 _silent_buffers->set_count(count);
4108 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4109 for (size_t i= 0; i < count.get(*t); ++i) {
4110 _silent_buffers->get(*t, i).clear();
4114 return *_silent_buffers;
4118 Session::get_scratch_buffers (ChanCount count)
4120 if (count != ChanCount::ZERO) {
4121 assert(_scratch_buffers->available() >= count);
4122 _scratch_buffers->set_count(count);
4124 _scratch_buffers->set_count (_scratch_buffers->available());
4127 return *_scratch_buffers;
4131 Session::get_mix_buffers (ChanCount count)
4133 assert(_mix_buffers->available() >= count);
4134 _mix_buffers->set_count(count);
4135 return *_mix_buffers;
4139 Session::ntracks () const
4142 shared_ptr<RouteList> r = routes.reader ();
4144 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4145 if (boost::dynamic_pointer_cast<Track> (*i)) {
4154 Session::nbusses () const
4157 shared_ptr<RouteList> r = routes.reader ();
4159 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4160 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4169 Session::add_automation_list(AutomationList *al)
4171 automation_lists[al->id()] = al;
4175 Session::compute_initial_length ()
4177 return _engine.frame_rate() * 60 * 5;
4181 Session::sync_order_keys (std::string const & base)
4183 if (deletion_in_progress()) {
4187 if (!Config->get_sync_all_route_ordering()) {
4188 /* leave order keys as they are */
4192 boost::shared_ptr<RouteList> r = routes.reader ();
4194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4195 (*i)->sync_order_keys (base);
4198 Route::SyncOrderKeys (base); // EMIT SIGNAL
4200 /* this might not do anything */
4202 set_remote_control_ids ();
4205 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4207 Session::have_rec_enabled_diskstream () const
4209 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4212 /** Update the state of our rec-enabled diskstreams flag */
4214 Session::update_have_rec_enabled_diskstream ()
4216 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4217 DiskstreamList::iterator i = dsl->begin ();
4218 while (i != dsl->end () && (*i)->record_enabled () == false) {
4222 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4224 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4226 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4227 RecordStateChanged (); /* EMIT SIGNAL */
4232 Session::listen_position_changed ()
4236 switch (Config->get_listen_position()) {
4237 case AfterFaderListen:
4241 case PreFaderListen:
4246 boost::shared_ptr<RouteList> r = routes.reader ();
4248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4249 (*i)->put_control_outs_at (p);
4254 Session::solo_control_mode_changed ()
4256 /* cancel all solo or all listen when solo control mode changes */
4258 if (Config->get_solo_control_is_listen_control()) {
4259 set_solo (routes.reader(), false);
4261 set_listen (routes.reader(), false);
4266 Session::route_group_changed ()
4268 RouteGroupChanged (); /* EMIT SIGNAL */
4272 Session::get_available_sync_options () const
4274 vector<SyncSource> ret;
4276 ret.push_back (JACK);
4279 ret.push_back (MTC);
4282 if (midi_clock_port()) {
4283 ret.push_back (MIDIClock);
4289 boost::shared_ptr<RouteList>
4290 Session::get_routes_with_regions_at (nframes64_t const p) const
4292 shared_ptr<RouteList> r = routes.reader ();
4293 shared_ptr<RouteList> rl (new RouteList);
4295 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4296 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
4301 boost::shared_ptr<Diskstream> ds = tr->diskstream ();
4306 boost::shared_ptr<Playlist> pl = ds->playlist ();
4311 if (pl->has_region_at (p)) {